Compare commits

...

17 Commits

Author SHA1 Message Date
Georges Khaznadar 279c81b366 Imported Debian patch 1.6.1-5 2023-07-01 12:15:55 +02:00
Mario Fetka 40afaea348 Imported Upstream version 1.6.1 2023-07-01 12:15:55 +02:00
Mario Fetka a935cc9da0 Bump 2021-08-09 17:58:07 +02:00
Mario Fetka ad51843419 Bump 2021-08-09 17:41:04 +02:00
Mario Fetka 682db6f593 Bump 2021-08-09 17:31:23 +02:00
Mario Fetka 6d10f268c9 Bump 2021-08-09 17:24:27 +02:00
Mario Fetka 79652fd531 Bump 2021-08-09 17:22:40 +02:00
Mario Fetka 691a4c9bfa Bump 2021-08-09 17:06:52 +02:00
Mario Fetka ca39db51aa Bump 2021-08-09 16:55:08 +02:00
Mario Fetka 53372c20a2 Bump 2021-08-09 16:45:11 +02:00
Mario Fetka 0c594392ac make it compile on old debian 2021-08-09 15:34:14 +02:00
Mario Fetka bdf0408644 maek it compile on old debian 2021-08-09 15:26:08 +02:00
Christian Kastner 0de9c5e286 Imported Debian patch 1.5.5-3 2021-08-09 15:08:55 +02:00
Mario Fetka 40b51ec933 Imported Upstream version 1.5.5 2021-08-09 15:08:54 +02:00
Mario Fetka 38f79ab6a4 Bump 2019-08-06 19:01:25 +02:00
Mario Fetka 16e9a0ed83 Merge tag 'upstream/1.5.4'
Upstream version 1.5.4
2019-08-06 18:08:05 +02:00
Christian Kastner 3f49655c6b Imported Debian patch 1.4.8-1~exp1 2017-05-08 15:30:04 +02:00
80 changed files with 5159 additions and 2755 deletions

339
COPYING.anacron Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

510
COPYING.obstack Normal file
View File

@ -0,0 +1,510 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes a de-facto standard. To achieve this, non-free programs must
be allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least
three years, to give the same user the materials specified in
Subsection 6a, above, for a charge no more than the cost of
performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).
To apply these terms, attach the following notices to the library.
It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the library,
if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James
Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

299
ChangeLog
View File

@ -1,3 +1,302 @@
2022-03-23 w30023233 <wangyuhang27@huawei.com>
* Fix regression in handling 1-5 crontab entries
2022-03-22 Tomas Mraz <tmraz@fedoraproject.org>
* Release version 1.6.0
2022-03-22 w30023233 <wangyuhang27@huawei.com>
* Add switch -f for foreground mode
2022-03-22 Tomas Mraz <tmraz@fedoraproject.org>
* Fix regression in handling */x crontab entries
2022-01-05 Tomas Mraz <tmraz@fedoraproject.org>
* get_number: Add missing NUL termination for the scanned string
2021-11-08 Ondřej Pohořelský <35430604+opohorel@users.noreply.github.com>
* Add random within range '~' operator
2021-11-03 Nicolas Limare <nicolas@limare.net>
* Fix RandomScale calculation
2021-10-27 sgerwk <sgerwk@aol.com>
* include the case where runstate is undefined
2021-10-26 sgerwk <sgerwk@aol.com>
* use the configure runstatedir directory for pid file
2021-09-02 Nils Philippsen <nils@tiptoe.de>
* crond: Fix description of '-P' option
2021-07-13 Danilo Spinella <danilo.spinella@suse.com>
* Increase the maximum number of crontab entries
2021-04-29 Jan Staněk <jstanek@redhat.com>
* Address issues found by coverity scan
2021-03-29 Christian Hesse <mail@eworm.de>
* crontab: use bold colors
2021-03-29 Tomas Mraz <tmraz@fedoraproject.org>
* Release new version 1.5.7
2021-03-29 Tomas Mraz <tmraz@fedoraproject.org>
* crond: Skip blanks between user name and command
2021-03-29 Tomas Mraz <tmraz@fedoraproject.org>
* 0anacron: Check only Mains type power_supply for status
2021-03-22 Tomas Mraz <tmraz@fedoraproject.org>
* 0anacron: Ignore Battery type power supply devices
2021-03-19 Tomas Mraz <tmraz@fedoraproject.org>
* crontab: switch off colors if NO_COLOR is set
2021-03-17 Lars Wendler <polynomial-c@gentoo.org>
* configure.ac: Don't use AM_CONDITIONAL inside an if statement
or else configure might break:
2021-03-17 Tomas Mraz <tmraz@fedoraproject.org>
* Release new version 1.5.6
2021-03-17 Tomas Mraz <tmraz@fedoraproject.org>
* Partially revert the behavior of crontab command without arguments
If the stdin is not a TTY we behave as required in the POSIX spec.
This still prevents mistakes from simply running crontab without
arguments in a terminal.
2021-03-17 Tomas Mraz <tmraz@fedoraproject.org>
* Any online power supply indicates that the system is on mains
2021-01-22 Tomas Mraz <tmraz@fedoraproject.org>
* Fix some compilation warnings
2021-01-22 Tomas Mraz <tmraz@fedoraproject.org>
* Always load database on startup even if all files have st_mtime == 0
2020-11-28 Mark Hills <mark@xwax.org>
* Fix compiler warnings on 32-bit systems
2020-12-28 Sami Kerola <kerolasa@iki.fi>
* build-sys: update to autoconf 2.70
2020-12-24 Hyunsoo Choe <hytgbn@gmail.com>
* Fix race condition between file update and load_database
Issue: https://github.com/cronie-crond/cronie/issues/73
2020-11-02 Tomas Mraz <tmraz@fedoraproject.org>
* configure.ac: Drop the bug report e-mail from AC_INIT()
Fixes #70
2020-10-25 Wayne Van Son <waynevanson@gmail.com>
* docs(readme): adds Void Linux to packaged distributions
2020-08-20 Björn Persson <Bjorn@Rombobjörn.se>
* Add missing Content-Transfer-Encoding.
2020-08-03 Kevin Adler <kadler@us.ibm.com>
* Fix anacron build when obstack not available
2020-07-23 Fernando Cappi <3818944+fcappi@users.noreply.github.com>
* Expand MAILTO and MAILFROM environment variables
2020-07-13 J. Paul Reed <preed@release-approaches.com>
* Fix crontab.5 man page, wrt verbiage regarding named lists/ranges for crontab entries.
See https://github.com/cronie-crond/cronie/issues/62 for more info.
2020-06-11 Fernando Cappi <3818944+fcappi@users.noreply.github.com>
* Add new option to test a crontab file syntax without installing it
Co-authored-by: Fernando Cappi <fcappi@motorola.com>
2020-06-10 Tomas Mraz <tmraz@fedoraproject.org>
* Update packit configuration for latest Fedora versions
2020-06-10 Tomas Mraz <tmraz@fedoraproject.org>
* Fix the .spec for packit
2020-04-21 Tomas Mraz <tmraz@fedoraproject.org>
* Sync cronie.spec with Fedora
2019-11-11 Dominika Hodovska <dhodovsk@redhat.com>
* Enable copr builds and add packit config
2020-04-21 Tomas Mraz <tmraz@fedoraproject.org>
* Handle out-of-memory condition from mkprints() call
2020-04-20 John Horne <john.horne@plymouth.ac.uk>
* Ensure the command name is not null before logging it.
2020-04-20 John Horne <john.horne@plymouth.ac.uk>
* Moved CMDEND code to outside for for loop.
2020-04-20 John Horne <john.horne@plymouth.ac.uk>
* Add CMDEND log entry to log when cron jobs end.
2020-03-02 Ian2020 <Ian2020@users.noreply.github.com>
* Allow backslashes when not part of a line continuation
2019-12-16 Tomas Mraz <tmraz@fedoraproject.org>
* Fix incorrect flag set for @weekly jobs.
Fixes #52
2019-11-24 Josef Schlehofer <pepe.schlehofer@gmail.com>
* Fix incorrect include of fcntl.h
2019-11-06 Tomas Mraz <tmraz@fedoraproject.org>
* crontab: Fix coloring when crontab ends with comment
Also emphasize a missing EOL at EOF by red warning text
Fixes #45
2019-10-31 Tomas Mraz <tmraz@fedoraproject.org>
* Release new version 1.5.5
2019-10-31 Tomas Mraz <tmraz@fedoraproject.org>
* Avoid warning for strncat.
2019-10-29 Christian Kastner <ckk@kvr.at>
* crontab.1: Various fixes and improvements
2019-10-30 Christian Kastner <ckk@kvr.at>
* crontab: fsync to check for full disk
2019-10-30 Christian Kastner <ckk@kvr.at>
* crontab: Add Y/N to retry prompt
2019-10-30 Christian Kastner <ckk@kvr.at>
* entries: Explicitly validate upper ranges and steps
2019-10-29 Christian Kastner <ckk@kvr.at>
* crond: report missing newline before EOF
2019-09-09 Christian Hesse <mail@eworm.de>
* do not log carriage return
2019-08-22 sgerwk <sgerwk@aol.com>
* skip directories when given as crontabs
2019-07-22 Stephane Blondon <stephane.blondon@gmail.com>
* crontab -l colors comment lines in a different color
2019-07-09 sgerwk <sgerwk@aol.com>
* fix compile instruction: configure is generated by autogen.sh
2019-07-08 Tomas Mraz <tmraz@fedoraproject.org>
* getdtablesize() can return very high values in containers
2019-05-11 John Horne <jayaich@users.noreply.github.com>
* Power supply name not detected correctly.
2019-05-07 Tomas Mraz <tmraz@fedoraproject.org>
* Revert "Avoid creating pid files when crond doesn't fork"
2019-04-15 Tomas Mraz <tmraz@fedoraproject.org>
* anacron: fix types in comparisons
2019-03-31 Sami Kerola <kerolasa@iki.fi>
* mics: stop using plain integer as NULL pointer
2019-03-31 Sami Kerola <kerolasa@iki.fi>
* cron: fix type in comparison
2019-03-31 Sami Kerola <kerolasa@iki.fi>
* cron: fix variable shadowing
2019-03-31 Sami Kerola <kerolasa@iki.fi>
* cron: mark signal number arguments in signal handlers unused
2019-04-08 Tomáš Mráz <t8m@users.noreply.github.com>
* Update readme.md with recent releases
2019-04-08 Tomas Mraz <tmraz@fedoraproject.org>
* Move allowed() and related function to security.c
2019-03-31 Sami Kerola <kerolasa@iki.fi>
* build-sys: enable anacron by default
2019-03-31 Sami Kerola <kerolasa@iki.fi>
* build-sys: use none-recursive build
2019-04-02 sgerwk <sgerwk@aol.com>
* cronnext: optionally select jobs by substring
2019-03-18 Tomas Mraz <tmraz@fedoraproject.org>
* crond: Do not abort loading crontab prematurely in case of error
2019-03-18 Tomas Mraz <tmraz@fedoraproject.org>
* Release new version 1.5.4
2019-03-18 Tomas Mraz <tmraz@fedoraproject.org>
* crond: Fix regression from last release

View File

@ -6,6 +6,9 @@ Run the usual autotools combination of:
make
make install
If no "configure" script is present, generate it by:
./autogen.sh
The executable files will be installed in /usr/local/* by default.
Configure Options

View File

@ -1,9 +1,20 @@
SUBDIRS = src man anacron
AM_CFLAGS = -I$(top_srcdir)
BUILT_SOURCES =
CLEANFILES =
EXTRA_DIST =
bin_PROGRAMS =
common_nodist =
sbin_PROGRAMS =
dist_noinst_HEADERS = \
cronie_common.h
EXTRA_DIST = \
EXTRA_DIST += \
README.anacron \
COPYING.anacron \
COPYING.obstack \
obstack/obstack.h \
cronie.init \
crond.sysconfig \
contrib/anacrontab \
@ -19,3 +30,7 @@ dist_pam_DATA = pam/crond
else
EXTRA_DIST += pam/crond
endif
include anacron/Makemodule.am
include man/Makemodule.am
include src/Makemodule.am

File diff suppressed because it is too large Load Diff

37
NEWS
View File

@ -1,10 +1,47 @@
cronie NEWS -- history of user-visible changes.
Release 1.6.1
* crond: Fix regression of handling ranges (x-y) in crontab
Release 1.6.0
* crond: Add switch -f as an alias for -n
* crond: Add random within range '~' operator
* crond: Use the configure runstatedir directory for pid file
* crond: Increase the maximum number of crontab entries to 10000
Release 1.5.7
* anacron: Fix problem of anacron not being started on some desktops
* crontab: switch off colors if NO_COLOR is set
Release 1.5.6
* crontab: crontab without arguments now works if stdin is not a TTY
* crond: Fix various issues on loading the crontab databases on startup
* anacron: Expand MAILTO and MAILFROM environment variables
* crontab: New option to test crontab file syntax without installing it
Release 1.5.5
* Explicitly validate upper end of range and step to disallow entries
such as: 1-234/5678 * * * * ....
* crond: Report missing newline before EOF in syslog so the line is not
completely silently ignored.
* crontab -l colors comment lines in a different color.
* crond: Revert "Avoid creating pid files when crond doesn't fork".
* anacron is built by default.
* Use non-recursive build.
* cronnext: Allow to optionally select jobs by substring.
Release 1.5.4
* crond: Fix regression from previous release. Only first job from a crontab
was being run.
Release 1.5.3
* Fix CVE-2019-9704 and CVE-2019-9705 to avoid local DoS of the crond.
* crontab: Make crontab without arguments fail.
* crond: In PAM configuration include system-auth instead of password-auth.

22
README
View File

@ -1,11 +1,13 @@
17. January 2008 mmaslano (at) redhat (dot) com
Rename the fork on cronie. The source code could be found here:
http://mmaslano.fedorapeople.org/cronie/ or git archive here:
git://git.fedorahosted.org/git/cronie.git
Cronie contains the standard UNIX daemon crond that runs specified programs at
scheduled times and related tools. The source is based on the original vixie-cron
and has security and configuration enhancements like the ability to use pam and
SELinux.
3. October 2007 mmaslano (at) redhat (dot) com
This is a clone of 'original' vixie-cron. It was used in Red Hat|Fedora
system and patched for a long time. Now was made clone tagged with
version 4.2.
Changes are mainly in git commit messages, some older changes could be
found in spec changelog (contrib/vixie-cron.spec).
And why cronie? See http://www.urbandictionary.com/define.php?term=cronie
Contact
-------
Mailing list: `cronie-devel AT lists.fedorahosted DOT org`
Bug reports and pull requests can be filled at the Github site.

142
README.anacron Normal file
View File

@ -0,0 +1,142 @@
What is Anacron ?
-----------------
Anacron is a periodic command scheduler. It executes commands at
intervals specified in days. Unlike cron, it does not assume that the
system is running continuously. It can therefore be used to control
the execution of daily, weekly and monthly jobs (or anything with a
period of n days), on systems that don't run 24 hours a day. When
installed and configured properly, Anacron will make sure that the
commands are run at the specified intervals as closely as
machine-uptime permits.
Every time Anacron is run, it reads a configuration file that
specifies the jobs Anacron controls, and their periods in days. If a
job wasn't executed in the last n days, where n is the period of that
job, Anacron executes it. Anacron then records the date in a special
timestamp file that it keeps for each job, so it can know when to run
it again. When all the executed commands terminate, Anacron exits.
It is recommended to run Anacron from the system boot-scripts.
This way the jobs "whose time has come" will be run shortly after the
machine boots. A delay can be specified for each job so that the
machine isn't overloaded at boot time.
In addition to running Anacron from the boot-scripts, it is also
recommended to schedule it as a daily cron-job (usually at an early
morning hour), so that if the machine is kept running for a night,
jobs for the next day will still be executed.
Why this may be useful ?
------------------------
Most Unix-like systems have daily, weekly and monthly scripts that
take care of various "housekeeping chores" such as log-rotation,
updating the "locate" and "man" databases, etc. Daily scripts are
usually scheduled as cron-jobs to execute around 1-7 AM. Weekly
scripts are scheduled to run on Sundays. On machines that are turned
off for the night or for the weekend, these scripts rarely get run.
Anacron solves this problem. These jobs can simply be scheduled as
Anacron-jobs with periods of 1, 7 and a special target called @monthly.
What Anacron is not ?
---------------------
Anacron is not an attempt to make cron redundant. It cannot
currently be used to schedule commands at intervals smaller than days.
It also does not guarantee that the commands will be executed at any
specific day or hour.
It isn't a full-time daemon. It has to be executed from boot
scripts, from cron-jobs, or explicitly.
For more details, see the anacron(8) manpage.
Requirements
------------
- A Linux system. (maybe other *NIX systems)
- A functioning syslog daemon.
- A functioning /usr/lib/sendmail command. (all MTAs should have
that).
Compilation and Installation
----------------------------
- Untar the source package.
- Check the Makefile. Edit as required.
- Check the top of "global.h". You may want to change the syslog
facility and priorities, and the path to your MTA's sendmail
compatible command (/usr/lib/sendmail).
- cd to the directory.
- Type "make".
You can safely ignore warnings of the form: "*.d: No such file or
directory"
- Become root. Type "make install".
Setup
-----
1. Locate your system's daily, weekly and monthly cron-jobs.
See your cron documentation for more details.
2. Decide which of these jobs should be controlled by Anacron.
Remember that Anacron does not guarantee execution at any specific
day of the month, day of the week, or time of day. Jobs for which
the timing is critical should probably not be controlled by
Anacron.
3. Comment these jobs out of their crontab files. (You may have to
use the "crontab" command for this. See the cron documentation.)
4. Put them in /etc/anacrontab. Note that the format is not the same
as the crontab entries. See the anacrontab(5) manpage. Here's an
example from a typical Debian system:
-----Cut
# /etc/anacrontab example
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
# format: period delay job-identifier command
1 5 cron.daily run-parts /etc/cron.daily
7 10 cron.weekly run-parts /etc/cron.weekly
@monthly 15 cron.monthly run-parts /etc/cron.monthly
-----Cut
5. Put the command "anacron -s" somewhere in your boot-scripts.
Make sure that syslogd is started before this command.
6. Schedule the command "anacron -s" as a daily cron-job (preferably
at some early morning hour). This will make sure that jobs are run
when the systems is left running for a night.
That's it.
It is a good idea to check what your daily, weekly and monthly scripts
actually do, and disable any parts that may be irrelevant for your
system.
Credits
-------
Anacron was originally conceived and implemented by Christian Schwarz
<schwarz@monet.m.isar.de>.
The current implementation is a complete rewrite by Itai Tzur
<itzur@actcom.co.il>.
Current code base maintained by Sean 'Shaleh' Perry <shaleh@(debian.org|valinux.com)>.

48
aclocal.m4 vendored
View File

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
# Copyright (C) 2002-2018 Free Software Foundation, Inc.
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.16'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.16.1], [],
m4_if([$1], [1.16.2], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.16.1])dnl
[AM_AUTOMAKE_VERSION([1.16.2])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -371,7 +371,9 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
done
if test $am_rc -ne 0; then
AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. Try re-running configure with the
for automatic dependency tracking. If GNU make was not used, consider
re-running the configure script with MAKE="gmake" (or whatever is
necessary). You can also try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).])
fi
@ -398,7 +400,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -595,7 +597,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -616,7 +618,7 @@ if test x"${install_sh+set}" != xset; then
fi
AC_SUBST([install_sh])])
# Copyright (C) 2003-2018 Free Software Foundation, Inc.
# Copyright (C) 2003-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -637,7 +639,7 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -680,7 +682,7 @@ AC_SUBST([am__quote])])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -719,7 +721,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -748,7 +750,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -795,7 +797,7 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -814,7 +816,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -895,7 +897,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])
# Copyright (C) 2009-2018 Free Software Foundation, Inc.
# Copyright (C) 2009-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -955,7 +957,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -983,7 +985,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006-2018 Free Software Foundation, Inc.
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -1002,7 +1004,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004-2018 Free Software Foundation, Inc.
# Copyright (C) 2004-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,

7
anacron-paths.h Normal file
View File

@ -0,0 +1,7 @@
/* This file has been automatically generated. Do not edit. */
#ifndef _ANACRON_PATHS_H_
#define _ANACRON_PATHS_H_
#define ANACRON_SPOOL_DIR "/usr/local/var/spool/anacron"
#define ANACRONTAB "/usr/local/etc/anacrontab"
#endif /* _ANACRON_PATHS_H_ */

View File

@ -1,647 +0,0 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@ANACRON_TRUE@sbin_PROGRAMS = anacron$(EXEEXT)
subdir = anacron
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)"
PROGRAMS = $(sbin_PROGRAMS)
am__objects_1 =
am_anacron_OBJECTS = gregor.$(OBJEXT) lock.$(OBJEXT) log.$(OBJEXT) \
main.$(OBJEXT) matchrx.$(OBJEXT) readtab.$(OBJEXT) \
runjob.$(OBJEXT) $(am__objects_1)
nodist_anacron_OBJECTS = $(am__objects_1)
anacron_OBJECTS = $(am_anacron_OBJECTS) $(nodist_anacron_OBJECTS)
anacron_LDADD = $(LDADD)
am__DEPENDENCIES_1 =
anacron_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/gregor.Po ./$(DEPDIR)/lock.Po \
./$(DEPDIR)/log.Po ./$(DEPDIR)/main.Po ./$(DEPDIR)/matchrx.Po \
./$(DEPDIR)/readtab.Po ./$(DEPDIR)/runjob.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(anacron_SOURCES) $(nodist_anacron_SOURCES)
DIST_SOURCES = $(anacron_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANACRONTAB = @ANACRONTAB@
ANACRON_SPOOL_DIR = @ANACRON_SPOOL_DIR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DAEMON_GROUPNAME = @DAEMON_GROUPNAME@
DAEMON_USERNAME = @DAEMON_USERNAME@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBAUDIT = @LIBAUDIT@
LIBOBJS = @LIBOBJS@
LIBPAM = @LIBPAM@
LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPOOL_DIR = @SPOOL_DIR@
STRIP = @STRIP@
SYSCRONTAB = @SYSCRONTAB@
SYS_CROND_DIR = @SYS_CROND_DIR@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
editor_defined = @editor_defined@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
anacron_SOURCES = \
gregor.c lock.c log.c main.c matchrx.c readtab.c runjob.c \
$(common_src)
common_src = global.h gregor.h matchrx.h
common_nodist = anacron-paths.h
nodist_anacron_SOURCES = $(common_nodist)
BUILT_SOURCES = $(common_nodist)
AM_CFLAGS = -I$(top_srcdir)
LDADD = $(LIBSELINUX) $(LIBPAM) $(LIBAUDIT)
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu anacron/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu anacron/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p \
; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' \
-e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
} \
; done
uninstall-sbinPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' \
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(sbindir)" && rm -f $$files
clean-sbinPROGRAMS:
-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
anacron$(EXEEXT): $(anacron_OBJECTS) $(anacron_DEPENDENCIES) $(EXTRA_anacron_DEPENDENCIES)
@rm -f anacron$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(anacron_OBJECTS) $(anacron_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gregor.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matchrx.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readtab.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runjob.Po@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(sbindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am
clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -f ./$(DEPDIR)/gregor.Po
-rm -f ./$(DEPDIR)/lock.Po
-rm -f ./$(DEPDIR)/log.Po
-rm -f ./$(DEPDIR)/main.Po
-rm -f ./$(DEPDIR)/matchrx.Po
-rm -f ./$(DEPDIR)/readtab.Po
-rm -f ./$(DEPDIR)/runjob.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-sbinPROGRAMS
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/gregor.Po
-rm -f ./$(DEPDIR)/lock.Po
-rm -f ./$(DEPDIR)/log.Po
-rm -f ./$(DEPDIR)/main.Po
-rm -f ./$(DEPDIR)/matchrx.Po
-rm -f ./$(DEPDIR)/readtab.Po
-rm -f ./$(DEPDIR)/runjob.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-sbinPROGRAMS
.MAKE: all check install install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-generic clean-sbinPROGRAMS cscopelist-am ctags ctags-am \
distclean distclean-compile distclean-generic distclean-tags \
distdir dvi dvi-am html html-am info info-am install \
install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-sbinPROGRAMS install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-sbinPROGRAMS
.PRECIOUS: Makefile
# This header contains all the paths.
# If they are configurable, they are declared in configure script.
# Depends on this Makefile, because it uses make variables.
anacron-paths.h: Makefile
@echo 'creating $@'
@sed >$@ 's/ *\\$$//' <<\END #\
/* This file has been automatically generated. Do not edit. */ \
\
#ifndef _ANACRON_PATHS_H_ \
#define _ANACRON_PATHS_H_ \
#define ANACRON_SPOOL_DIR "$(ANACRON_SPOOL_DIR)" \
#define ANACRONTAB "$(ANACRONTAB)" \
#endif /* _ANACRON_PATHS_H_ */ \
END
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,23 +1,33 @@
# Makefile.am - two binaries crond and crontab
if ANACRON
sbin_PROGRAMS = anacron
sbin_PROGRAMS += anacron/anacron
anacron_anacron_SOURCES = \
anacron-paths.h \
anacron/global.h \
anacron/gregor.c \
anacron/gregor.h \
anacron/lock.c \
anacron/log.c \
anacron/main.c \
anacron/matchrx.c \
anacron/matchrx.h \
anacron/readtab.c \
anacron/runjob.c \
cronie_common.c
common_nodist += anacron-paths.h
nodist_anacron_anacron_SOURCES = $(common_nodist)
BUILT_SOURCES += $(common_nodist)
if NEED_OBSTACK
anacron_anacron_SOURCES += obstack/obstack.c
endif
anacron_SOURCES = \
gregor.c lock.c log.c main.c matchrx.c readtab.c runjob.c \
$(common_src)
common_src = global.h gregor.h matchrx.h
common_nodist = anacron-paths.h
nodist_anacron_SOURCES = $(common_nodist)
BUILT_SOURCES = $(common_nodist)
AM_CFLAGS = -I$(top_srcdir)
LDADD = $(LIBSELINUX) $(LIBPAM) $(LIBAUDIT)
anacron_anacron_LDADD = $(LIBSELINUX) $(LIBPAM) $(LIBAUDIT)
# This header contains all the paths.
# If they are configurable, they are declared in configure script.
# Depends on this Makefile, because it uses make variables.
CLEANFILES += anacron-paths.h
anacron-paths.h: Makefile
@echo 'creating $@'
@sed >$@ 's/ *\\$$//' <<\END #\
@ -29,3 +39,4 @@ anacron-paths.h: Makefile
#define ANACRONTAB "$(ANACRONTAB)" \
#endif /* _ANACRON_PATHS_H_ */ \
END
endif

View File

@ -79,7 +79,12 @@ make_msg(const char *fmt, va_list args)
/* There's some confusion in the documentation about what vsnprintf
* returns when the buffer overflows. Hmmm... */
len = vsnprintf(msg, sizeof(msg), fmt, args);
if (len >= sizeof(msg) - 1)
if (len < 0) {
strncpy(msg, "(vsnprintf failed)", sizeof(msg));
msg[sizeof(msg) - 1] = '\0';
return;
}
if ((size_t) len >= sizeof(msg) - 1)
strcpy(msg + sizeof(msg) - sizeof(truncated), truncated);
}

View File

@ -44,8 +44,8 @@ int day_now;
int year, month, day_of_month; /* date anacron started */
char *program_name;
char *anacrontab;
char *spooldir;
char *anacrontab = NULL;
char *spooldir = NULL;
int serialize, force, update_only, now,
no_daemon, quiet, testing_only; /* command-line options */
char **job_args; /* vector of "job" command-line arguments */
@ -128,12 +128,14 @@ parse_opts(int argc, char *argv[])
quiet = 1;
break;
case 't':
free(anacrontab);
anacrontab = strdup(optarg);
break;
case 'T':
testing_only = 1;
break;
case 'S':
free(spooldir);
spooldir = strdup(optarg);
break;
case 'V':
@ -208,9 +210,11 @@ go_background(void)
/* stdin is already closed */
if (fclose(stdout)) die_e("Can't close stdout");
/* coverity[leaked_handle] fd 1 closed automatically */
xopen(1, "/dev/null", O_WRONLY);
if (fclose(stderr)) die_e("Can't close stderr");
/* coverity[leaked_handle] fd 2 closed automatically */
xopen(2, "/dev/null", O_WRONLY);
pid = xfork();

View File

@ -42,11 +42,13 @@ match_rx(const char *rx, char *string, unsigned int n_sub, /* char **substrings
* This is not the most efficient, or elegant way of doing this.
*/
{
int r, n;
int r;
unsigned int n;
regex_t crx;
va_list va;
char **substring;
regmatch_t *sub_offsets;
sub_offsets = malloc(sizeof(regmatch_t) * (n_sub + 1));
if (sub_offsets == NULL)
return -1;

View File

@ -98,7 +98,7 @@ Return NULL if no more lines.
break;
}
if ('\\' != prev && 0 != prev && '\n' != prev) obstack_1grow(&input_o, (char)prev);
if (('\\' != prev || c != '\n') && 0 != prev && '\n' != prev) obstack_1grow(&input_o, (char)prev);
else if ('\n' == prev) obstack_1grow(&input_o, ' ');
prev = c;

View File

@ -35,6 +35,7 @@
#include <string.h>
#include <limits.h>
#include "global.h"
#include "cronie_common.h"
#include <langinfo.h>
@ -53,7 +54,9 @@ temp_file(job_rec *jr)
dir = P_tmpdir;
len = snprintf(template, sizeof(template), "%s/$anacronXXXXXX", dir);
if (len >= sizeof(template))
if (len < 0)
die_e("snprintf failed");
else if ((size_t) len >= sizeof(template))
die_e("TMPDIR too long");
fdout = mkstemp(template);
@ -234,7 +237,9 @@ launch_mailer(job_rec *jr)
xcloselog();
/* Ensure stdout/stderr are sane before exec-ing sendmail */
/* coverity[leaked_handle] STDOUT closed automatically */
xclose(STDOUT_FILENO); xopen(STDOUT_FILENO, "/dev/null", O_WRONLY);
/* coverity[leaked_handle] STDERR closed automatically */
xclose(STDERR_FILENO); xopen(STDERR_FILENO, "/dev/null", O_WRONLY);
xclose(jr->output_fd);
@ -284,6 +289,8 @@ launch_job(job_rec *jr)
char hostname[512];
char *mailto;
char *mailfrom;
char mailto_expanded[MAX_EMAILSTR];
char mailfrom_expanded[MAX_EMAILSTR];
/* get hostname */
if (gethostname(hostname, 512)) {
@ -294,14 +301,31 @@ launch_job(job_rec *jr)
/* Get the destination email address if set, or current user otherwise */
mailto = getenv("MAILTO");
if (mailto == NULL)
mailto = username();
if (mailto == NULL) {
mailto = username();
}
else {
if (expand_envvar(mailto, mailto_expanded, sizeof(mailto_expanded))) {
mailto = mailto_expanded;
}
else {
complain("The environment variable 'MAILTO' could not be expanded. The non-expanded value will be used.");
}
}
/* Get the source email address if set, or current user otherwise */
mailfrom = getenv("MAILFROM");
if (mailfrom == NULL)
mailfrom = username();
if (mailfrom == NULL) {
mailfrom = username();
}
else {
if (expand_envvar(mailfrom, mailfrom_expanded, sizeof(mailfrom_expanded))) {
mailfrom = mailfrom_expanded;
}
else {
complain("The environment variable 'MAILFROM' could not be expanded. The non-expanded value will be used.");
}
}
/* create temporary file for stdout and stderr of the job */
temp_file(jr); fd = jr->output_fd;
@ -317,6 +341,7 @@ launch_job(job_rec *jr)
xwrite(fd, "Content-Type: text/plain; charset=\"");
xwrite(fd, nl_langinfo(CODESET));
xwrite(fd, "\"\n");
xwrite(fd, "Content-Transfer-Encoding: 8bit\n");
xwrite(fd, "Subject: Anacron job '");
xwrite(fd, jr->ident);
xwrite(fd, "' on ");

View File

@ -108,9 +108,6 @@
/* Define to 1 if you have the <sys/cdefs.h> header file. */
#undef HAVE_SYS_CDEFS_H
/* Define to 1 if you have the <sys/fcntl.h> header file. */
#undef HAVE_SYS_FCNTL_H
/* Define to 1 if you have the <sys/inotify.h> header file. */
#undef HAVE_SYS_INOTIFY_H
@ -174,9 +171,6 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

141
configure vendored
View File

@ -1,8 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for cronie 1.5.4.
#
# Report bugs to <mmaslano@redhat.com,tmraz@fedoraproject.org>.
# Generated by GNU Autoconf 2.69 for cronie 1.6.1.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@ -266,9 +264,8 @@ fi
$as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
else
$as_echo "$0: Please tell bug-autoconf@gnu.org and
$0: mmaslano@redhat.com,tmraz@fedoraproject.org about your
$0: system, including any error possibly output before this
$as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
$0: including any error possibly output before this
$0: message. Then install a modern shell, or manually run
$0: the script under such a shell if you do have one."
fi
@ -580,9 +577,9 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='cronie'
PACKAGE_TARNAME='cronie'
PACKAGE_VERSION='1.5.4'
PACKAGE_STRING='cronie 1.5.4'
PACKAGE_BUGREPORT='mmaslano@redhat.com,tmraz@fedoraproject.org'
PACKAGE_VERSION='1.6.1'
PACKAGE_STRING='cronie 1.6.1'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
# Factoring default headers for most tests.
@ -625,6 +622,10 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
HAS_RUNSTATE_FALSE
HAS_RUNSTATE_TRUE
NEED_OBSTACK_FALSE
NEED_OBSTACK_TRUE
ANACRONTAB
ANACRON_SPOOL_DIR
ANACRON_FALSE
@ -714,6 +715,7 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -805,6 +807,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1057,6 +1060,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1194,7 +1206,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir
libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1307,7 +1319,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures cronie 1.5.4 to adapt to many kinds of systems.
\`configure' configures cronie 1.6.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1347,6 +1359,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@ -1377,7 +1390,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of cronie 1.5.4:";;
short | recursive ) echo "Configuration of cronie 1.6.1:";;
esac
cat <<\_ACEOF
@ -1396,7 +1409,7 @@ CRONIE_HELP_STRING(--enable-relro,Build cronie with relro flag)
BSD_STRING(--enable-bsd,Build cronie with BSD specific parts)
--enable-pam Alias for --with-pam
--enable-syscrontab Build cronie with system crontab enabled.
--enable-anacron Build also anacron.
--disable-anacron Do not build anacron.
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@ -1434,7 +1447,7 @@ Some influential environment variables:
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
Report bugs to <mmaslano@redhat.com,tmraz@fedoraproject.org>.
Report bugs to the package provider.
_ACEOF
ac_status=$?
fi
@ -1497,7 +1510,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
cronie configure 1.5.4
cronie configure 1.6.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -1656,10 +1669,6 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
( $as_echo "## tttttttttttttttttttttttttttttttttt ##
## Report this to mmaslano@redhat.com ##
## tttttttttttttttttttttttttttttttttt ##"
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
@ -1977,7 +1986,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by cronie $as_me 1.5.4, which was
It was created by cronie $as_me 1.6.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -2844,7 +2853,7 @@ fi
# Define the identity of the package.
PACKAGE='cronie'
VERSION='1.5.4'
VERSION='1.6.1'
cat >>confdefs.h <<_ACEOF
@ -4583,7 +4592,6 @@ for ac_header in \
sys/timers.h \
sys/types.h \
sys/cdefs.h \
sys/fcntl.h \
time.h \
unistd.h \
util.h \
@ -4702,39 +4710,6 @@ $as_echo "#define const /**/" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
$as_echo_n "checking return type of signal handlers... " >&6; }
if ${ac_cv_type_signal+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
#include <signal.h>
int
main ()
{
return *(signal (0, 0)) (0) == 1;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_type_signal=int
else
ac_cv_type_signal=void
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
$as_echo "$ac_cv_type_signal" >&6; }
cat >>confdefs.h <<_ACEOF
#define RETSIGTYPE $ac_cv_type_signal
_ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
if ${ac_cv_type_uid_t+:} false; then :
@ -5400,6 +5375,8 @@ fi
# Check whether --enable-anacron was given.
if test "${enable_anacron+set}" = set; then :
enableval=$enable_anacron;
else
enable_anacron=yes
fi
if test "$enable_anacron" = yes; then
@ -5421,9 +5398,40 @@ if test "$ANACRONTAB" = ""; then
ANACRONTAB='${sysconfdir}/anacrontab'
fi
ac_fn_c_check_header_mongrel "$LINENO" "obstack.h" "ac_cv_header_obstack_h" "$ac_includes_default"
if test "x$ac_cv_header_obstack_h" = xyes; then :
have_obstack=yes
else
have_obstack=no
fi
ac_config_files="$ac_config_files Makefile src/Makefile man/Makefile anacron/Makefile"
fi
if test "$have_obstack" = no; then
NEED_OBSTACK_TRUE=
NEED_OBSTACK_FALSE='#'
else
NEED_OBSTACK_TRUE='#'
NEED_OBSTACK_FALSE=
fi
if test "$enable_anacron" != no && test "$have_obstack" = no; then :
CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/obstack"
fi
if test x$runstatedir != x; then
HAS_RUNSTATE_TRUE=
HAS_RUNSTATE_FALSE='#'
else
HAS_RUNSTATE_TRUE='#'
HAS_RUNSTATE_FALSE=
fi
ac_config_files="$ac_config_files Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@ -5566,6 +5574,14 @@ if test -z "${ANACRON_TRUE}" && test -z "${ANACRON_FALSE}"; then
as_fn_error $? "conditional \"ANACRON\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${NEED_OBSTACK_TRUE}" && test -z "${NEED_OBSTACK_FALSE}"; then
as_fn_error $? "conditional \"NEED_OBSTACK\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${HAS_RUNSTATE_TRUE}" && test -z "${HAS_RUNSTATE_FALSE}"; then
as_fn_error $? "conditional \"HAS_RUNSTATE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
@ -5963,7 +5979,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by cronie $as_me 1.5.4, which was
This file was extended by cronie $as_me 1.6.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -6023,13 +6039,13 @@ $config_headers
Configuration commands:
$config_commands
Report bugs to <mmaslano@redhat.com,tmraz@fedoraproject.org>."
Report bugs to the package provider."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
cronie config.status 1.5.4
cronie config.status 1.6.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@ -6161,9 +6177,6 @@ do
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
"man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
"anacron/Makefile") CONFIG_FILES="$CONFIG_FILES anacron/Makefile" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
@ -6841,7 +6854,9 @@ $as_echo X/"$am_mf" |
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. Try re-running configure with the
for automatic dependency tracking. If GNU make was not used, consider
re-running the configure script with MAKE=\"gmake\" (or whatever is
necessary). You can also try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).
See \`config.log' for more details" "$LINENO" 5; }

View File

@ -1,8 +1,8 @@
AC_INIT([cronie],[1.5.4],[mmaslano@redhat.com,tmraz@fedoraproject.org])
AC_CONFIG_HEADER([config.h])
AC_PREREQ(2.60)
AC_INIT([cronie],[1.6.1])
AC_CONFIG_HEADERS([config.h])
AC_PREREQ([2.64])
AM_INIT_AUTOMAKE
AM_INIT_AUTOMAKE([subdir-objects])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])],
[AC_SUBST([AM_DEFAULT_VERBOSITY], [1])])
@ -38,7 +38,6 @@ AC_CHECK_HEADERS( \
sys/timers.h \
sys/types.h \
sys/cdefs.h \
sys/fcntl.h \
time.h \
unistd.h \
util.h \
@ -55,7 +54,6 @@ AC_CHECK_FUNCS( \
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIGNAL
AC_TYPE_UID_T
AC_TYPE_MODE_T
AC_TYPE_OFF_T
@ -67,7 +65,7 @@ AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[#include <time.h>])
dnl Checking for programs
AC_ARG_WITH([editor],
[AC_HELP_STRING([--with-editor=EDITOR], [path to default editor])],
[AS_HELP_STRING([--with-editor=EDITOR],[path to default editor])],
[editor_defined="$with_editor"],
[editor_defined="no"])
AS_IF([test "x$editor_defined" = "xno"], [
@ -253,13 +251,23 @@ CRONIE_CONF_VAR([SYSCRONTAB], [the current working directory of the running daem
CRONIE_CONF_VAR([SYS_CROND_DIR], [the current working directory of the running daemon], [${sysconfdir}/cron.d])
CRONIE_CONF_VAR([SPOOL_DIR], [the directory where all the user cron tabs reside], [${localstatedir}/spool/cron])
AC_ARG_ENABLE([anacron], [AS_HELP_STRING([--enable-anacron], [Build also anacron.])])
AC_ARG_ENABLE([anacron], [AS_HELP_STRING([--disable-anacron], [Do not build anacron.])], [], [enable_anacron=yes])
AM_CONDITIONAL([ANACRON], [test "$enable_anacron" = yes])
if test "$enable_anacron" != no; then
ANACRON_CONF_VAR([ANACRON_SPOOL_DIR],[The path for anacron locks.],[${localstatedir}/spool/anacron])
ANACRON_CONF_VAR([ANACRONTAB],[The anacron table for regular jobs.],[${sysconfdir}/anacrontab])
fi
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile anacron/Makefile])
dnl obstack.h is part of GLIBC and may not be present on other systems,
dnl eg. musl and AIX. There, we static link in our own copy.
AC_CHECK_HEADER(obstack.h, [have_obstack=yes], [have_obstack=no], [])
fi
AM_CONDITIONAL([NEED_OBSTACK], [test "$have_obstack" = no])
AS_IF([test "$enable_anacron" != no && test "$have_obstack" = no], [
CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/obstack"
])
AM_CONDITIONAL(HAS_RUNSTATE, [test x$runstatedir != x])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View File

@ -9,11 +9,9 @@ fi
# Do not run jobs when on battery power
online=1
for psupply in AC ADP0 ; do
sysfile="/sys/class/power_supply/$psupply/online"
if [ -f $sysfile ] ; then
if [ `cat $sysfile 2>/dev/null`x = 1x ]; then
for psupply in /sys/class/power_supply/* ; do
if [ `cat "$psupply/type" 2>/dev/null`x = Mainsx ] && [ -f "$psupply/online" ]; then
if [ `cat "$psupply/online" 2>/dev/null`x = 1x ]; then
online=1
break
else

137
cronie_common.c Normal file
View File

@ -0,0 +1,137 @@
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
/* Return:
* 0 - Not found
* 1 - Found */
static int find_envvar(const char *source, const char **start_pos, size_t *length) {
const char *reader;
size_t size = 1;
int waiting_close = 0;
*length = 0;
*start_pos = NULL;
if (source == NULL || *source == '\0') {
return 0;
}
*start_pos = strchr(source, '$');
if (*start_pos == NULL) {
return 0;
}
/* Skip $, since all envvars start with this char */
reader = *start_pos + 1;
while (*reader != '\0') {
if (*reader == '_' || isalnum(*reader)) {
if (size <= 2 && isdigit(*reader)) {
goto not_found;
}
size++;
}
else if (*reader == '{') {
if (size != 1) {
goto not_found;
}
size++;
waiting_close = 1;
}
else if (*reader == '}') {
if ((waiting_close && size == 2) || size == 1) {
goto not_found;
}
if (waiting_close) {
size++;
}
waiting_close = 0;
break;
}
else
break;
reader++;
}
if (waiting_close) {
goto not_found;
}
*length = size;
return 1;
not_found:
*length = 0;
*start_pos = NULL;
return 0;
}
/* Expand env variables in 'source' arg and save to 'result'
* Return:
* 1 - Success
* 0 - Fail */
int expand_envvar(const char *source, char *result, size_t max_size) {
const char *envvar_p;
size_t envvar_name_size = 0;
*result = '\0';
while (find_envvar(source, &envvar_p, &envvar_name_size)) {
char *envvar_name, *envvar_value;
size_t prefix_size;
/* Copy content before env var name */
prefix_size = envvar_p - source;
if (prefix_size > 0) {
if ((strlen(result) + prefix_size + 1) > max_size) {
goto too_big;
}
strncat(result, source, prefix_size);
}
/* skip envvar name */
source = envvar_p + envvar_name_size;
/* copy envvar name, ignoring $, { and } chars*/
envvar_p++;
envvar_name_size--;
if (*envvar_p == '{') {
envvar_p++;
envvar_name_size = envvar_name_size - 2;
}
envvar_name = malloc(envvar_name_size + 1);
strncpy(envvar_name, envvar_p, envvar_name_size);
envvar_name[envvar_name_size] = '\0';
/* Copy envvar value to result */
envvar_value = getenv(envvar_name);
free(envvar_name);
if (envvar_value != NULL) {
if ((strlen(result) + strlen(envvar_value) + 1) > max_size) {
goto too_big;
}
strcat(result, envvar_value);
}
}
/* Copy any character left in the source string */
if (*source != '\0') {
if ((strlen(result) + strlen(source) + 1) > max_size) {
goto too_big;
}
strcat(result, source);
}
return 1;
too_big:
return 0;
}

View File

@ -34,4 +34,10 @@
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#endif
#ifndef MAX_EMAILSTR
#define MAX_EMAILSTR 255 /* max length of email address strings (254 + \0) */
#endif
int expand_envvar(const char *, char *, size_t);
#endif /* CRONIE_COMMON_H */

16
debian/README.Debian vendored Normal file
View File

@ -0,0 +1,16 @@
cronie for Debian
-----------------
This version of cronie has been patched and configured to be as compatible as
possible to Debian's standard job scheduler, ISC cron. You should be able to
switch between these implementations without experiencing any major negative
side effects to your system.
Feature-wise, however, there still are quite a number of subtle and
not-so-subtle differences (mostly because of how much Debian's version of ISC
cron is patched), so be sure to read the manpages.
cronie installs a file /etc/cron.deny (empty), thereby enabling all users to
use the crontab(1) command by default.
-- Christian Kastner <ckk@debian.org> Sun, 20 Mar 2011 01:27:55 +0100

134
debian/changelog vendored Normal file
View File

@ -0,0 +1,134 @@
cronie (1.6.1-5) experimental; urgency=medium
* cronie pre-depends now on cron-daemon-common, and does no longer install
conflicting files.
-- Georges Khaznadar <georgesk@debian.org> Sun, 13 Nov 2022 17:09:31 +0100
cronie (1.6.1-4) experimental; urgency=medium
* fixed the watch file
-- Georges Khaznadar <georgesk@debian.org> Tue, 01 Nov 2022 21:53:41 +0100
cronie (1.6.1-3) experimental; urgency=medium
* reverted previous changes, as I did not notice the closed ITA bug
#974038, came back to contents authored by Lin Lance.
-- Georges Khaznadar <georgesk@debian.org> Thu, 12 May 2022 10:35:36 +0200
cronie (1.6.1-2) experimental; urgency=medium
* refreshed debian patches, which were targetted to version 1.5.5
-- Georges Khaznadar <georgesk@debian.org> Tue, 10 May 2022 17:56:24 +0200
cronie (1.6.1-1) experimental; urgency=medium
* New upstream version (1.6.1)
* Refreshed patches
* d/control: New maintainer (Closes: #974038)
* d/control: Updated standards (4.6.0), dh-compat (13)
-- Lance Lin <LQi254@protonmail.com> Tue, 03 May 2022 21:21:59 +0700
cronie (1.5.5-3) experimental; urgency=medium
* Add Hurd-workaround-for-PATH_MAX.patch (Closes: #638048)
* Fix spelling error in previous changelog entry
-- Christian Kastner <ckk@debian.org> Tue, 05 Nov 2019 08:04:37 +0100
cronie (1.5.5-2) experimental; urgency=medium
* Don't build /usr/sbin/anacron
/usr/sbin/anacron is still provided by src:anacron.
Thanks, Andreas Beckmann, for catching this! (Closes: #944024)
-- Christian Kastner <ckk@debian.org> Sun, 03 Nov 2019 11:12:33 +0100
cronie (1.5.5-1) experimental; urgency=medium
* New upstream version 1.5.5
* Drop patches (included upstream):
- crond-report-missing-newline-before-EOF.patch
- crontab-Add-Y-N-to-retry-prompt.patch
- crontab-fsync-to-check-for-full-disk.patch
- crontab.1-Various-fixes-and-improvements.patch
- entries-Explicitly-validate-upper-ranges-and-steps.patch
* Refresh patches
- debian/patches/Manpage-and-typo-fixes.patch
- debian/patches/Rename-PAM-service-to-cronie.patch
+ Split out Unbundle-upstream-PAM-config.patch from this one
-- Christian Kastner <ckk@debian.org> Thu, 31 Oct 2019 22:20:05 +0100
cronie (1.5.4-final-2) experimental; urgency=medium
* build: Set default EDITOR to /usr/bin/sensible-editor
* d/patches (added):
- crond-report-missing-newline-before-EOF.patch
- entries-Explicitly-validate-upper-ranges-and-steps.patch
- crontab.1-Various-fixes-and-improvements.patch
- crontab-Add-Y-N-to-retry-prompt.patch
- crontab-fsync-to-check-for-full-disk.patch
-- Christian Kastner <ckk@debian.org> Wed, 30 Oct 2019 21:12:01 +0100
cronie (1.5.4-final-1) experimental; urgency=medium
* New upstream release. (Closes: #697811, #783856)
[ Andreas Henriksson ]
* debian/watch: update for cronie move to github
* Modify patches to apply against new upstream release
* Add debian/gbp.conf
* Adjust and ship the cronie.service file
* Use debian/clean to remove src/cron-paths.h
* Fix lintian warning about not using default-mta
* Fix typo in patch tagging meta-header
[ Christian Kastner ]
* d/control:
- Switch Build-Depends from debhelper to debhelper-compat
- Bump debhelper compatibility level to 12
- Bump Standards-Version to 4.4.1 (no changes needed)
- Remove now obsolete d/compat file
- Set Rules-Requires-Root: no
We don't need (fake)root for building the package.
- Point Homepage to GitHub
- Set Vcs-* URLs for Salsa
- Mark package cronie as Multi-Arch: foreign
- Add Pre-Depends: ${misc:Pre-Depends} to binary package
As recommended by lintian's skip-systemd-native-flag-missing-pre-depends
* d/cronie.default: Add new daemon flag "-P"
* d/rules:
- Add hardening flags
- Stop passing actions to dh_installinit
This has been obsoleted by dependency-based booting in Wheezy, see
https://lists.debian.org/debian-devel/2013/05/msg01109.html
- Use DEB_HOST_ARCH_OS from /usr/share/dpkg/architecture.mk
- Proper passing of CFLAGS through DEB_CFLAGS_MAINT_APPEND
* d/copyright:
- Fix syntax errors
- Switch URL to official policy URL
- Point Source to GitHub
fedorahosted.org has been retired
- Bump copyrights
* d/clean: Remove generated files for (non-enabled) anacron build
* Sync maintscripts with src:cron
-- Christian Kastner <ckk@debian.org> Mon, 28 Oct 2019 19:35:38 +0100
cronie (1.4.8-1~exp1) experimental; urgency=low
* Initial release (Closes: #590876)
* debian/patches added:
- 0001-Unbundle-anacron
- 0002-Manpage-and-typo-fixes
- 0003-Rename-PAM-service-to-cronie
- 0004-Debian-specific-paths-and-features
- 0005-Extend-support-for-kFreeBSD-and-GNU-HURD
-- Christian Kastner <debian@kvr.at> Tue, 26 Jul 2011 14:00:34 +0200

2
debian/clean vendored Normal file
View File

@ -0,0 +1,2 @@
src/cron-paths.h
anacron/anacron-paths.h

46
debian/control vendored Normal file
View File

@ -0,0 +1,46 @@
Source: cronie
Section: admin
Priority: optional
Maintainer: Lance Lin <LQi254@protonmail.com>
Uploaders: Georges Khaznadar <georgesk@debian.org>
Build-Depends:
debhelper-compat (= 13),
libpam0g-dev,
libselinux1-dev [linux-any],
libaudit-dev [linux-any]
Rules-Requires-Root: no
Standards-Version: 4.6.0
Homepage: https://github.com/cronie-crond/cronie
Vcs-Git: https://salsa.debian.org/debian/cronie.git
Vcs-Browser: https://salsa.debian.org/debian/cronie
Package: cronie
Architecture: any
Multi-Arch: foreign
Pre-Depends:
${misc:Pre-Depends},
cron-daemon-common
Depends:
${shlibs:Depends},
${misc:Depends},
adduser,
lsb-base (>= 3.0-6),
libpam-runtime (>= 1.0.1-11),
sensible-utils
Recommends:
default-mta | mail-transport-agent
Suggests:
anacron (>= 2.0-1)
Provides: cron-daemon, cron
Conflicts: cron
Replaces: cron
Description: Process Scheduling Daemon
cronie is a daemon that runs specified programs at scheduled times and
optionally mails generated output to the user. It is a fork of the original
ISC cron and contains many improvements, such as:
* inotify support (Linux only)
* clustering support
* full PAM support
.
cronie is fully compatible with ISC cron (Debian's standard job scheduler),
and can be used as a drop-in replacement for it.

135
debian/copyright vendored Normal file
View File

@ -0,0 +1,135 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: cronie
Upstream-Contact: Marcela Mašláňová <mmaslano@redhat.com>
Source: https://github.com/cronie-crond/cronie
Files: *
Copyright: 1988,1989,1990,1993,1994, The Regents of the University of California
1997,2000, Internet Software Consortium, Inc.
2004, Internet Systems Consortium, Inc. ("ISC")
1997-2019, Red Hat, Inc.
2000,2002, Todd C. Miller
2010, Colin Dean
License: ISC
Files: src/popen.c
Copyright: 1989,1993,1994,2005, The Regents of the University of California
License: BSD-2-clause
Files: src/bitstring.h
Copyright: 1989,1993,2003, The Regents of the University of California
License: BSD-3-clause
Files: anacron/*
Copyright: 1998, Itai Tzur <itzur@actcom.co.il>
1999, Sean 'Shaleh' Perry <shaleh@debian.org>
2004, Pascal Hakim <pasc@redellipse.net>
2009-2019, Red Hat, Inc.
License: GPL-2+
Files: debian/*
Copyright: 2010-2019, Christian Kastner <ckk@debian.org>
2018, Andreas Henriksson <andreas@fatal.se>
License: GPL-3+
Files: debian/patches/*
Copyright: 2019, Christian Kastner <ckk@debian.org>
License: ISC
License: ISC
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
.
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
License: BSD-2-clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
License: BSD-3-clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
License: GPL-2+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.
On Debian systems, the full text of the GNU General Public
License version 2 can be found in the file
"/usr/share/common-licenses/GPL-2".
License: GPL-3+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
.
On Debian systems, the full text of the GNU General Public
License version 3 can be found in the file
"/usr/share/common-licenses/GPL-3".

13
debian/cronie.default vendored Normal file
View File

@ -0,0 +1,13 @@
# Defaults for cronie initscript
# This is a POSIX shell fragment
# Some additional options for the daemon
# See cron(8) for all options and a detailed explanation of these
#
# -m <cmd> shell command to use for sending mail instead of sendmail(8)
# -p lift some restrictions on user crontabs (owner, mode, type)
# -P Don't set PATH; instead, inherit it from the environment
# -c enable clustering support
# -s send job output to syslog instead of mail
#
DAEMON_ARGS=""

6
debian/cronie.dirs vendored Normal file
View File

@ -0,0 +1,6 @@
etc/cron.d
etc/cron.hourly
etc/cron.daily
etc/cron.weekly
etc/cron.monthly
var/spool/cron/crontabs

87
debian/cronie.init vendored Normal file
View File

@ -0,0 +1,87 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: cronie
# Required-Start: $remote_fs $syslog $time
# Required-Stop: $remote_fs $syslog $time
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: time-based job scheduler
# Description: cronie is a daemon that runs specified programs at
# scheduled times and optionally mails generated output
# to the user.
### END INIT INFO
# Author: Christian Kastner <ckk@debian.org>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="time-based job scheduler"
NAME=cronie
DAEMON_NAME=crond
DAEMON=/usr/sbin/$DAEMON_NAME
DAEMON_ARGS=""
PIDFILE=/var/run/$DAEMON_NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x $DAEMON ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
. /lib/lsb/init-functions
do_start()
{
start_daemon -p $PIDFILE $DAEMON $DAEMON_ARGS
}
do_stop()
{
killproc -p $PIDFILE $DAEMON
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 || exit 0 ;;
2|3) [ "$VERBOSE" != no ] && log_end_msg 1 || exit 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|3) [ "$VERBOSE" != no ] && log_end_msg 0 || exit 0 ;;
*) [ "$VERBOSE" != no ] && log_end_msg 1 || exit 1 ;;
esac
;;
status)
status_of_proc -p $PIDFILE "$DAEMON" "$DAEMON_NAME" && exit 0 || exit $?
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
if [ $? -eq 0 ]
then
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
else
# Failed to stop
log_end_msg 1
fi
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac

21
debian/cronie.pam vendored Normal file
View File

@ -0,0 +1,21 @@
# The PAM configuration file for cronie (cron daemon)
# Access control using /etc/security/access.conf
account required pam_access.so
# Set the loginuid process attribute
session required pam_loginuid.so
# Read environment variables from pam_env's default files, /etc/environment
# and /etc/security/pam_env.conf.
session required pam_env.so
# In addition to the above, read system locale information
session required pam_env.so envfile=/etc/default/locale
# Sets up user limits
session required pam_limits.so
@include common-account
@include common-session-noninteractive
@include common-auth

65
debian/cronie.postinst vendored Normal file
View File

@ -0,0 +1,65 @@
#!/bin/sh
set -e
# Analogous to Debian's ISC cron postinst script (for compatibility reasons)
crondir="/var/spool/cron"
action="$1"
if [ "$action" != configure ]
then
exit 0
fi
# Make sure group "crontab" exists (needed for running SGID)
getent group crontab > /dev/null 2>&1 || addgroup --system crontab
# Make crontab(1) SGID
if ! dpkg-statoverride --list /usr/bin/crontab > /dev/null
then
dpkg-statoverride --update --add root crontab 2755 /usr/bin/crontab
fi
# Adjust permissions for spool dir
# Can't use dpkg-statoverride for this because it doesn't cooperate nicely
# with cron alternatives such as bcron
if [ -d $crondir/crontabs ]
then
# This must be in sync with misc.c:check_spool_dir()
chown root:crontab $crondir/crontabs
chmod 1730 $crondir/crontabs
cd $crondir/crontabs
set +e
# Iterate over each entry in the spool directory, perform some sanity
# checks (see CVE-2017-9525), and chown/chgroup the crontabs
for tab_name in *
do
[ "$tab_name" = "*" ] && continue
tab_links=`stat -c '%h' "$tab_name"`
tab_owner=`stat -c '%U' "$tab_name"`
if [ ! -f "$tab_name" ]
then
echo "Warning: $tab_name is not a regular file!"
continue
elif [ "$tab_links" -ne 1 ]
then
echo "Warning: $tab_name has more than one hard link!"
continue
elif [ "$tab_owner" != "$tab_name" ]
then
echo "Warning: $tab_name name differs from owner $tab_owner!"
continue
fi
chown "$tab_owner:crontab" "$tab_name"
chmod 600 "$tab_name"
done
set -e
fi
#DEBHELPER#
exit 0

11
debian/cronie.postrm vendored Normal file
View File

@ -0,0 +1,11 @@
#!/bin/sh
set -e
if [ "$1" = "purge" ]
then
rm -f /etc/cron.allow /etc/cron.deny
fi
#DEBHELPER#
exit 0

6
debian/cronie.prerm vendored Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh
set -e
#DEBHELPER#
exit 0

2
debian/docs vendored Normal file
View File

@ -0,0 +1,2 @@
NEWS
README

0
debian/etc/cronie.deny vendored Normal file
View File

12
debian/etc/crontab.system vendored Normal file
View File

@ -0,0 +1,12 @@
# /etc/crontab: system-wide crontab
# See crontab(5)
# Set PATH to system default
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

2
debian/etc/placeholder vendored Normal file
View File

@ -0,0 +1,2 @@
# DO NOT REMOVE
# this file prevents dpkg from removing this directory

10
debian/gbp.conf vendored Normal file
View File

@ -0,0 +1,10 @@
[DEFAULT]
pristine-tar = True
debian-branch = debian/master
upstream-branch = upstream/latest
[buildpackage]
sign-tags = True
[pq]
patch-numbers = False

View File

@ -0,0 +1,75 @@
From: Christian Kastner <ckk@kvr.at>
Date: Thu, 28 Jul 2011 11:15:01 +0200
Subject: Debian-specific paths and features
Use Debian-specific paths and features. For example, the spool dir differs from
upstream, and we always build to use syslog.
Forwarded: not-needed
Last-Update: 2011-07-28
---
man/cron.8 | 15 ++-------------
man/crontab.1 | 2 +-
man/crontab.5 | 2 +-
3 files changed, 4 insertions(+), 15 deletions(-)
--- a/man/cron.8
+++ b/man/cron.8
@@ -41,7 +41,7 @@
.PP
.I Cron
searches
-.I /var/spool/cron
+.I /var/spool/cron/crontabs
for crontab files which are named after user accounts;
together with the system crontab
.IR /etc/crontab ,
@@ -88,7 +88,7 @@
.IR /etc/cron.d/
directory that contains system cronjobs stored for different users.
.TP
-.IR /var/spool/cron
+.IR /var/spool/cron/crontabs
directory that contains user crontables created by the
.BR crontab (1)
command.
@@ -181,17 +181,6 @@
.TP
.B "\-V"
Print version and exit.
-.SH SIGNALS
-When the
-.I SIGHUP
-is received, the
-.I Cron
-daemon will close and reopen its log file. This proves to be useful in
-scripts which rotate and age log files. Naturally, this is not relevant
-if
-.I Cron
-was built to use
-.IR syslog (3).
.SH CLUSTERING SUPPORT
In this version of
.IR Cron
--- a/man/crontab.1
+++ b/man/crontab.1
@@ -68,7 +68,7 @@
In this version of
.IR Cron
it is possible to use a network-mounted shared
-.I /var/spool/cron
+.I /var/spool/cron/crontabs
across a cluster of hosts and specify that only one of the hosts should
run the crontab jobs in the particular directory at any one time. You
may also use
--- a/man/crontab.5
+++ b/man/crontab.5
@@ -315,7 +315,7 @@
.SH FILES
.I /etc/crontab
main system crontab file.
-.I /var/spool/cron/
+.I /var/spool/cron/crontabs
a directory for storing crontabs defined by users.
.I /etc/cron.d/
a directory for storing system crontabs.

View File

@ -0,0 +1,36 @@
From: Christian Kastner <ckk@kvr.at>
Date: Sun, 7 Aug 2011 19:48:09 +0200
Subject: Extend support for kFreeBSD and GNU HURD
Extend some of the #ifdefs to include kFreeBSD and HURD where it's obviously OK
to do so
Forwarded: no
Last-Update: 2011-08-07
---
src/entry.c | 2 +-
src/pathnames.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/src/entry.c
+++ b/src/entry.c
@@ -403,7 +403,7 @@
}
else
log_it("CRON", getpid(), "ERROR", "can't set LOGNAME", 0);
-#if defined(BSD) || defined(__linux)
+#if defined(BSD) || defined(__linux) || defined(__GLIBC__) || defined(__gnu_hurd__)
if (glue_strings(envstr, sizeof envstr, "USER", pw->pw_name, '=')) {
if ((tenvp = env_set(e->envp, envstr)) == NULL) {
ecode = e_memory;
--- a/src/pathnames.h
+++ b/src/pathnames.h
@@ -26,7 +26,7 @@
#ifndef _PATHNAMES_H_
#define _PATHNAMES_H_
-#if (defined(BSD)) && (BSD >= 199103) || defined(__linux) || defined(AIX)
+#if (defined(BSD)) && (BSD >= 199103) || defined(__linux) || defined(AIX) || defined(__GLIBC__) || defined(__gnu_hurd__)
# include <paths.h>
#endif /*BSD*/

View File

@ -0,0 +1,27 @@
From: Christian Kastner <ckk@kvr.at>
Date: Tue, 5 Nov 2019 07:52:09 +0100
Subject: Hurd workaround for PATH_MAX
PATH_MAX is not defined on GNU Hurd, which is legal according to POSIX.
https://www.gnu.org/software/hurd/hurd/porting/guidelines.html
Bug-Debian: https://bugs.debian.org/638048
---
src/macros.h | 5 +++++
1 file changed, 5 insertions(+)
--- a/src/macros.h
+++ b/src/macros.h
@@ -43,6 +43,11 @@
#define DEBUGGING FALSE
#endif
+/* Gnu Hurd has no limit on pathnames */
+#if !defined PATH_MAX && defined __GNU__
+#define PATH_MAX 4096
+#endif
+
#define INIT_PID 1 /* parent of orphans */
#define READ_PIPE 0 /* which end of a pipe pair do you read? */
#define WRITE_PIPE 1 /* or write to? */

View File

@ -0,0 +1,133 @@
From: Christian Kastner <ckk@kvr.at>
Date: Thu, 28 Jul 2011 11:07:40 +0200
Subject: Manpage and typo fixes
Correct some errors or clarify sections in the manpages; fix some typos
---
man/cron.8 | 43 ++++++++++++++++---------------------------
man/crontab.1 | 2 +-
man/crontab.5 | 2 +-
src/cron.c | 2 +-
4 files changed, 19 insertions(+), 30 deletions(-)
--- a/man/cron.8
+++ b/man/cron.8
@@ -37,23 +37,15 @@
.B -V
.SH DESCRIPTION
.I Cron
-is started from
-.I /etc/rc.d/init.d
-or
-.I /etc/init.d
-when classical sysvinit scripts are used. In case systemd is enabled, then unit file is installed into
-.I /lib/systemd/system/crond.service
-and daemon is started by
-.I systemctl start crond.service
-command. It returns immediately, thus, there is no need to need to start it with
-the '&' parameter.
+is automatically started at boot time.
.PP
.I Cron
searches
.I /var/spool/cron
-for crontab files which are named after accounts in
-.I /etc/passwd;
-The found crontabs are loaded into the memory.
+for crontab files which are named after user accounts;
+together with the system crontab
+.IR /etc/crontab ,
+the found crontabs are loaded into the memory.
.I Cron
also searches for
any files in the
@@ -71,12 +63,11 @@
option.
.PP
There are two ways how changes in crontables are checked. The first
-method is checking the modtime of a file. The second method is using the
-inotify support. Using of inotify is logged in the
-.I /var/log/cron
-log after the daemon is started. The inotify support checks for changes
-in all crontables and accesses the hard disk only when a change is
-detected.
+method is checking the modtime of a file. The second method
+is using inotify support, which is only available on Linux.
+When the daemon uses inotify, it logs this fact to syslog on startup.
+The inotify support checks for changes in all crontables and accesses the
+hard disk only when a change is detected.
.PP
When using the modtime option,
.I Cron
@@ -99,13 +90,8 @@
.TP
.IR /var/spool/cron
directory that contains user crontables created by the
-.IR crontab
-command.
-.PP
-Note that the
.BR crontab (1)
-command updates the modtime of the spool directory whenever it changes a
-crontab.
+command.
.PP
.SS Daylight Saving Time and other time changes
Local time changes of less than three hours, such as those caused by the
@@ -153,7 +139,6 @@
standard input and send it as a mail message to the recipients specified
in the mail headers. Specifying the string
.I "off"
-(i.e., crond -m off)
will disable the sending of mail.
.TP
.B "\-n"
@@ -167,10 +152,14 @@
.B "\-f"
the same as -n, consistent with other crond implementations.
.TP
+.B "\-i"
+Disables inotify support (if present)
+.TP
.B "\-p"
Allows
.I Cron
-to accept any user set crontables.
+to accept any user set crontables (read: lift owner, type and mode
+restrictions)
.TP
.B "\-P"
Don't set PATH. PATH is instead inherited from the environment.
--- a/man/crontab.1
+++ b/man/crontab.1
@@ -109,7 +109,7 @@
.IR /etc/cron.d/
directory.
.PP
-The temporary directory can be set in an environment variable. If it is
+The temporary directory can be set using the environment variable $TMPDIR. If it is
not set by the user, the
.I /tmp
directory is used.
--- a/man/crontab.5
+++ b/man/crontab.5
@@ -268,7 +268,7 @@
# run at 2:15pm on the first of every month -- output mailed to paul
15 14 1 * * $HOME/bin/monthly
# run at 10 pm on weekdays, annoy Joe
-0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
+0 22 * * 1-5 mail \-s "It's 10pm" joe%Joe,%%Where are your kids?%
23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
5 4 * * sun echo "run at 5 after 4 every sunday"
.fi
--- a/src/cron.c
+++ b/src/cron.c
@@ -179,7 +179,7 @@
fprintf(stderr, "\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, " -h print this message \n");
- fprintf(stderr, " -i deamon runs without inotify support\n");
+ fprintf(stderr, " -i daemon runs without inotify support\n");
fprintf(stderr, " -m <comm> off, or specify preferred client for sending mails\n");
fprintf(stderr, " -n run in foreground\n");
fprintf(stderr, " -f run in foreground, the same as -n\n");

View File

@ -0,0 +1,24 @@
From: Christian Kastner <ckk@kvr.at>
Date: Thu, 28 Jul 2011 11:11:45 +0200
Subject: Rename PAM service to cronie
Upstream uses "crond"; we switch to "cron" to avoid confusion with Debian's ISC
cron (it uses "cron" but that might change).
Forwarded: not-needed
Last-Update: 2011-07-28
---
src/security.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/src/security.c
+++ b/src/security.c
@@ -195,7 +195,7 @@
int cron_start_pam(struct passwd *pw) {
int retcode = 0;
- retcode = pam_start("crond", pw->pw_name, &conv, &pamh);
+ retcode = pam_start("cronie", pw->pw_name, &conv, &pamh);
PAM_FAIL_CHECK;
retcode = pam_set_item(pamh, PAM_TTY, "cron");
PAM_FAIL_CHECK;

40
debian/patches/Unbundle-anacron.patch vendored Normal file
View File

@ -0,0 +1,40 @@
From: Christian Kastner <ckk@kvr.at>
Date: Thu, 28 Jul 2011 11:01:03 +0200
Subject: Unbundle anacron
Upstream has integrated anacron into cronie. Debian has its own package, so
we unbundle it (mostly by removing references to it).
Forwarded: not-needed
Last-Update: 2011-07-28
---
man/cron.8 | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
--- a/man/cron.8
+++ b/man/cron.8
@@ -56,8 +56,7 @@
The found crontabs are loaded into the memory.
.I Cron
also searches for
-.I /etc/anacrontab
-and any files in the
+any files in the
.I /etc/cron.d
directory, which have a different format (see
.BR crontab (5)).
@@ -91,12 +90,8 @@
checks these files and directories:
.TP
.IR /etc/crontab
-system crontab. Nowadays the file is empty by default. Originally it
-was usually used to run daily, weekly, monthly jobs. By default these
-jobs are now run through anacron which reads
-.IR /etc/anacrontab
-configuration file. See
-.BR anacrontab (5)
+system crontab, usually used to run daily, weekly, monthly jobs. See
+.BR crontab (5)
for more details.
.TP
.IR /etc/cron.d/

View File

@ -0,0 +1,27 @@
From: Christian Kastner <ckk@kvr.at>
Date: Thu, 31 Oct 2019 22:16:13 +0100
Subject: Unbundle upstream PAM config
We supply our own PAM config, tailored to the Debian setup.
Last-Update: 2019-10-31
---
Makefile.am | 7 -------
1 file changed, 7 deletions(-)
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,13 +24,6 @@
contrib/cronie.systemd \
anacron/ChangeLog.anacron
-if PAM
-pamdir = $(sysconfdir)/pam.d
-dist_pam_DATA = pam/crond
-else
-EXTRA_DIST += pam/crond
-endif
-
include anacron/Makemodule.am
include man/Makemodule.am
include src/Makemodule.am

View File

@ -0,0 +1,27 @@
From: Andreas Henriksson <andreas@fatal.se>
Date: Mon, 28 Oct 2019 19:33:53 +0100
Subject: Adjust the cronie.service file for debian use
Use default file instead of sysconfig, as shipped by this
package (debian/cronie.default) and also modify the variable
on ExecStart line as for what is used in the shipped default
file.
Forwarded: not-needed
---
contrib/cronie.systemd | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/contrib/cronie.systemd
+++ b/contrib/cronie.systemd
@@ -3,8 +3,8 @@
After=auditd.service nss-user-lookup.target systemd-user-sessions.service time-sync.target ypbind.service autofs.service
[Service]
-EnvironmentFile=/etc/sysconfig/crond
-ExecStart=/usr/sbin/crond -n $CRONDARGS
+EnvironmentFile=/etc/default/cronie
+ExecStart=/usr/sbin/crond -n $DAEMON_ARGS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure

8
debian/patches/series vendored Normal file
View File

@ -0,0 +1,8 @@
Unbundle-anacron.patch
Manpage-and-typo-fixes.patch
Rename-PAM-service-to-cronie.patch
Unbundle-upstream-PAM-config.patch
Debian-specific-paths-and-features.patch
Extend-support-for-kFreeBSD-and-GNU-HURD.patch
cronie-service-debianization.patch
Hurd-workaround-for-PATH_MAX.patch

76
debian/rules vendored Executable file
View File

@ -0,0 +1,76 @@
#!/usr/bin/make -f
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# For DEB_HOST_ARCH_OS
include /usr/share/dpkg/architecture.mk
# Add build flags
export DEB_CFLAGS_MAINT_APPEND = -Wall
# Add hardening flags
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# Build the config options string
CONFIG_OPTIONS =
# anacron is still being provided by src:anacron
CONFIG_OPTIONS += --disable-anacron
# Default EDITOR path
CONFIG_OPTIONS += --with-editor=/usr/bin/sensible-editor
# PAM is enabled by default
ifeq (,$(findstring nopam,$(DEB_BUILD_OPTIONS)))
CONFIG_OPTIONS += --with-pam
endif
##########################
### Linux-only options ###
ifeq ($(DEB_HOST_ARCH_OS), linux)
# SELINUX is enabled by default
ifeq (,$(findstring noselinux,$(DEB_BUILD_OPTIONS)))
CONFIG_OPTIONS += --with-selinux
endif
# inotify is enabled by default
ifeq (,$(findstring noinotify,$(DEB_BUILD_OPTIONS)))
CONFIG_OPTIONS += --with-inotify
endif
# audit is disabled by default
ifneq (,$(findstring withaudit,$(DEB_BUILD_OPTIONS)))
CONFIG_OPTIONS += --with-audit
endif
endif
##### End Linux-only #####
##########################
%:
dh $@
# Set SPOOL_DIR to Debian's traditional location for crontabs (see Policy)
# Set CRON_GROUP to "crontab" to enable SGID functionality (avoids SUID)
override_dh_auto_configure:
SPOOL_DIR=/var/spool/cron/crontabs \
dh_auto_configure CRON_GROUP=crontab -- $(CONFIG_OPTIONS)
override_dh_install:
dh_install
# Create /etc/cron.deny to allow crontab(1) for all users by default
install -m 644 debian/etc/cronie.deny debian/cronie/etc/cron.deny
# System-wide crontab: IS NOT INSTALLED HERE: SEE CON-DAEMON-COMMON
#install -m 644 debian/etc/crontab.system debian/cronie/etc/crontab
# Placeholders for dpkg: ARE NOT INSTALLED HERE: SEE CON-DAEMON-COMMON
#install -m 644 debian/etc/placeholder debian/cronie/etc/cron.d/.placeholder
#install -m 644 debian/etc/placeholder debian/cronie/etc/cron.hourly/.placeholder
#install -m 644 debian/etc/placeholder debian/cronie/etc/cron.daily/.placeholder
#install -m 644 debian/etc/placeholder debian/cronie/etc/cron.weekly/.placeholder
#install -m 644 debian/etc/placeholder debian/cronie/etc/cron.monthly/.placeholder
# systemd service file
install -d -m 755 debian/cronie/lib/systemd/system/
install -m 644 contrib/cronie.systemd debian/cronie/lib/systemd/system/cronie.service

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (quilt)

8
debian/watch vendored Normal file
View File

@ -0,0 +1,8 @@
version=4
# using Github's API with tags
opts="searchmode=plain,\
filenamemangle=s%v?@ANY_VERSION@%@PACKAGE@-$1.tar.gz%" \
https://api.github.com/repos/cronie-crond/cronie/tags?per_page=100 \
https://api.github.com/repos/[^/]+/[^/]+/tarball/refs/tags/v?@ANY_VERSION@

View File

@ -1,6 +0,0 @@
dist_man_MANS = crontab.1 crontab.5 cron.8 crond.8 cronnext.1
EXTRA_DIST = anacrontab.5 anacron.8
if ANACRON
dist_man_MANS += $(EXTRA_DIST)
endif

View File

@ -1,593 +0,0 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@ANACRON_TRUE@am__append_1 = $(EXTRA_DIST)
subdir = man
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
man1dir = $(mandir)/man1
am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \
"$(DESTDIR)$(man8dir)"
man5dir = $(mandir)/man5
man8dir = $(mandir)/man8
NROFF = nroff
MANS = $(dist_man_MANS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANACRONTAB = @ANACRONTAB@
ANACRON_SPOOL_DIR = @ANACRON_SPOOL_DIR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DAEMON_GROUPNAME = @DAEMON_GROUPNAME@
DAEMON_USERNAME = @DAEMON_USERNAME@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBAUDIT = @LIBAUDIT@
LIBOBJS = @LIBOBJS@
LIBPAM = @LIBPAM@
LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPOOL_DIR = @SPOOL_DIR@
STRIP = @STRIP@
SYSCRONTAB = @SYSCRONTAB@
SYS_CROND_DIR = @SYS_CROND_DIR@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
editor_defined = @editor_defined@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
dist_man_MANS = crontab.1 crontab.5 cron.8 crond.8 cronnext.1 \
$(am__append_1)
EXTRA_DIST = anacrontab.5 anacron.8
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu man/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-man1: $(dist_man_MANS)
@$(NORMAL_INSTALL)
@list1=''; \
list2='$(dist_man_MANS)'; \
test -n "$(man1dir)" \
&& test -n "`echo $$list1$$list2`" \
|| exit 0; \
echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
{ for i in $$list1; do echo "$$i"; done; \
if test -n "$$list2"; then \
for i in $$list2; do echo "$$i"; done \
| sed -n '/\.1[a-z]*$$/p'; \
fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
done; }
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man1dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.1[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
install-man5: $(dist_man_MANS)
@$(NORMAL_INSTALL)
@list1=''; \
list2='$(dist_man_MANS)'; \
test -n "$(man5dir)" \
&& test -n "`echo $$list1$$list2`" \
|| exit 0; \
echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
{ for i in $$list1; do echo "$$i"; done; \
if test -n "$$list2"; then \
for i in $$list2; do echo "$$i"; done \
| sed -n '/\.5[a-z]*$$/p'; \
fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
done; }
uninstall-man5:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man5dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.5[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
install-man8: $(dist_man_MANS)
@$(NORMAL_INSTALL)
@list1=''; \
list2='$(dist_man_MANS)'; \
test -n "$(man8dir)" \
&& test -n "`echo $$list1$$list2`" \
|| exit 0; \
echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
{ for i in $$list1; do echo "$$i"; done; \
if test -n "$$list2"; then \
for i in $$list2; do echo "$$i"; done \
| sed -n '/\.8[a-z]*$$/p'; \
fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
done; }
uninstall-man8:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man8dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.8[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
tags TAGS:
ctags CTAGS:
cscope cscopelist:
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(MANS)
installdirs:
for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-man
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man: install-man1 install-man5 install-man8
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-man
uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
ctags-am distclean distclean-generic distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-man1 install-man5 \
install-man8 install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \
uninstall uninstall-am uninstall-man uninstall-man1 \
uninstall-man5 uninstall-man8
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

16
man/Makemodule.am Normal file
View File

@ -0,0 +1,16 @@
dist_man_MANS = \
man/cron.8 \
man/crond.8 \
man/cronnext.1 \
man/crontab.1 \
man/crontab.5
anacron_man = \
man/anacrontab.5 \
man/anacron.8
EXTRA_DIST += $(anacron_man)
if ANACRON
dist_man_MANS += $(anacron_man)
endif

View File

@ -65,6 +65,23 @@ set to 12 would therefore add, randomly, between 0 and 12 minutes to the
delay in minutes for each job in that particular anacrontab. When set to
0, no random delay is added.
.PP
If
.I MAILTO
is defined (and non-empty), mail is sent to the specified address,
otherwise, system user is used.
.PP
If
.I MAILFROM
is defined (and non-empty), it is used as the envelope sender address,
otherwise, system user is used.
.PP
(Note: Both
.I MAILFROM
and
.I MAILTO
variables are expanded, so setting them as in the following example works as expected: MAILFROM=cron-$USER@cron.com ($USER is replaced by the system user) )
.PP
.PP
Empty lines are either blank lines, line containing white spaces only, or
lines with white spaces followed by a '#' followed by an arbitrary
comment.

View File

@ -169,6 +169,9 @@ must not enable
.I pam_loginuid.so
module.
.TP
.B "\-f"
the same as -n, consistent with other crond implementations.
.TP
.B "\-p"
Allows
.I Cron

View File

@ -6,7 +6,7 @@ cronnext \- time of next job cron will execute
.B cronnext
[\fB-i \fIusers\fR] [\fB-e \fIusers\fR] [\fB-s\fR]
[\fB-a\fR]
[\fB-t \fItime\fR] [\fB-q \fItime\fR]
[\fB-t \fItime\fR] [\fB-q \fItime\fR] [\fB-j \fIcommand\fR]
[\fB-l\fR] [\fB-c\fR] [\fB-f\fR] [\fB-h\fR] [\fB-V\fR]
[file]...
.SH DESCRIPTION
@ -52,6 +52,9 @@ and is internally rounded to the minute.
Do not check jobs over this time, expressed in the same way as in option
.BR -t .
.TP
.BI "\-j " command
Only look for jobs that contain \fIcommand\fP as a substring.
.TP
.B \-l
Print the whole entries of the jobs that are the next to be executed by cron.
The default is to only print their next time of execution.

View File

@ -22,7 +22,7 @@
.\"
.\" $Id: crontab.1,v 1.7 2004/01/23 19:03:32 vixie Exp $
.\"
.TH CRONTAB 1 "2012-11-22" "cronie" "User Commands"
.TH CRONTAB 1 "2019-10-29" "cronie" "User Commands"
.SH NAME
crontab \- maintains crontab files for individual users
.SH SYNOPSIS
@ -33,6 +33,11 @@ crontab \- maintains crontab files for individual users
.RB | \ - >
.br
.B crontab
.RB [ -T ]
.RI < "file"
.RB | \ - >
.br
.B crontab
.RB [ -u
.IR user ]
.RB < -l " | " -r " | " -e >\ [ -i ]
@ -67,18 +72,21 @@ it is possible to use a network-mounted shared
across a cluster of hosts and specify that only one of the hosts should
run the crontab jobs in the particular directory at any one time. You
may also use
.BR crontab (1)
.BR crontab
from any of these hosts to edit the same shared set of crontab files, and
to set and query which host should run the crontab jobs.
.PP
Running cron jobs can be allowed or disallowed for different users. For
this purpose, use the
Scheduling cron jobs with
.BR crontab
can be allowed or disallowed for different users. For this purpose, use the
.I cron.allow
and
.I cron.deny
files. If the
.I cron.allow
file exists, a user must be listed in it to be allowed to use cron If the
file exists, a user must be listed in it to be allowed to use
.BR crontab .
If the
.I cron.allow
file does not exist but the
.I cron.deny
@ -86,12 +94,17 @@ file does exist, then a user must
.I not
be listed in the
.I cron.deny
file in order to use cron. If neither of these files exists, only the
super user is allowed to use cron. Another way to restrict access to
cron is to use PAM authentication in
file in order to use
.BR crontab.
If neither of these files exist, then only the super user is allowed to use
.BR crontab .
.PP
Another way to restrict the scheduling of cron jobs beyond
.BR crontab
is to use PAM authentication in
.I /etc/security/access.conf
to set up users, which are allowed or disallowed to use
.I crontab
.BR crontab
or modify system cron jobs in the
.IR /etc/cron.d/
directory.
@ -101,17 +114,26 @@ not set by the user, the
.I /tmp
directory is used.
.PP
When listing a crontab on a terminal the output will be colorized unless
an environment variable
.I NO_COLOR
is set.
.PP
.SH "OPTIONS"
.TP
.B "\-u"
Specifies the name of the user whose crontab is to be modified. If this
option is not used,
.I crontab
.BR crontab
examines "your" crontab, i.e., the crontab of the person executing the
command. If no crontab exists for a particular user, it is created for
him the first time the
them the first time the
.B crontab -u
command is used under his username.
command is used under their username.
.TP
.B "\-T"
Test the crontab file syntax without installing it.
Once an issue is found, the validation is interrupted, so this will not return all the existing issues at the same execution.
.TP
.B "\-l"
Displays the current crontab on standard output.
@ -178,6 +200,27 @@ option.
.TP
.B "\-V"
Print version and exit.
.SH CAVEATS
The files
.I cron.allow
and
.I cron.deny
cannot be used to restrict the execution of cron jobs; they only restrict the
use of
.BR crontab .
In particular, restricting access to
.BR crontab
has no effect on an existing
.I crontab
of a user. Its jobs will continue to be executed until the crontab is removed.
.PP
The files
.I cron.allow
and
.I cron.deny
must be readable by the user invoking
.BR crontab .
If this is not the case, then they are treated as non-existent.
.SH "SEE ALSO"
.BR crontab (5),
.BR cron (8)
@ -192,9 +235,9 @@ The
command conforms to IEEE Std1003.2-1992 (``POSIX'') with one exception:
For replacing the current crontab with data from standard input the
.B \-
has to be specified on the command line. This new command
syntax differs from previous versions of Vixie Cron, as well as from the
classic SVR3 syntax.
has to be specified on the command line if the standard input is a TTY.
This new command syntax differs from previous versions of Vixie Cron,
as well as from the classic SVR3 syntax.
.SH DIAGNOSTICS
An informative usage message appears if you run a crontab with a faulty
command defined in it.

View File

@ -99,6 +99,12 @@ aliasing and UUCP usually does not read its mail. If
.I MAILFROM
is defined (and non-empty), it is used as the envelope sender address,
otherwise, ``root'' is used.
.PP
(Note: Both
.I MAILFROM
and
.I MAILTO
variables are expanded, so setting them as in the following example works as expected: MAILFROM=cron-$USER@cron.com ($USER is replaced by the system user) )
.PP
By default, cron sends a mail using the 'Content-Type:' header
of 'text/plain' with the 'charset=' parameter set to the 'charmap/codeset'
@ -199,6 +205,15 @@ hyphen. The specified range is inclusive. For example, 8-11 for
an 'hours' entry specifies execution at hours 8, 9, 10, and 11. The first
number must be less than or equal to the second one.
.PP
Randomization of the execution time within a range can be used.
A random number within a range specified as two numbers separated with
a tilde is picked. The specified range is inclusive.
For example, 6~15 for a 'minutes' entry picks a random minute
within 6 to 15 range. The random number is picked when crontab file is parsed.
The first number must be less than or equal to the second one. You might omit
one or both of the numbers specifying the range. For example, ~ for a 'minutes'
entry picks a random minute within 0 to 59 range.
.PP
Lists are allowed. A list is a set of numbers (or ranges) separated by
commas. Examples: "1,2,5,9", "0-4,8-12".
.PP
@ -212,7 +227,8 @@ two hours, you can use "*/2".
.PP
Names can also be used for the 'month' and 'day of week' fields. Use the
first three letters of the particular day or month (case does not
matter). Ranges or lists of names are not allowed.
matter). Ranges and lists of names are allowed. Examples: "mon,wed,fri",
"jan-mar".
.PP
If the UID of the owner is 0 (root), the first character of a crontab
entry can be "-" character. This will prevent cron from writing a syslog
@ -235,6 +251,10 @@ field matches the current time. For example,
.br
"30 4 1,15 * 5" would cause a command to be run at 4:30 am on the 1st and
15th of each month, plus every Friday.
.PP
A crontab file syntax can be tested before an install using the -T option. See
.BR crontab (1)
for details.
.SH EXAMPLE CRON FILE
.nf
# use /bin/sh to run commands, no matter what /etc/passwd says
@ -326,6 +346,11 @@ option on the crond command line. If inotify support is in use, changes
in the symlinked crontabs are not automatically noticed by the cron
daemon. The cron daemon must receive a SIGHUP signal to reload the
crontabs. This is a limitation of the inotify API.
.PP
cron requires that each entry in a crontab end in a newline character. If the
last entry in a crontab is missing a newline (i.e.\& terminated by EOF),
cron will consider the crontab (at least partially) broken.
A warning will be written to syslog.
.SH AUTHOR
.MT vixie@isc.org
Paul Vixie

376
obstack/obstack.c Normal file
View File

@ -0,0 +1,376 @@
/* obstack.c - subroutines used implicitly by object stack macros
Copyright (C) 1988-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifdef _LIBC
# include <obstack.h>
#else
# include <config.h>
# include "obstack.h"
#endif
/* NOTE BEFORE MODIFYING THIS FILE: _OBSTACK_INTERFACE_VERSION in
obstack.h must be incremented whenever callers compiled using an old
obstack.h can no longer properly call the functions in this file. */
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself, and the installed library
supports the same library interface we do. This code is part of the GNU
C Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand 'configure --with-gnu-libc' and omit the object
files, it is simpler to just do this in the source for each such file. */
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
# include <gnu-versions.h>
# if (_GNU_OBSTACK_INTERFACE_VERSION == _OBSTACK_INTERFACE_VERSION \
|| (_GNU_OBSTACK_INTERFACE_VERSION == 1 \
&& _OBSTACK_INTERFACE_VERSION == 2 \
&& defined SIZEOF_INT && defined SIZEOF_SIZE_T \
&& SIZEOF_INT == SIZEOF_SIZE_T))
# define _OBSTACK_ELIDE_CODE
# endif
#endif
#ifndef _OBSTACK_ELIDE_CODE
/* If GCC, or if an oddball (testing?) host that #defines __alignof__,
use the already-supplied __alignof__. Otherwise, this must be Gnulib
(as glibc assumes GCC); defer to Gnulib's alignof_type. */
# if !defined __GNUC__ && !defined __IBM__ALIGNOF__ && !defined __alignof__
# if defined __cplusplus
template <class type> struct alignof_helper { char __slot1; type __slot2; };
# define __alignof__(type) offsetof (alignof_helper<type>, __slot2)
# else
# define __alignof__(type) \
offsetof (struct { char __slot1; type __slot2; }, __slot2)
# endif
# endif
# include <stdlib.h>
# include <stdint.h>
# ifndef MAX
# define MAX(a,b) ((a) > (b) ? (a) : (b))
# endif
/* Determine default alignment. */
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
But in fact it might be less smart and round addresses to as much as
DEFAULT_ROUNDING. So we prepare for it to do that.
DEFAULT_ALIGNMENT cannot be an enum constant; see gnulib's alignof.h. */
#define DEFAULT_ALIGNMENT MAX (__alignof__ (long double), \
MAX (__alignof__ (uintmax_t), \
__alignof__ (void *)))
#define DEFAULT_ROUNDING MAX (sizeof (long double), \
MAX (sizeof (uintmax_t), \
sizeof (void *)))
/* Call functions with either the traditional malloc/free calling
interface, or the mmalloc/mfree interface (that adds an extra first
argument), based on the value of use_extra_arg. */
static void *
call_chunkfun (struct obstack *h, size_t size)
{
if (h->use_extra_arg)
return h->chunkfun.extra (h->extra_arg, size);
else
return h->chunkfun.plain (size);
}
static void
call_freefun (struct obstack *h, void *old_chunk)
{
if (h->use_extra_arg)
h->freefun.extra (h->extra_arg, old_chunk);
else
h->freefun.plain (old_chunk);
}
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
Objects start on multiples of ALIGNMENT (0 means use default).
Return nonzero if successful, calls obstack_alloc_failed_handler if
allocation fails. */
static int
_obstack_begin_worker (struct obstack *h,
_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment)
{
struct _obstack_chunk *chunk; /* points to new chunk */
if (alignment == 0)
alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block. */
{
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
Use the values for range checking, because if range checking is off,
the extra bytes won't be missed terribly, but if range checking is on
and we used a larger request, a whole extra 4096 bytes would be
allocated.
These number are irrelevant to the new GNU malloc. I suspect it is
less sensitive to the size of the request. */
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ 4 + DEFAULT_ROUNDING - 1)
& ~(DEFAULT_ROUNDING - 1));
size = 4096 - extra;
}
h->chunk_size = size;
h->alignment_mask = alignment - 1;
chunk = (struct _obstack_chunk *) call_chunkfun (h, h->chunk_size);
if (!chunk)
(*obstack_alloc_failed_handler) ();
h->chunk = chunk;
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
alignment - 1);
h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size;
chunk->prev = 0;
/* The initial chunk now contains no empty object. */
h->maybe_empty_object = 0;
h->alloc_failed = 0;
return 1;
}
int
_obstack_begin (struct obstack *h,
_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
void *(*chunkfun) (size_t),
void (*freefun) (void *))
{
h->chunkfun.plain = chunkfun;
h->freefun.plain = freefun;
h->use_extra_arg = 0;
return _obstack_begin_worker (h, size, alignment);
}
int
_obstack_begin_1 (struct obstack *h,
_OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,
void *(*chunkfun) (void *, size_t),
void (*freefun) (void *, void *),
void *arg)
{
h->chunkfun.extra = chunkfun;
h->freefun.extra = freefun;
h->extra_arg = arg;
h->use_extra_arg = 1;
return _obstack_begin_worker (h, size, alignment);
}
/* Allocate a new current chunk for the obstack *H
on the assumption that LENGTH bytes need to be added
to the current object, or a new object of length LENGTH allocated.
Copies any partial object from the end of the old chunk
to the beginning of the new one. */
void
_obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)
{
struct _obstack_chunk *old_chunk = h->chunk;
struct _obstack_chunk *new_chunk = 0;
size_t obj_size = h->next_free - h->object_base;
char *object_base;
/* Compute size for new chunk. */
size_t sum1 = obj_size + length;
size_t sum2 = sum1 + h->alignment_mask;
size_t new_size = sum2 + (obj_size >> 3) + 100;
if (new_size < sum2)
new_size = sum2;
if (new_size < h->chunk_size)
new_size = h->chunk_size;
/* Allocate and initialize the new chunk. */
if (obj_size <= sum1 && sum1 <= sum2)
new_chunk = (struct _obstack_chunk *) call_chunkfun (h, new_size);
if (!new_chunk)
(*obstack_alloc_failed_handler)();
h->chunk = new_chunk;
new_chunk->prev = old_chunk;
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
/* Compute an aligned object_base in the new chunk */
object_base =
__PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
/* Move the existing object to the new chunk. */
memcpy (object_base, h->object_base, obj_size);
/* If the object just copied was the only data in OLD_CHUNK,
free that chunk and remove it from the chain.
But not if that chunk might contain an empty object. */
if (!h->maybe_empty_object
&& (h->object_base
== __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
h->alignment_mask)))
{
new_chunk->prev = old_chunk->prev;
call_freefun (h, old_chunk);
}
h->object_base = object_base;
h->next_free = h->object_base + obj_size;
/* The new chunk certainly contains no empty object yet. */
h->maybe_empty_object = 0;
}
/* Return nonzero if object OBJ has been allocated from obstack H.
This is here for debugging.
If you use it in a program, you are probably losing. */
/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
obstack.h because it is just for debugging. */
int _obstack_allocated_p (struct obstack *h, void *obj) __attribute_pure__;
int
_obstack_allocated_p (struct obstack *h, void *obj)
{
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
lp = (h)->chunk;
/* We use >= rather than > since the object cannot be exactly at
the beginning of the chunk but might be an empty object exactly
at the end of an adjacent chunk. */
while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
{
plp = lp->prev;
lp = plp;
}
return lp != 0;
}
/* Free objects in obstack H, including OBJ and everything allocate
more recently than OBJ. If OBJ is zero, free everything in H. */
void
_obstack_free (struct obstack *h, void *obj)
{
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
lp = h->chunk;
/* We use >= because there cannot be an object at the beginning of a chunk.
But there can be an empty object at that address
at the end of another chunk. */
while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
{
plp = lp->prev;
call_freefun (h, lp);
lp = plp;
/* If we switch chunks, we can't tell whether the new current
chunk contains an empty object, so assume that it may. */
h->maybe_empty_object = 1;
}
if (lp)
{
h->object_base = h->next_free = (char *) (obj);
h->chunk_limit = lp->limit;
h->chunk = lp;
}
else if (obj != 0)
/* obj is not in any of the chunks! */
abort ();
}
_OBSTACK_SIZE_T
_obstack_memory_used (struct obstack *h)
{
struct _obstack_chunk *lp;
_OBSTACK_SIZE_T nbytes = 0;
for (lp = h->chunk; lp != 0; lp = lp->prev)
{
nbytes += lp->limit - (char *) lp;
}
return nbytes;
}
# ifndef _OBSTACK_NO_ERROR_HANDLER
/* Define the error handler. */
# include <stdio.h>
/* Exit value used when 'print_and_abort' is used. */
# ifdef _LIBC
int obstack_exit_failure = EXIT_FAILURE;
# else
# ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
# endif
# define obstack_exit_failure EXIT_FAILURE
# endif
# if defined _LIBC || (HAVE_LIBINTL_H && ENABLE_NLS)
# include <libintl.h>
# ifndef _
# define _(msgid) gettext (msgid)
# endif
# else
# ifndef _
# define _(msgid) (msgid)
# endif
# endif
# if !(defined _Noreturn \
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112))
# if ((defined __GNUC__ \
&& (__GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))) \
|| (defined __SUNPRO_C && __SUNPRO_C >= 0x5110))
# define _Noreturn __attribute__ ((__noreturn__))
# elif defined _MSC_VER && _MSC_VER >= 1200
# define _Noreturn __declspec (noreturn)
# else
# define _Noreturn
# endif
# endif
# ifdef _LIBC
# include <libio/iolibio.h>
# endif
static _Noreturn void
print_and_abort (void)
{
/* Don't change any of these strings. Yes, it would be possible to add
the newline to the string and use fputs or so. But this must not
happen because the "memory exhausted" message appears in other places
like this and the translation should be reused instead of creating
a very similar string which requires a separate translation. */
# ifdef _LIBC
(void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
# else
fprintf (stderr, "%s\n", _("memory exhausted"));
# endif
exit (obstack_exit_failure);
}
/* The functions allocating more room by calling 'obstack_chunk_alloc'
jump to the handler pointed to by 'obstack_alloc_failed_handler'.
This can be set to a user defined function which should either
abort gracefully or use longjump - but shouldn't return. This
variable by default points to the internal function
'print_and_abort'. */
void (*obstack_alloc_failed_handler) (void) = print_and_abort;
# endif /* !_OBSTACK_NO_ERROR_HANDLER */
#endif /* !_OBSTACK_ELIDE_CODE */

535
obstack/obstack.h Normal file
View File

@ -0,0 +1,535 @@
/* obstack.h - object stack macros
Copyright (C) 1988-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* Summary:
All the apparent functions defined here are macros. The idea
is that you would use these pre-tested macros to solve a
very specific set of problems, and they would run fast.
Caution: no side-effects in arguments please!! They may be
evaluated MANY times!!
These macros operate a stack of objects. Each object starts life
small, and may grow to maturity. (Consider building a word syllable
by syllable.) An object can move while it is growing. Once it has
been "finished" it never changes address again. So the "top of the
stack" is typically an immature growing object, while the rest of the
stack is of mature, fixed size and fixed address objects.
These routines grab large chunks of memory, using a function you
supply, called 'obstack_chunk_alloc'. On occasion, they free chunks,
by calling 'obstack_chunk_free'. You must define them and declare
them before using any obstack macros.
Each independent stack is represented by a 'struct obstack'.
Each of the obstack macros expects a pointer to such a structure
as the first argument.
One motivation for this package is the problem of growing char strings
in symbol tables. Unless you are "fascist pig with a read-only mind"
--Gosper's immortal quote from HAKMEM item 154, out of context--you
would not like to put any arbitrary upper limit on the length of your
symbols.
In practice this often means you will build many short symbols and a
few long symbols. At the time you are reading a symbol you don't know
how long it is. One traditional method is to read a symbol into a
buffer, realloc()ating the buffer every time you try to read a symbol
that is longer than the buffer. This is beaut, but you still will
want to copy the symbol from the buffer to a more permanent
symbol-table entry say about half the time.
With obstacks, you can work differently. Use one obstack for all symbol
names. As you read a symbol, grow the name in the obstack gradually.
When the name is complete, finalize it. Then, if the symbol exists already,
free the newly read name.
The way we do this is to take a large chunk, allocating memory from
low addresses. When you want to build a symbol in the chunk you just
add chars above the current "high water mark" in the chunk. When you
have finished adding chars, because you got to the end of the symbol,
you know how long the chars are, and you can create a new object.
Mostly the chars will not burst over the highest address of the chunk,
because you would typically expect a chunk to be (say) 100 times as
long as an average object.
In case that isn't clear, when we have enough chars to make up
the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
so we just point to it where it lies. No moving of chars is
needed and this is the second win: potentially long strings need
never be explicitly shuffled. Once an object is formed, it does not
change its address during its lifetime.
When the chars burst over a chunk boundary, we allocate a larger
chunk, and then copy the partly formed object from the end of the old
chunk to the beginning of the new larger chunk. We then carry on
accreting characters to the end of the object as we normally would.
A special macro is provided to add a single char at a time to a
growing object. This allows the use of register variables, which
break the ordinary 'growth' macro.
Summary:
We allocate large chunks.
We carve out one object at a time from the current chunk.
Once carved, an object never moves.
We are free to append data of any size to the currently
growing object.
Exactly one object is growing in an obstack at any one time.
You can run one obstack per control block.
You may have as many control blocks as you dare.
Because of the way we do it, you can "unwind" an obstack
back to a previous state. (You may remove objects much
as you would with a stack.)
*/
/* Don't do the contents of this file more than once. */
#ifndef _OBSTACK_H
#define _OBSTACK_H 1
#ifndef _OBSTACK_INTERFACE_VERSION
# define _OBSTACK_INTERFACE_VERSION 2
#endif
#include <stddef.h> /* For size_t and ptrdiff_t. */
#include <string.h> /* For __GNU_LIBRARY__, and memcpy. */
#if _OBSTACK_INTERFACE_VERSION == 1
/* For binary compatibility with obstack version 1, which used "int"
and "long" for these two types. */
# define _OBSTACK_SIZE_T unsigned int
# define _CHUNK_SIZE_T unsigned long
# define _OBSTACK_CAST(type, expr) ((type) (expr))
#else
/* Version 2 with sane types, especially for 64-bit hosts. */
# define _OBSTACK_SIZE_T size_t
# define _CHUNK_SIZE_T size_t
# define _OBSTACK_CAST(type, expr) (expr)
#endif
/* If B is the base of an object addressed by P, return the result of
aligning P to the next multiple of A + 1. B and P must be of type
char *. A + 1 must be a power of 2. */
#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
/* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case
where pointers can be converted to integers, aligned as integers,
and converted back again. If ptrdiff_t is narrower than a
pointer (e.g., the AS/400), play it safe and compute the alignment
relative to B. Otherwise, use the faster strategy of computing the
alignment relative to 0. */
#define __PTR_ALIGN(B, P, A) \
__BPTR_ALIGN (sizeof (ptrdiff_t) < sizeof (void *) ? (B) : (char *) 0, \
P, A)
#ifndef __attribute_pure__
# if defined __GNUC_MINOR__ && __GNUC__ * 1000 + __GNUC_MINOR__ >= 2096
# define __attribute_pure__ __attribute__ ((__pure__))
# else
# define __attribute_pure__
# endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct _obstack_chunk /* Lives at front of each chunk. */
{
char *limit; /* 1 past end of this chunk */
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
char contents[4]; /* objects begin here */
};
struct obstack /* control current object in current chunk */
{
_CHUNK_SIZE_T chunk_size; /* preferred size to allocate chunks in */
struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
char *object_base; /* address of object we are building */
char *next_free; /* where to add next char to current object */
char *chunk_limit; /* address of char after current chunk */
union
{
_OBSTACK_SIZE_T i;
void *p;
} temp; /* Temporary for some macros. */
_OBSTACK_SIZE_T alignment_mask; /* Mask of alignment for each object. */
/* These prototypes vary based on 'use_extra_arg'. */
union
{
void *(*plain) (size_t);
void *(*extra) (void *, size_t);
} chunkfun;
union
{
void (*plain) (void *);
void (*extra) (void *, void *);
} freefun;
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
unsigned use_extra_arg : 1; /* chunk alloc/dealloc funcs take extra arg */
unsigned maybe_empty_object : 1; /* There is a possibility that the current
chunk contains a zero-length object. This
prevents freeing the chunk if we allocate
a bigger chunk to replace it. */
unsigned alloc_failed : 1; /* No longer used, as we now call the failed
handler on error, but retained for binary
compatibility. */
};
/* Declare the external functions we use; they are in obstack.c. */
extern void _obstack_newchunk (struct obstack *, _OBSTACK_SIZE_T);
extern void _obstack_free (struct obstack *, void *);
extern int _obstack_begin (struct obstack *,
_OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
void *(*) (size_t), void (*) (void *));
extern int _obstack_begin_1 (struct obstack *,
_OBSTACK_SIZE_T, _OBSTACK_SIZE_T,
void *(*) (void *, size_t),
void (*) (void *, void *), void *);
extern _OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)
__attribute_pure__;
/* Error handler called when 'obstack_chunk_alloc' failed to allocate
more memory. This can be set to a user defined function which
should either abort gracefully or use longjump - but shouldn't
return. The default action is to print a message and abort. */
extern void (*obstack_alloc_failed_handler) (void);
/* Exit value used when 'print_and_abort' is used. */
extern int obstack_exit_failure;
/* Pointer to beginning of object being allocated or to be allocated next.
Note that this might not be the final address of the object
because a new chunk might be needed to hold the final size. */
#define obstack_base(h) ((void *) (h)->object_base)
/* Size for allocating ordinary chunks. */
#define obstack_chunk_size(h) ((h)->chunk_size)
/* Pointer to next byte not yet allocated in current chunk. */
#define obstack_next_free(h) ((void *) (h)->next_free)
/* Mask specifying low bits that should be clear in address of an object. */
#define obstack_alignment_mask(h) ((h)->alignment_mask)
/* To prevent prototype warnings provide complete argument list. */
#define obstack_init(h) \
_obstack_begin ((h), 0, 0, \
_OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
_OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
#define obstack_begin(h, size) \
_obstack_begin ((h), (size), 0, \
_OBSTACK_CAST (void *(*) (size_t), obstack_chunk_alloc), \
_OBSTACK_CAST (void (*) (void *), obstack_chunk_free))
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
_obstack_begin ((h), (size), (alignment), \
_OBSTACK_CAST (void *(*) (size_t), chunkfun), \
_OBSTACK_CAST (void (*) (void *), freefun))
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
_obstack_begin_1 ((h), (size), (alignment), \
_OBSTACK_CAST (void *(*) (void *, size_t), chunkfun), \
_OBSTACK_CAST (void (*) (void *, void *), freefun), arg)
#define obstack_chunkfun(h, newchunkfun) \
((void) ((h)->chunkfun.extra = (void *(*) (void *, size_t)) (newchunkfun)))
#define obstack_freefun(h, newfreefun) \
((void) ((h)->freefun.extra = (void *(*) (void *, void *)) (newfreefun)))
#define obstack_1grow_fast(h, achar) ((void) (*((h)->next_free)++ = (achar)))
#define obstack_blank_fast(h, n) ((void) ((h)->next_free += (n)))
#define obstack_memory_used(h) _obstack_memory_used (h)
#if defined __GNUC__
# if !defined __GNUC_MINOR__ || __GNUC__ * 1000 + __GNUC_MINOR__ < 2008
# define __extension__
# endif
/* For GNU C, if not -traditional,
we can define these macros to compute all args only once
without using a global variable.
Also, we can avoid using the 'temp' slot, to make faster code. */
# define obstack_object_size(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(_OBSTACK_SIZE_T) (__o->next_free - __o->object_base); })
/* The local variable is named __o1 to avoid a shadowed variable
warning when invoked from other obstack macros. */
# define obstack_room(OBSTACK) \
__extension__ \
({ struct obstack const *__o1 = (OBSTACK); \
(_OBSTACK_SIZE_T) (__o1->chunk_limit - __o1->next_free); })
# define obstack_make_room(OBSTACK, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
_OBSTACK_SIZE_T __len = (length); \
if (obstack_room (__o) < __len) \
_obstack_newchunk (__o, __len); \
(void) 0; })
# define obstack_empty_p(OBSTACK) \
__extension__ \
({ struct obstack const *__o = (OBSTACK); \
(__o->chunk->prev == 0 \
&& __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
__o->chunk->contents, \
__o->alignment_mask)); })
# define obstack_grow(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
_OBSTACK_SIZE_T __len = (length); \
if (obstack_room (__o) < __len) \
_obstack_newchunk (__o, __len); \
memcpy (__o->next_free, where, __len); \
__o->next_free += __len; \
(void) 0; })
# define obstack_grow0(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
_OBSTACK_SIZE_T __len = (length); \
if (obstack_room (__o) < __len + 1) \
_obstack_newchunk (__o, __len + 1); \
memcpy (__o->next_free, where, __len); \
__o->next_free += __len; \
*(__o->next_free)++ = 0; \
(void) 0; })
# define obstack_1grow(OBSTACK, datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (obstack_room (__o) < 1) \
_obstack_newchunk (__o, 1); \
obstack_1grow_fast (__o, datum); })
/* These assume that the obstack alignment is good enough for pointers
or ints, and that the data added so far to the current object
shares that much alignment. */
# define obstack_ptr_grow(OBSTACK, datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (obstack_room (__o) < sizeof (void *)) \
_obstack_newchunk (__o, sizeof (void *)); \
obstack_ptr_grow_fast (__o, datum); })
# define obstack_int_grow(OBSTACK, datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (obstack_room (__o) < sizeof (int)) \
_obstack_newchunk (__o, sizeof (int)); \
obstack_int_grow_fast (__o, datum); })
# define obstack_ptr_grow_fast(OBSTACK, aptr) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
void *__p1 = __o1->next_free; \
*(const void **) __p1 = (aptr); \
__o1->next_free += sizeof (const void *); \
(void) 0; })
# define obstack_int_grow_fast(OBSTACK, aint) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
void *__p1 = __o1->next_free; \
*(int *) __p1 = (aint); \
__o1->next_free += sizeof (int); \
(void) 0; })
# define obstack_blank(OBSTACK, length) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
_OBSTACK_SIZE_T __len = (length); \
if (obstack_room (__o) < __len) \
_obstack_newchunk (__o, __len); \
obstack_blank_fast (__o, __len); })
# define obstack_alloc(OBSTACK, length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_blank (__h, (length)); \
obstack_finish (__h); })
# define obstack_copy(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_grow (__h, (where), (length)); \
obstack_finish (__h); })
# define obstack_copy0(OBSTACK, where, length) \
__extension__ \
({ struct obstack *__h = (OBSTACK); \
obstack_grow0 (__h, (where), (length)); \
obstack_finish (__h); })
/* The local variable is named __o1 to avoid a shadowed variable
warning when invoked from other obstack macros, typically obstack_free. */
# define obstack_finish(OBSTACK) \
__extension__ \
({ struct obstack *__o1 = (OBSTACK); \
void *__value = (void *) __o1->object_base; \
if (__o1->next_free == __value) \
__o1->maybe_empty_object = 1; \
__o1->next_free \
= __PTR_ALIGN (__o1->object_base, __o1->next_free, \
__o1->alignment_mask); \
if ((size_t) (__o1->next_free - (char *) __o1->chunk) \
> (size_t) (__o1->chunk_limit - (char *) __o1->chunk)) \
__o1->next_free = __o1->chunk_limit; \
__o1->object_base = __o1->next_free; \
__value; })
# define obstack_free(OBSTACK, OBJ) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
void *__obj = (void *) (OBJ); \
if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) \
__o->next_free = __o->object_base = (char *) __obj; \
else \
_obstack_free (__o, __obj); })
#else /* not __GNUC__ */
# define obstack_object_size(h) \
((_OBSTACK_SIZE_T) ((h)->next_free - (h)->object_base))
# define obstack_room(h) \
((_OBSTACK_SIZE_T) ((h)->chunk_limit - (h)->next_free))
# define obstack_empty_p(h) \
((h)->chunk->prev == 0 \
&& (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
(h)->chunk->contents, \
(h)->alignment_mask))
/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
so that we can avoid having void expressions
in the arms of the conditional expression.
Casting the third operand to void was tried before,
but some compilers won't accept it. */
# define obstack_make_room(h, length) \
((h)->temp.i = (length), \
((obstack_room (h) < (h)->temp.i) \
? (_obstack_newchunk (h, (h)->temp.i), 0) : 0), \
(void) 0)
# define obstack_grow(h, where, length) \
((h)->temp.i = (length), \
((obstack_room (h) < (h)->temp.i) \
? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.i), \
(h)->next_free += (h)->temp.i, \
(void) 0)
# define obstack_grow0(h, where, length) \
((h)->temp.i = (length), \
((obstack_room (h) < (h)->temp.i + 1) \
? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0), \
memcpy ((h)->next_free, where, (h)->temp.i), \
(h)->next_free += (h)->temp.i, \
*((h)->next_free)++ = 0, \
(void) 0)
# define obstack_1grow(h, datum) \
(((obstack_room (h) < 1) \
? (_obstack_newchunk ((h), 1), 0) : 0), \
obstack_1grow_fast (h, datum))
# define obstack_ptr_grow(h, datum) \
(((obstack_room (h) < sizeof (char *)) \
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
obstack_ptr_grow_fast (h, datum))
# define obstack_int_grow(h, datum) \
(((obstack_room (h) < sizeof (int)) \
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
obstack_int_grow_fast (h, datum))
# define obstack_ptr_grow_fast(h, aptr) \
(((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr), \
(void) 0)
# define obstack_int_grow_fast(h, aint) \
(((int *) ((h)->next_free += sizeof (int)))[-1] = (aint), \
(void) 0)
# define obstack_blank(h, length) \
((h)->temp.i = (length), \
((obstack_room (h) < (h)->temp.i) \
? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \
obstack_blank_fast (h, (h)->temp.i))
# define obstack_alloc(h, length) \
(obstack_blank ((h), (length)), obstack_finish ((h)))
# define obstack_copy(h, where, length) \
(obstack_grow ((h), (where), (length)), obstack_finish ((h)))
# define obstack_copy0(h, where, length) \
(obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
# define obstack_finish(h) \
(((h)->next_free == (h)->object_base \
? (((h)->maybe_empty_object = 1), 0) \
: 0), \
(h)->temp.p = (h)->object_base, \
(h)->next_free \
= __PTR_ALIGN ((h)->object_base, (h)->next_free, \
(h)->alignment_mask), \
(((size_t) ((h)->next_free - (char *) (h)->chunk) \
> (size_t) ((h)->chunk_limit - (char *) (h)->chunk)) \
? ((h)->next_free = (h)->chunk_limit) : 0), \
(h)->object_base = (h)->next_free, \
(h)->temp.p)
# define obstack_free(h, obj) \
((h)->temp.p = (void *) (obj), \
(((h)->temp.p > (void *) (h)->chunk \
&& (h)->temp.p < (void *) (h)->chunk_limit) \
? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.p) \
: _obstack_free ((h), (h)->temp.p)))
#endif /* not __GNUC__ */
#ifdef __cplusplus
} /* C++ */
#endif
#endif /* _OBSTACK_H */

View File

@ -1,788 +0,0 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# Makefile.am - two binaries crond and crontab
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
sbin_PROGRAMS = crond$(EXEEXT)
bin_PROGRAMS = crontab$(EXEEXT) cronnext$(EXEEXT)
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"
PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS)
am__objects_1 = entry.$(OBJEXT) env.$(OBJEXT) misc.$(OBJEXT) \
pw_dup.$(OBJEXT)
am_crond_OBJECTS = cron.$(OBJEXT) database.$(OBJEXT) user.$(OBJEXT) \
job.$(OBJEXT) do_command.$(OBJEXT) popen.$(OBJEXT) \
security.$(OBJEXT) $(am__objects_1)
am__objects_2 =
nodist_crond_OBJECTS = $(am__objects_2)
crond_OBJECTS = $(am_crond_OBJECTS) $(nodist_crond_OBJECTS)
crond_LDADD = $(LDADD)
am__DEPENDENCIES_1 =
crond_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
am_cronnext_OBJECTS = cronnext.$(OBJEXT) database.$(OBJEXT) \
user.$(OBJEXT) job.$(OBJEXT) $(am__objects_1)
nodist_cronnext_OBJECTS = $(am__objects_2)
cronnext_OBJECTS = $(am_cronnext_OBJECTS) $(nodist_cronnext_OBJECTS)
cronnext_LDADD = $(LDADD)
cronnext_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
am_crontab_OBJECTS = crontab.$(OBJEXT) security.$(OBJEXT) \
$(am__objects_1)
nodist_crontab_OBJECTS = $(am__objects_2)
crontab_OBJECTS = $(am_crontab_OBJECTS) $(nodist_crontab_OBJECTS)
crontab_LDADD = $(LDADD)
crontab_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/cron.Po ./$(DEPDIR)/cronnext.Po \
./$(DEPDIR)/crontab.Po ./$(DEPDIR)/database.Po \
./$(DEPDIR)/do_command.Po ./$(DEPDIR)/entry.Po \
./$(DEPDIR)/env.Po ./$(DEPDIR)/job.Po ./$(DEPDIR)/misc.Po \
./$(DEPDIR)/popen.Po ./$(DEPDIR)/pw_dup.Po \
./$(DEPDIR)/security.Po ./$(DEPDIR)/user.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(crond_SOURCES) $(nodist_crond_SOURCES) $(cronnext_SOURCES) \
$(nodist_cronnext_SOURCES) $(crontab_SOURCES) \
$(nodist_crontab_SOURCES)
DIST_SOURCES = $(crond_SOURCES) $(cronnext_SOURCES) $(crontab_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
ANACRONTAB = @ANACRONTAB@
ANACRON_SPOOL_DIR = @ANACRON_SPOOL_DIR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DAEMON_GROUPNAME = @DAEMON_GROUPNAME@
DAEMON_USERNAME = @DAEMON_USERNAME@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBAUDIT = @LIBAUDIT@
LIBOBJS = @LIBOBJS@
LIBPAM = @LIBPAM@
LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SPOOL_DIR = @SPOOL_DIR@
STRIP = @STRIP@
SYSCRONTAB = @SYSCRONTAB@
SYS_CROND_DIR = @SYS_CROND_DIR@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
editor_defined = @editor_defined@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
crond_SOURCES = \
cron.c database.c user.c job.c do_command.c popen.c security.c \
$(common_src)
crontab_SOURCES = crontab.c security.c $(common_src)
cronnext_SOURCES = \
cronnext.c database.c user.c job.c \
$(common_src)
common_src = entry.c env.c misc.c pw_dup.c \
externs.h funcs.h globals.h macros.h pathnames.h structs.h \
bitstring.h
common_nodist = cron-paths.h
nodist_crond_SOURCES = $(common_nodist)
nodist_crontab_SOURCES = $(common_nodist)
nodist_cronnext_SOURCES = $(common_nodist)
BUILT_SOURCES = $(common_nodist)
AM_CFLAGS = -I$(top_srcdir)
LDADD = $(LIBSELINUX) $(LIBPAM) $(LIBAUDIT)
# This header contains all the paths.
# If they are configurable, they are declared in configure script.
# Depends on this Makefile, because it uses make variables.
# CCD 2010/09/10 added CRON_HOSTNAME for clustered-cron.
CLEANFILES = cron-paths.h
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p \
; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' \
-e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' \
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p \
; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' \
-e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
} \
; done
uninstall-sbinPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' \
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(sbindir)" && rm -f $$files
clean-sbinPROGRAMS:
-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
crond$(EXEEXT): $(crond_OBJECTS) $(crond_DEPENDENCIES) $(EXTRA_crond_DEPENDENCIES)
@rm -f crond$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(crond_OBJECTS) $(crond_LDADD) $(LIBS)
cronnext$(EXEEXT): $(cronnext_OBJECTS) $(cronnext_DEPENDENCIES) $(EXTRA_cronnext_DEPENDENCIES)
@rm -f cronnext$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(cronnext_OBJECTS) $(cronnext_LDADD) $(LIBS)
crontab$(EXEEXT): $(crontab_OBJECTS) $(crontab_DEPENDENCIES) $(EXTRA_crontab_DEPENDENCIES)
@rm -f crontab$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(crontab_OBJECTS) $(crontab_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cron.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cronnext.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crontab.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/database.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/do_command.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/entry.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/job.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/popen.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pw_dup.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user.Po@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic clean-sbinPROGRAMS \
mostlyclean-am
distclean: distclean-am
-rm -f ./$(DEPDIR)/cron.Po
-rm -f ./$(DEPDIR)/cronnext.Po
-rm -f ./$(DEPDIR)/crontab.Po
-rm -f ./$(DEPDIR)/database.Po
-rm -f ./$(DEPDIR)/do_command.Po
-rm -f ./$(DEPDIR)/entry.Po
-rm -f ./$(DEPDIR)/env.Po
-rm -f ./$(DEPDIR)/job.Po
-rm -f ./$(DEPDIR)/misc.Po
-rm -f ./$(DEPDIR)/popen.Po
-rm -f ./$(DEPDIR)/pw_dup.Po
-rm -f ./$(DEPDIR)/security.Po
-rm -f ./$(DEPDIR)/user.Po
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-binPROGRAMS install-sbinPROGRAMS
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/cron.Po
-rm -f ./$(DEPDIR)/cronnext.Po
-rm -f ./$(DEPDIR)/crontab.Po
-rm -f ./$(DEPDIR)/database.Po
-rm -f ./$(DEPDIR)/do_command.Po
-rm -f ./$(DEPDIR)/entry.Po
-rm -f ./$(DEPDIR)/env.Po
-rm -f ./$(DEPDIR)/job.Po
-rm -f ./$(DEPDIR)/misc.Po
-rm -f ./$(DEPDIR)/popen.Po
-rm -f ./$(DEPDIR)/pw_dup.Po
-rm -f ./$(DEPDIR)/security.Po
-rm -f ./$(DEPDIR)/user.Po
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS
.MAKE: all check install install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-binPROGRAMS clean-generic clean-sbinPROGRAMS \
cscopelist-am ctags ctags-am distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-binPROGRAMS \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
uninstall-sbinPROGRAMS
.PRECIOUS: Makefile
cron-paths.h: Makefile
@echo 'creating $@'
@sed >$@ 's/ *\\$$//' <<\END #\
/* This file has been automatically generated. Do not edit. */ \
\
#ifndef _CRON_PATHS_H_ \
#define _CRON_PATHS_H_ \
\
/* SPOOLDIR is where the crontabs live. \
* This directory will have its modtime updated \
* whenever crontab(1) changes a crontab; this is \
* the signal for cron(8) to look at each individual \
* crontab file and reload those whose modtimes are \
* newer than they were last time around (or which \
* didn't exist last time around...) \
* or it will be checked by inotify \
*/ \
#define SPOOL_DIR "$(SPOOL_DIR)" \
\
/* CRON_HOSTNAME is file in SPOOL_DIR which, if it \
* exists, and does not just contain a line matching \
* the name returned by gethostname(), causes all \
* crontabs in SPOOL_DIR to be ignored. This is \
* intended to be used when clustering hosts sharing \
* one NFS-mounted SPOOL_DIR, and where only one host \
* should use the crontab files here at any one time. \
*/ \
#define CRON_HOSTNAME ".cron.hostname" \
\
/* cron allow/deny file. At least cron.deny must \
* exist for ordinary users to run crontab. \
*/ \
#define CRON_ALLOW "$(sysconfdir)/cron.allow" \
#define CRON_DENY "$(sysconfdir)/cron.deny" \
\
/* 4.3BSD-style crontab f.e. /etc/crontab */ \
#define SYSCRONTAB "$(SYSCRONTAB)" \
\
/* system crontab dir f.e. /etc/cron.d/ */ \
#define SYS_CROND_DIR "$(SYS_CROND_DIR)" \
\
#define SYSCONFDIR "$(sysconfdir)" \
\
#endif /* _CRON_PATHS_H_ */ \
END
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,27 +1,56 @@
# Makefile.am - two binaries crond and crontab
sbin_PROGRAMS = crond
bin_PROGRAMS = crontab cronnext
sbin_PROGRAMS += \
src/crond
crond_SOURCES = \
cron.c database.c user.c job.c do_command.c popen.c security.c \
bin_PROGRAMS += \
src/cronnext \
src/crontab
src_crond_SOURCES = \
src/cron.c \
src/database.c \
src/do_command.c \
src/job.c \
src/popen.c \
src/security.c \
src/user.c \
cronie_common.c \
$(common_src)
crontab_SOURCES = crontab.c security.c $(common_src)
cronnext_SOURCES = \
cronnext.c database.c user.c job.c \
src_crontab_SOURCES = \
src/crontab.c \
src/security.c \
$(common_src)
common_src = entry.c env.c misc.c pw_dup.c \
externs.h funcs.h globals.h macros.h pathnames.h structs.h \
bitstring.h
common_nodist = cron-paths.h
nodist_crond_SOURCES = $(common_nodist)
nodist_crontab_SOURCES = $(common_nodist)
nodist_cronnext_SOURCES = $(common_nodist)
BUILT_SOURCES = $(common_nodist)
AM_CFLAGS = -I$(top_srcdir)
src_cronnext_SOURCES = \
src/cronnext.c \
src/database.c \
src/job.c \
src/user.c \
$(common_src)
LDADD = $(LIBSELINUX) $(LIBPAM) $(LIBAUDIT)
common_src = \
src/bitstring.h \
src/entry.c \
src/env.c \
src/externs.h \
src/funcs.h \
src/globals.h \
src/macros.h \
src/misc.c \
src/pathnames.h \
src/pw_dup.c \
src/structs.h
common_nodist += cron-paths.h
nodist_src_crond_SOURCES = $(common_nodist)
nodist_src_crontab_SOURCES = $(common_nodist)
nodist_src_cronnext_SOURCES = $(common_nodist)
BUILT_SOURCES += $(common_nodist)
src_crond_LDADD = $(LIBSELINUX) $(LIBPAM) $(LIBAUDIT)
src_crontab_LDADD = $(LIBSELINUX) $(LIBPAM) $(LIBAUDIT)
## if DEBUG
## noinst_PROGRAMS = debug
@ -31,7 +60,14 @@ LDADD = $(LIBSELINUX) $(LIBPAM) $(LIBAUDIT)
# If they are configurable, they are declared in configure script.
# Depends on this Makefile, because it uses make variables.
# CCD 2010/09/10 added CRON_HOSTNAME for clustered-cron.
CLEANFILES = cron-paths.h
CLEANFILES += cron-paths.h
if HAS_RUNSTATE
cronpidcomment=/* directory of cron pid file */
cronpiddir=\#define CRON_PID_DIR "$(runstatedir)"
else
cronpidcomment=
cronpiddir=
endif
cron-paths.h: Makefile
@echo 'creating $@'
@sed >$@ 's/ *\\$$//' <<\END #\
@ -66,6 +102,9 @@ cron-paths.h: Makefile
*/ \
#define CRON_ALLOW "$(sysconfdir)/cron.allow" \
#define CRON_DENY "$(sysconfdir)/cron.deny" \
\
$(cronpidcomment) \
$(cronpiddir) \
\
/* 4.3BSD-style crontab f.e. /etc/crontab */ \
#define SYSCRONTAB "$(SYSCRONTAB)" \

View File

@ -40,15 +40,12 @@
#include <sys/wait.h>
#include <unistd.h>
#include <sys/time.h>
#include <fcntl.h>
#ifdef WITH_INOTIFY
# include <sys/inotify.h>
#endif
#ifdef HAVE_SYS_FCNTL_H
# include <sys/fcntl.h>
#endif
#include "cronie_common.h"
#include "funcs.h"
#include "globals.h"
@ -68,8 +65,9 @@ find_jobs(int, cron_db *, int, int, long),
set_time(int),
cron_sleep(int, cron_db *),
sigchld_handler(int),
sighup_handler(int),
sigchld_reaper(void), sigintterm_handler(int), parse_args(int c, char *v[]);
sighup_handler(int ATTRIBUTE_UNUSED),
sigchld_reaper(void),
sigintterm_handler(int ATTRIBUTE_UNUSED), parse_args(int c, char *v[]);
static volatile sig_atomic_t got_sighup, got_sigchld, got_sigintterm;
static int timeRunning, virtualTime, clockTime;
@ -184,8 +182,10 @@ static void usage(void) {
fprintf(stderr, " -i deamon runs without inotify support\n");
fprintf(stderr, " -m <comm> off, or specify preferred client for sending mails\n");
fprintf(stderr, " -n run in foreground\n");
fprintf(stderr, " -f run in foreground, the same as -n\n");
fprintf(stderr, " -p permit any crontab\n");
fprintf(stderr, " -P use PATH=\"%s\"\n", _PATH_DEFPATH);
fprintf(stderr, " -P inherit PATH from environment instead of using default value");
fprintf(stderr, " of \"%s\"\n", _PATH_DEFPATH);
fprintf(stderr, " -c enable clustering support\n");
fprintf(stderr, " -s log into syslog instead of sending mails\n");
fprintf(stderr, " -V print version and exit\n");
@ -261,7 +261,7 @@ int main(int argc, char *argv[]) {
*/
setlocale(LC_ALL, ""); /* set locale to system defaults or to
* that specified by any LC_* env vars */
if ((cs = nl_langinfo(CODESET)) != 0L)
if ((cs = nl_langinfo(CODESET)) != NULL)
strncpy(cron_default_mail_charset, cs, MAX_ENVSTR-1);
else
strcpy(cron_default_mail_charset, "US-ASCII");
@ -309,16 +309,11 @@ int main(int argc, char *argv[]) {
if (gettimeofday(&tv, &tz) != 0)
tv.tv_usec = 0;
srandom((unsigned int)(pid + tv.tv_usec));
RandomScale = (double)random() / (double)RAND_MAX;
RandomScale = (double)random() / (double)(1lu << 31);
snprintf(buf, sizeof(buf), "RANDOM_DELAY will be scaled with factor %d%% if used.", (int)(RandomScale*100));
log_it("CRON", pid, "INFO", buf, 0);
acquire_daemonlock(0);
database.head = NULL;
database.tail = NULL;
database.mtime = (time_t) 0;
load_database(&database);
fd = -1;
#if defined WITH_INOTIFY
@ -336,6 +331,12 @@ int main(int argc, char *argv[]) {
}
#endif
database.head = NULL;
database.tail = NULL;
database.mtime = (time_t) 0;
load_database(&database);
set_time(TRUE);
run_reboot_jobs(&database);
timeRunning = virtualTime = clockTime;
@ -651,15 +652,15 @@ static void cron_sleep(int target, cron_db * db) {
}
}
static void sighup_handler(int x) {
static void sighup_handler(int x ATTRIBUTE_UNUSED) {
got_sighup = 1;
}
static void sigchld_handler(int x) {
static void sigchld_handler(int x ATTRIBUTE_UNUSED) {
got_sigchld = 1;
}
static void sigintterm_handler(int x) {
static void sigintterm_handler(int x ATTRIBUTE_UNUSED) {
got_sigintterm = 1;
}
@ -690,13 +691,14 @@ static void sigchld_reaper(void) {
static void parse_args(int argc, char *argv[]) {
int argch;
while (-1 != (argch = getopt(argc, argv, "hnpsiPx:m:cV"))) {
while (-1 != (argch = getopt(argc, argv, "hnfpsiPx:m:cV"))) {
switch (argch) {
case 'x':
if (!set_debug_flags(optarg))
usage();
break;
case 'n':
case 'f':
NoFork = 1;
break;
case 'p':

View File

@ -25,6 +25,8 @@
#define MAIN_PROGRAM
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include <pwd.h>
@ -81,7 +83,7 @@ const char *flagname[]= {
};
void printflags(char *indent, int flags) {
int f;
size_t f;
int first = 1;
printf("%s flagnames:", indent);
@ -197,11 +199,11 @@ time_t nextmatch(entry *e, time_t start, time_t end) {
/*
* match a user against a list
*/
int matchuser(char *user, char *list) {
int matchuser(char *user_name, char *list) {
char *pos;
size_t l = strlen(user);
size_t l = strlen(user_name);
for (pos = list; (pos = strstr(pos, user)) != NULL; pos += l) {
for (pos = list; (pos = strstr(pos, user_name)) != NULL; pos += l) {
if ((pos != list) && (*(pos - 1) != ','))
continue;
if ((pos[l] != '\0') && (pos[l] != ','))
@ -216,7 +218,7 @@ int matchuser(char *user, char *list) {
*/
time_t cronnext(cron_db database,
time_t start, time_t end,
char *include, char *exclude, int flags) {
char *include, char *exclude, char *command, int flags) {
time_t closest, next;
user *u;
entry *e;
@ -242,7 +244,9 @@ time_t cronnext(cron_db database,
if (flags & CRONTABS)
printcrontab(u);
for (e = u->crontab; e; e = e->next)
for (e = u->crontab; e; e = e->next) {
if (command && strstr(e->cmd, command) == NULL)
continue;
for (next = nextmatch(e, start, end);
next <= end;
next = nextmatch(e, next + 60, end)) {
@ -255,6 +259,7 @@ time_t cronnext(cron_db database,
if (! (flags & ALLJOBS))
break;
}
}
}
return closest;
@ -267,6 +272,7 @@ cron_db database(int installed, char **additional) {
cron_db db = {NULL, NULL, (time_t) 0};
struct passwd pw;
int fd;
struct stat ss;
user *u;
if (installed)
@ -278,6 +284,12 @@ cron_db database(int installed, char **additional) {
perror(*additional);
continue;
}
fstat(fd, &ss);
if (S_ISDIR(ss.st_mode)) {
fprintf(stderr, "%s is a directory - skipping\n", *additional);
close(fd);
continue;
}
memset(&pw, 0, sizeof(pw));
pw.pw_name = *additional;
pw.pw_passwd = "";
@ -305,6 +317,7 @@ void usage() {
fprintf(stderr, " -a examine installed crontabs even if files are given\n");
fprintf(stderr, " -t time start from this time (seconds since epoch)\n");
fprintf(stderr, " -q time end check at this time (seconds since epoch)\n");
fprintf(stderr, " -j cmd only check jobs that contain cmd as a substring\n");
fprintf(stderr, " -l print next jobs to be executed\n");
fprintf(stderr, " -c print next execution of each job\n");
fprintf(stderr, " -f print all jobs executed in the given interval\n");
@ -317,7 +330,7 @@ void usage() {
*/
int main(int argn, char *argv[]) {
int opt;
char *include, *exclude;
char *include, *exclude, *command;
int flags;
time_t start, next, end = 0;
int endtime, printjobs;
@ -326,12 +339,13 @@ int main(int argn, char *argv[]) {
include = NULL;
exclude = NULL;
command = NULL;
flags = SYSTEM;
endtime = 0;
printjobs = 0;
start = time(NULL) / 60 * 60;
while (-1 != (opt = getopt(argn, argv, "i:e:ast:q:lcfhV"))) {
while (-1 != (opt = getopt(argn, argv, "i:e:ast:q:j:lcfhV"))) {
switch (opt) {
case 'i':
include = optarg;
@ -352,6 +366,9 @@ int main(int argn, char *argv[]) {
end = atoi(optarg) / 60 * 60;
endtime = 1;
break;
case 'j':
command = optarg;
break;
case 'l':
printjobs = 1;
break;
@ -399,7 +416,7 @@ int main(int argn, char *argv[]) {
db = database(installed || argv[optind] == NULL, argv + optind);
/* find time of next scheduled command */
next = cronnext(db, start, end, include, exclude, flags);
next = cronnext(db, start, end, include, exclude, command, flags);
/* print time */
if (next == -1)
@ -410,7 +427,7 @@ int main(int argn, char *argv[]) {
/* print next jobs */
if (printjobs) {
printf("nextjobs:\n");
cronnext(db, next, next, include, exclude, (flags & SYSTEM) | ENTRIES);
cronnext(db, next, next, include, exclude, command, (flags & SYSTEM) | ENTRIES);
}
return EXIT_SUCCESS;

View File

@ -66,21 +66,30 @@
#define NHEADER_LINES 0
enum opt_t {opt_unknown, opt_list, opt_delete, opt_edit, opt_replace, opt_hostset, opt_hostget};
#define COMMENT_COLOR "\x1B[34;1m"
#define ERROR_COLOR "\x1B[31;1m"
#define RESET_COLOR "\x1B[0m"
enum opt_t {
opt_unknown, opt_list, opt_delete, opt_edit, opt_replace, opt_hostset,
opt_hostget, opt_test
};
#if DEBUGGING
static const char *Options[] = {"???", "list", "delete", "edit", "replace", "hostset", "hostget"};
static const char *Options[] = {
"???", "list", "delete", "edit", "replace", "hostset", "hostget", "test"
};
# ifdef WITH_SELINUX
static const char *getoptargs = "u:lerisncx:V";
static const char *getoptargs = "u:lerisncx:VT";
# else
static const char *getoptargs = "u:lerincx:V";
static const char *getoptargs = "u:lerincx:VT";
# endif
#else
# ifdef WITH_SELINUX
static const char *getoptargs = "u:lerisncV";
static const char *getoptargs = "u:lerisncVT";
# else
static const char *getoptargs = "u:lerincV";
static const char *getoptargs = "u:lerincVT";
# endif
#endif
#ifdef WITH_SELINUX
@ -101,9 +110,12 @@ static void list_cmd(void),
delete_cmd(void),
edit_cmd(void),
poke_daemon(void),
check_error(const char *), parse_args(int c, char *v[]), die(int) ATTRIBUTE_NORETURN;
static int replace_cmd(void), hostset_cmd(void), hostget_cmd(void);
static char *host_specific_filename(const char *prefix, const char *suffix);
check_error(const char *), parse_args(int c, char *v[]),
die(int) ATTRIBUTE_NORETURN;
static int replace_cmd(void), hostset_cmd(void), hostget_cmd(void),
test_cmd(void), check_syntax(FILE *);
static char *host_specific_filename(const char *prefix,
const char *suffix);
static const char *tmp_path(void);
static void usage(const char *msg) ATTRIBUTE_NORETURN;
@ -122,6 +134,7 @@ static void usage(const char *msg) {
fprintf(stderr, " -i prompt before deleting\n");
fprintf(stderr, " -n <host> set host in cluster to run users' crontabs\n");
fprintf(stderr, " -c get host in cluster to run users' crontabs\n");
fprintf(stderr, " -T <file> test a crontab file syntax\n");
#ifdef WITH_SELINUX
fprintf(stderr, " -s selinux context\n");
#endif
@ -136,7 +149,7 @@ static void usage(const char *msg) {
int main(int argc, char *argv[]) {
int exitstatus;
if ((ProgramName=strrchr(argv[0], '/')) == NULL) {
if ((ProgramName = strrchr(argv[0], '/')) == NULL) {
ProgramName = argv[0];
}
else {
@ -198,6 +211,10 @@ int main(int argc, char *argv[]) {
if (hostget_cmd() < 0)
exitstatus = ERROR_EXIT;
break;
case opt_test:
if (test_cmd() < 0)
exitstatus = ERROR_EXIT;
break;
default:
abort();
}
@ -246,9 +263,9 @@ static void parse_args(int argc, char *argv[]) {
exit(ERROR_EXIT);
}
#endif
if (Option == opt_hostset || Option == opt_hostget) {
fprintf(stderr,
"cannot use -u with -n or -c\n");
if (Option == opt_hostset || Option == opt_hostget ||
Option == opt_test) {
fprintf(stderr, "cannot use -u with -n, -c or -T\n");
exit(ERROR_EXIT);
}
@ -276,6 +293,11 @@ static void parse_args(int argc, char *argv[]) {
usage("only one operation permitted");
Option = opt_edit;
break;
case 'T':
if (Option != opt_unknown)
usage("only one operation permitted");
Option = opt_test;
break;
case 'i':
PromptOnDelete = 1;
break;
@ -289,15 +311,13 @@ static void parse_args(int argc, char *argv[]) {
#endif
case 'n':
if (MY_UID(pw) != ROOT_UID) {
fprintf(stderr,
"must be privileged to set host with -n\n");
fprintf(stderr, "must be privileged to set host with -n\n");
exit(ERROR_EXIT);
}
if (Option != opt_unknown)
usage("only one operation permitted");
if (strcmp(User, RealUser) != 0) {
fprintf(stderr,
"cannot use -u with -n or -c\n");
fprintf(stderr, "cannot use -u with -n or -c\n");
exit(ERROR_EXIT);
}
Option = opt_hostset;
@ -306,8 +326,7 @@ static void parse_args(int argc, char *argv[]) {
if (Option != opt_unknown)
usage("only one operation permitted");
if (strcmp(User, RealUser) != 0) {
fprintf(stderr,
"cannot use -u with -n or -c\n");
fprintf(stderr, "cannot use -u with -n or -c\n");
exit(ERROR_EXIT);
}
Option = opt_hostget;
@ -330,22 +349,31 @@ static void parse_args(int argc, char *argv[]) {
optind++;
}
if (Option != opt_unknown) {
if (argv[optind] != NULL)
usage("no arguments permitted after this option");
if (Option == opt_unknown) {
/* replace is the default option */
Option = opt_replace;
}
else {
if (Option == opt_replace || Option == opt_test) {
if (argv[optind] != NULL) {
Option = opt_replace;
if (strlen(argv[optind]) >= sizeof Filename)
usage("filename too long");
(void) strcpy(Filename, argv[optind]);
optind++;
}
else if (isatty(STDIN_FILENO)) {
usage("file name or - (for stdin) must be specified");
}
else {
strcpy(Filename, "-");
}
else
usage("file name or - (for stdin) must be specified for replace");
}
if (Option == opt_replace) {
if (Option != opt_unknown && argv[optind] != NULL) {
usage("no arguments permitted after this option");
}
if (Filename[0] != '\0') {
if (!strcmp(Filename, "-"))
NewCrontab = stdin;
else {
@ -372,8 +400,7 @@ static void parse_args(int argc, char *argv[]) {
}
if ((sb.st_mode & S_IFMT) == S_IFDIR) {
fprintf(stderr,
"cannot replace crontab with a directory: %s\n",
Filename);
"invalid crontab file: '%s' is a directory\n", Filename);
fclose(NewCrontab);
exit(ERROR_EXIT);
}
@ -392,6 +419,9 @@ static void list_cmd(void) {
char n[MAX_FNAME];
FILE *f;
int ch;
const int colorize = isatty(STDOUT) && getenv("NO_COLOR") == NULL;
int new_line = 1;
int in_comment = 0;
log_it(RealUser, Pid, "LIST", User, 0);
if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) {
@ -408,9 +438,28 @@ static void list_cmd(void) {
/* file is open. copy to stdout, close.
*/
Set_LineNum(1)
while (EOF != (ch = get_char(f)))
Set_LineNum(1);
while (EOF != (ch = get_char(f))) {
if (colorize) {
if (!in_comment && new_line && ch == '#') {
in_comment = 1;
fputs(COMMENT_COLOR, stdout);
}
if (in_comment && ch == '\n') {
in_comment = 0;
fputs(RESET_COLOR, stdout);
}
}
putchar(ch);
new_line = ch == '\n';
}
/* no new line at EOF */
if (colorize && !new_line) {
putchar('\n');
fputs(ERROR_COLOR "No end-of-line character at the end of file"
RESET_COLOR, stdout);
putchar('\n');
}
fclose(f);
}
@ -419,7 +468,7 @@ static void delete_cmd(void) {
if (PromptOnDelete == 1) {
printf("crontab: really delete %s's crontab? ", User);
fflush(stdout);
if ((fgets(n, MAX_FNAME - 1, stdin) == 0L)
if ((fgets(n, MAX_FNAME - 1, stdin) == NULL)
|| ((n[0] != 'Y') && (n[0] != 'y'))
)
exit(0);
@ -454,8 +503,7 @@ static const char *tmp_path(void) {
return tmpdir ? tmpdir : "/tmp";
}
static char *host_specific_filename(const char *prefix, const char *suffix)
{
static char *host_specific_filename(const char *prefix, const char *suffix) {
/*
* For cluster-wide use, where there is otherwise risk of the same
* name being generated on more than one host at once, insert hostname
@ -536,14 +584,14 @@ static void edit_cmd(void) {
goto fatal;
}
Set_LineNum(1)
/*
* NHEADER_LINES processing removed for clarity
* (NHEADER_LINES == 0 in all Red Hat crontabs)
*/
/* copy the rest of the crontab (if any) to the temp file.
*/
if (EOF != ch)
Set_LineNum(1);
/*
* NHEADER_LINES processing removed for clarity
* (NHEADER_LINES == 0 in all Red Hat crontabs)
*/
/* copy the rest of the crontab (if any) to the temp file.
*/
if (EOF != ch)
while (EOF != (ch = get_char(f)))
putc(ch, NewCrontab);
@ -700,7 +748,7 @@ static void edit_cmd(void) {
perror("swapping uids back");
exit(ERROR_EXIT);
}
if (NewCrontab == 0L) {
if (NewCrontab == NULL) {
perror("fopen");
goto fatal;
}
@ -709,10 +757,10 @@ static void edit_cmd(void) {
break;
case -1:
for (;;) {
printf("Do you want to retry the same edit? ");
printf("Do you want to retry the same edit? (Y/N) ");
fflush(stdout);
q[0] = '\0';
if (fgets(q, sizeof q, stdin) == 0L)
if (fgets(q, sizeof q, stdin) == NULL)
continue;
switch (q[0]) {
case 'y':
@ -740,21 +788,31 @@ static void edit_cmd(void) {
log_it(RealUser, Pid, "END EDIT", User, 0);
}
/*
* Check if crontab file can be installed or not
*/
static int test_cmd(void) {
if (check_syntax(NewCrontab) < 0) {
fprintf(stderr, "Invalid crontab file. Syntax issues were found.\n");
return (-2);
}
else {
fprintf(stderr, "No syntax issues were found in the crontab file.\n");
}
return (0);
}
/* returns 0 on success
* -1 on syntax error
* -2 on install error
*/
static int replace_cmd(void) {
char n[MAX_FNAME], envstr[MAX_ENVSTR];
char n[MAX_FNAME];
FILE *tmp;
int ch, eof, fd;
int ch, fd;
int error = 0;
entry *e;
uid_t file_owner;
char **envp;
char *safename;
int envs = 0, entries = 0;
safename = host_specific_filename("#tmp", "XXXXXXXXXX");
if (!safename || !glue_strings(TempFilename, sizeof TempFilename, SPOOL_DIR,
@ -793,8 +851,8 @@ static int replace_cmd(void) {
/* copy the crontab to the tmp
*/
rewind(NewCrontab);
Set_LineNum(1)
while (EOF != (ch = get_char(NewCrontab)))
Set_LineNum(1);
while (EOF != (ch = get_char(NewCrontab)))
putc(ch, tmp);
if (ftruncate(fileno(tmp), ftell(tmp)) == -1) {
fprintf(stderr, "%s: error while writing new crontab to %s\n",
@ -803,84 +861,23 @@ static int replace_cmd(void) {
error = -2;
goto done;
}
fflush(tmp);
rewind(tmp);
if (ferror(tmp)) {
if (ferror(tmp) || fflush(tmp) || fsync(fileno(tmp))) {
fprintf(stderr, "%s: error while writing new crontab to %s\n",
ProgramName, TempFilename);
fclose(tmp);
error = -2;
goto done;
}
rewind(tmp);
/* check the syntax of the file being installed.
*/
/* BUG: was reporting errors after the EOF if there were any errors
* in the file proper -- kludged it by stopping after first error.
* vix 31mar87
*/
Set_LineNum(1 - NHEADER_LINES)
CheckErrorCount = 0;
eof = FALSE;
envp = env_init();
if (envp == NULL) {
fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName);
if ((error = check_syntax(tmp)) < 0) {
fprintf(stderr, "Invalid crontab file, can't install.\n");
fclose(tmp);
error = -2;
goto done;
}
while (!CheckErrorCount && !eof) {
if (!skip_comments(tmp)) {
check_error("too many garbage characters");
break;
}
switch (load_env(envstr, tmp)) {
case ERR:
/* check for data before the EOF */
if (envstr[0] != '\0') {
Set_LineNum(LineNumber + 1);
check_error("premature EOF");
}
eof = TRUE;
break;
case FALSE:
e = load_entry(tmp, check_error, pw, envp);
if (e) {
++entries;
free_entry(e);
}
break;
case TRUE:
++envs;
break;
}
}
env_free(envp);
if (envs > MAX_USER_ENVS) {
fprintf(stderr, "More than %d environment variables in crontab file, can't install.\n", MAX_USER_ENVS);
fclose(tmp);
error = -1;
goto done;
}
if (entries > MAX_USER_ENTRIES) {
fprintf(stderr, "More than %d entries in crontab file, can't install.\n", MAX_USER_ENTRIES);
fclose(tmp);
error = -1;
goto done;
}
if (CheckErrorCount != 0) {
fprintf(stderr, "errors in crontab file, can't install.\n");
fclose(tmp);
error = -1;
goto done;
}
file_owner = (getgid() == geteuid() && getgid() == getegid()) ? ROOT_UID : pw->pw_uid;
file_owner = (getgid() == geteuid() &&
getgid() == getegid()) ? ROOT_UID : pw->pw_uid;
#ifdef HAVE_FCHOWN
if (fchown(fileno(tmp), file_owner, (gid_t)-1) < OK) {
@ -932,16 +929,90 @@ static int replace_cmd(void) {
return (error);
}
/*
* Check the syntax of a crontab file
* Returns:
* 0 no syntax issues
* -1 syntax issue (can be fixed by user)
* -2 any other error, which can not be fixed by user
*/
static int check_syntax(FILE * crontab_file) {
char **envp = env_init();
int eof = FALSE;
int envs = 0, entries = 0;
CheckErrorCount = 0;
Set_LineNum(1 - NHEADER_LINES);
if (envp == NULL) {
fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName);
return (-2);
}
while (!CheckErrorCount && !eof) {
char envstr[MAX_ENVSTR];
entry *e;
if (!skip_comments(crontab_file)) {
check_error
("too much non-parseable content (comments, empty lines, spaces)");
break;
}
switch (load_env(envstr, crontab_file)) {
case ERR:
/* check for data before the EOF */
if (envstr[0] != '\0') {
Set_LineNum(LineNumber + 1);
check_error("premature EOF");
}
eof = TRUE;
break;
case FALSE:
e = load_entry(crontab_file, check_error, pw, envp);
if (e) {
++entries;
free_entry(e);
}
break;
case TRUE:
++envs;
break;
}
}
env_free(envp);
if (envs > MAX_USER_ENVS) {
fprintf(stderr,
"There are too many environment variables in the crontab file. Limit: %d\n",
MAX_USER_ENVS);
return (-1);
}
if (entries > MAX_USER_ENTRIES) {
fprintf(stderr,
"There are too many entries in the crontab file. Limit: %d\n",
MAX_USER_ENTRIES);
return (-1);
}
if (CheckErrorCount != 0) {
return (-1);
}
return 0;
}
static int hostset_cmd(void) {
char n[MAX_FNAME];
FILE *tmp;
int fd;
int error = 0;
char *safename;
if (!HostSpecified)
gethostname(Host, sizeof Host);
safename = host_specific_filename("#tmp", "XXXXXXXXXX");
if (!safename || !glue_strings(TempFilename, sizeof TempFilename, SPOOL_DIR,
safename, '/')) {
@ -963,7 +1034,7 @@ static int hostset_cmd(void) {
(void) signal(SIGINT, die);
(void) signal(SIGQUIT, die);
(void) fchmod(fd, 0600); /* not all mkstemp() implementations do this */
(void) fchmod(fd, 0600); /* not all mkstemp() implementations do this */
if (fprintf(tmp, "%s\n", Host) < 0 || fclose(tmp) == EOF) {
fprintf(stderr, "%s: error while writing to %s\n",
@ -1041,7 +1112,7 @@ static void poke_daemon(void) {
}
}
static void die(int x) {
static void die(int x ATTRIBUTE_UNUSED) {
if (TempFilename[0])
(void) unlink(TempFilename);
_exit(ERROR_EXIT);

View File

@ -48,9 +48,6 @@
#include "globals.h"
#include "pathnames.h"
#define TMAX(a,b) ((a)>(b)?(a):(b))
#define TMIN(a,b) ((a)<(b)?(a):(b))
/* size of the event structure, not counting name */
#define EVENT_SIZE (sizeof (struct inotify_event))
@ -472,10 +469,6 @@ int load_database(cron_db * old_db) {
statbuf.st_mtime = 0;
}
else {
/* As pointed out in Red Hat bugzilla 198019, with modern Linux it
* is possible to modify a file without modifying the mtime of the
* containing directory. Hence, we must check the mtime of each file:
*/
max_mtime(SPOOL_DIR, &statbuf);
}
@ -497,16 +490,16 @@ int load_database(cron_db * old_db) {
/* if spooldir's mtime has not changed, we don't need to fiddle with
* the database.
*
* Note that old_db->mtime is initialized to 0 in main(), and
* so is guaranteed to be different than the stat() mtime the first
* time this function is called.
* Note that old_db->mtime is initialized to 0 in main().
*
* We also use now - 1 as the upper bound of timestamp to avoid race,
* when a crontab is updated twice in a single second when we are
* just reading it.
*/
if (old_db->mtime == TMIN(now - 1, TMAX(crond_stat.st_mtime,
TMAX(statbuf.st_mtime, syscron_stat.st_mtime)))
if (old_db->mtime != 0
&& old_db->mtime == TMIN(now - 1,
TMAX(crond_stat.st_mtime,
TMAX(statbuf.st_mtime, syscron_stat.st_mtime)))
) {
Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n",
(long) pid));
@ -566,7 +559,8 @@ int load_database(cron_db * old_db) {
if (not_a_crontab(dp))
continue;
strncpy(fname, dp->d_name, NAME_MAX + 1);
strncpy(fname, dp->d_name, NAME_MAX);
fname[NAME_MAX] = '\0';
if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR, fname, '/'))
continue; /* XXX log? */

View File

@ -35,6 +35,7 @@
#include "funcs.h"
#include "globals.h"
#include "structs.h"
#include "cronie_common.h"
#ifndef isascii
# define isascii(c) ((unsigned)(c)<=0177)
@ -46,7 +47,7 @@ static int safe_p(const char *, const char *);
void do_command(entry * e, user * u) {
pid_t pid = getpid();
int ev;
char **jobenv = 0L;
char **jobenv = NULL;
Debug(DPROC, ("[%ld] do_command(%s, (%s,%ld,%ld))\n",
(long) pid, e->cmd, u->name,
@ -89,6 +90,8 @@ void do_command(entry * e, user * u) {
static int child_process(entry * e, char **jobenv) {
int stdin_pipe[2], stdout_pipe[2];
char *input_data, *usernm, *mailto, *mailfrom;
char mailto_expanded[MAX_EMAILSTR];
char mailfrom_expanded[MAX_EMAILSTR];
int children = 0;
pid_t pid = getpid();
struct sigaction sa;
@ -126,6 +129,24 @@ static int child_process(entry * e, char **jobenv) {
usernm = e->pwd->pw_name;
mailto = env_get("MAILTO", jobenv);
mailfrom = env_get("MAILFROM", e->envp);
if (mailto != NULL) {
if (expand_envvar(mailto, mailto_expanded, sizeof(mailto_expanded))) {
mailto = mailto_expanded;
}
else {
log_it("CRON", pid, "WARNING", "The environment variable 'MAILTO' could not be expanded. The non-expanded value will be used." , 0);
}
}
if (mailfrom != NULL) {
if (expand_envvar(mailfrom, mailfrom_expanded, sizeof(mailfrom_expanded))) {
mailfrom = mailfrom_expanded;
}
else {
log_it("CRON", pid, "WARNING", "The environment variable 'MAILFROM' could not be expanded. The non-expanded value will be used." , 0);
}
}
/* create some pipes to talk to our future child
*/
@ -194,6 +215,9 @@ static int child_process(entry * e, char **jobenv) {
if ((e->flags & DONT_LOG) == 0) {
char *x = mkprints((u_char *) e->cmd, strlen(e->cmd));
if (x == NULL) /* out of memory, better exit */
_exit(ERROR_EXIT);
log_it(usernm, getpid(), "CMD", x, 0);
free(x);
}
@ -238,7 +262,7 @@ static int child_process(entry * e, char **jobenv) {
*/
{
char *shell = env_get("SHELL", jobenv);
int fd, fdmax = getdtablesize();
int fd, fdmax = TMIN(getdtablesize(), MAX_CLOSE_FD);
/* close all unwanted open file descriptors */
for(fd = STDERR + 1; fd < fdmax; fd++) {
@ -427,8 +451,14 @@ static int child_process(entry * e, char **jobenv) {
gethostname(hostname, MAXHOSTNAMELEN);
if (MailCmd[0] == '\0') {
if (snprintf(mailcmd, sizeof mailcmd, MAILFMT, MAILARG, mailfrom)
>= sizeof mailcmd) {
int len;
len = snprintf(mailcmd, sizeof mailcmd, MAILFMT, MAILARG, mailfrom);
if (len < 0) {
fprintf(stderr, "mailcmd snprintf failed\n");
(void) _exit(ERROR_EXIT);
}
if (sizeof mailcmd <= (size_t) len) {
fprintf(stderr, "mailcmd too long\n");
(void) _exit(ERROR_EXIT);
}
@ -450,7 +480,7 @@ static int child_process(entry * e, char **jobenv) {
fprintf(mail, "Date: %s\n", arpadate(&StartTime));
#endif /*MAIL_DATE */
fprintf(mail, "MIME-Version: 1.0\n");
if (content_type == 0L) {
if (content_type == NULL) {
fprintf(mail, "Content-Type: text/plain; charset=%s\n",
cron_default_mail_charset);
}
@ -461,17 +491,20 @@ static int child_process(entry * e, char **jobenv) {
char *nl = content_type;
size_t ctlen = strlen(content_type);
while ((*nl != '\0')
&& ((nl = strchr(nl, '\n')) != 0L)
&& ((nl = strchr(nl, '\n')) != NULL)
&& (nl < (content_type + ctlen))
)
*nl = ' ';
fprintf(mail, "Content-Type: %s\n", content_type);
}
if (content_transfer_encoding != 0L) {
if (content_transfer_encoding == NULL) {
fprintf(mail, "Content-Transfer-Encoding: 8bit\n");
}
else {
char *nl = content_transfer_encoding;
size_t ctlen = strlen(content_transfer_encoding);
while ((*nl != '\0')
&& ((nl = strchr(nl, '\n')) != 0L)
&& ((nl = strchr(nl, '\n')) != NULL)
&& (nl < (content_transfer_encoding + ctlen))
)
*nl = ' ';
@ -500,6 +533,8 @@ static int child_process(entry * e, char **jobenv) {
*/
while (EOF != (ch = getc(in))) {
if (ch == '\r')
continue;
bytes++;
if (mail)
putc(ch, mail);
@ -581,6 +616,12 @@ static int child_process(entry * e, char **jobenv) {
Debug(DPROC, (", dumped core"));
Debug(DPROC, ("\n"));
}
if ((e->flags & DONT_LOG) == 0) {
char *x = mkprints((u_char *) e->cmd, strlen(e->cmd));
log_it(usernm, getpid(), "CMDEND", x ? x : "**Unknown command**" , 0);
free(x);
}
return OK_EXIT;
}

View File

@ -62,9 +62,22 @@ static const char *ecodes[] = {
"out of memory"
};
typedef enum {
R_START,
R_AST,
R_STEP,
R_TERMS,
R_NUM1,
R_RANGE,
R_RANGE_NUM2,
R_RANDOM,
R_RANDOM_NUM2,
R_FINISH,
} range_state_t;
static int get_list(bitstr_t *, int, int, const char *[], int, FILE *),
get_range(bitstr_t *, int, int, const char *[], int, FILE *),
get_number(int *, int, const char *[], int, FILE *, const char *),
get_range(bitstr_t *, int, int, const char *[], FILE *),
get_number(int *, int, const char *[], FILE *),
set_element(bitstr_t *, int, int, int);
void free_entry(entry * e) {
@ -179,7 +192,7 @@ entry *load_entry(FILE * file, void (*error_func) (), struct passwd *pw,
bit_nset(e->dom, 0, LAST_DOM - FIRST_DOM);
bit_nset(e->month, 0, LAST_MONTH - FIRST_MONTH);
bit_set(e->dow, 0);
e->flags |= DOW_STAR;
e->flags |= DOM_STAR;
}
else if (!strcmp("daily", cmd) || !strcmp("midnight", cmd)) {
bit_set(e->minute, 0);
@ -301,6 +314,17 @@ entry *load_entry(FILE * file, void (*error_func) (), struct passwd *pw,
Debug(DPARS, ("load_entry()...uid %ld, gid %ld\n",
(long) pw->pw_uid, (long) pw->pw_gid));
}
/* Advance past whitespace before command. */
Skip_Blanks(ch, file);
/* check for permature EOL or EOF */
if (ch == EOF || ch == '\n') {
ecode = e_cmd;
goto eof;
}
/* ch is the first character of a command */
unget_char(ch, file);
}
if ((e->pwd = pw_dup(pw)) == NULL) {
@ -456,11 +480,14 @@ get_list(bitstr_t * bits, int low, int high, const char *names[],
/* process all ranges
*/
done = FALSE;
/* unget ch to allow get_range() to process it properly
*/
unget_char(ch, file);
while (!done) {
if (EOF == (ch = get_range(bits, low, high, names, ch, file)))
if (EOF == (ch = get_range(bits, low, high, names, file)))
return (EOF);
if (ch == ',')
ch = get_char(file);
continue;
else
done = TRUE;
}
@ -475,137 +502,197 @@ get_list(bitstr_t * bits, int low, int high, const char *names[],
return (ch);
}
inline static int is_separator(int ch) {
switch (ch) {
case '\t':
case '\n':
case ' ':
case ',':
return 1;
default:
return 0;
}
}
static int
get_range(bitstr_t * bits, int low, int high, const char *names[],
int ch, FILE * file) {
FILE * file) {
/* range = number | number "-" number [ "/" number ]
* | [number] "~" [number]
*/
int ch, i, num1, num2, num3;
int i, num1, num2, num3;
/* default value for step
*/
num3 = 1;
range_state_t state = R_START;
Debug(DPARS | DEXT, ("get_range()...entering, exit won't show\n"));
if (ch == '*') {
/* '*' means "first-last" but can still be modified by /step
*/
num1 = low;
num2 = high;
ch = get_char(file);
if (ch == EOF)
return (EOF);
}
else {
ch = get_number(&num1, low, names, ch, file, ",- \t\n");
if (ch == EOF)
return (EOF);
if (ch != '-') {
/* not a range, it's a single number.
*/
if (EOF == set_element(bits, low, high, num1)) {
while (state != R_FINISH && ((ch = get_char(file)) != EOF)) {
switch (state) {
case R_START:
if (ch == '*') {
num1 = low;
num2 = high;
state = R_AST;
break;
}
if (ch == '~') {
num1 = low;
state = R_RANDOM;
break;
}
unget_char(ch, file);
return (EOF);
}
return (ch);
}
else {
/* eat the dash
*/
ch = get_char(file);
if (ch == EOF)
if (get_number(&num1, low, names, file) != EOF) {
state = R_NUM1;
break;
}
return (EOF);
/* get the number following the dash
*/
ch = get_number(&num2, low, names, ch, file, "/, \t\n");
if (ch == EOF || num1 > num2)
case R_AST:
if (ch == '/') {
state = R_STEP;
break;
}
if (is_separator(ch)) {
state = R_FINISH;
break;
}
return (EOF);
case R_STEP:
unget_char(ch, file);
if (get_number(&num3, 0, PPC_NULL, file) != EOF
&& num3 != 0) {
state = R_TERMS;
break;
}
return (EOF);
case R_TERMS:
if (is_separator(ch)) {
state = R_FINISH;
break;
}
return (EOF);
case R_NUM1:
if (ch == '-') {
state = R_RANGE;
break;
}
if (ch == '~') {
state = R_RANDOM;
break;
}
if (is_separator(ch)) {
num2 = num1;
state = R_FINISH;
break;
}
return (EOF);
case R_RANGE:
unget_char(ch, file);
if (get_number(&num2, low, names, file) != EOF) {
state = R_RANGE_NUM2;
break;
}
return (EOF);
case R_RANGE_NUM2:
if (ch == '/') {
state = R_STEP;
break;
}
if (is_separator(ch)) {
state = R_FINISH;
break;
}
return (EOF);
case R_RANDOM:
if (is_separator(ch)) {
num2 = high;
state = R_FINISH;
}
else if (unget_char(ch, file),
get_number(&num2, low, names, file) != EOF) {
state = R_TERMS;
}
/* fail if couldn't find match on previous term
*/
else
return (EOF);
/* if invalid random range was selected */
if (num1 > num2)
return (EOF);
/* select random number in range <num1, num2>
*/
num1 = num2 = random() % (num2 - num1 + 1) + num1;
break;
default:
/* We should never get here
*/
return (EOF);
}
}
if (state != R_FINISH || ch == EOF)
return (EOF);
/* check for step size
*/
if (ch == '/') {
/* eat the slash
*/
ch = get_char(file);
if (ch == EOF)
return (EOF);
/* get the step size -- note: we don't pass the
* names here, because the number is not an
* element id, it's a step size. 'low' is
* sent as a 0 since there is no offset either.
*/
ch = get_number(&num3, 0, PPC_NULL, ch, file, ", \t\n");
if (ch == EOF || num3 == 0)
return (EOF);
}
else {
/* no step. default==1.
*/
num3 = 1;
}
/* range. set all elements from num1 to num2, stepping
* by num3. (the step is a downward-compatible extension
* proposed conceptually by bob@acornrc, syntactically
* designed then implemented by paul vixie).
*/
for (i = num1; i <= num2; i += num3)
if (EOF == set_element(bits, low, high, i)) {
unget_char(ch, file);
return (EOF);
}
return (ch);
return ch;
}
static int
get_number(int *numptr, int low, const char *names[], int ch, FILE * file,
const char *terms) {
get_number(int *numptr, int low, const char *names[], FILE * file) {
char temp[MAX_TEMPSTR], *pc;
int len, i;
int len, i, ch;
char *endptr;
pc = temp;
len = 0;
/* first look for a number */
while (isdigit((unsigned char) ch)) {
/* get all alnum characters available */
while (isalnum((ch = get_char(file)))) {
if (++len >= MAX_TEMPSTR)
goto bad;
*pc++ = (char)ch;
ch = get_char(file);
}
*pc = '\0';
if (len != 0) {
/* got a number, check for valid terminator */
if (!strchr(terms, ch))
goto bad;
*numptr = atoi(temp);
return (ch);
if (len == 0)
goto bad;
unget_char(ch, file);
/* try to get number */
*numptr = (int) strtol(temp, &endptr, 10);
if (*endptr == '\0' && temp != endptr) {
/* We have a number */
return 0;
}
/* no numbers, look for a string if we have any */
if (names) {
while (isalpha((unsigned char) ch)) {
if (++len >= MAX_TEMPSTR)
goto bad;
*pc++ = (char)ch;
ch = get_char(file);
}
*pc = '\0';
if (len != 0 && strchr(terms, ch)) {
for (i = 0; names[i] != NULL; i++) {
Debug(DPARS | DEXT,
("get_num, compare(%s,%s)\n", names[i], temp));
if (!strcasecmp(names[i], temp)) {
*numptr = i + low;
return (ch);
}
for (i = 0; names[i] != NULL; i++) {
Debug(DPARS | DEXT, ("get_num, compare(%s,%s)\n", names[i], temp));
if (strcasecmp(names[i], temp) == 0) {
*numptr = i + low;
return 0;
}
}
} else {
goto bad;
}
bad:
@ -616,7 +703,7 @@ get_number(int *numptr, int low, const char *names[], int ch, FILE * file,
static int set_element(bitstr_t * bits, int low, int high, int number) {
Debug(DPARS | DEXT, ("set_element(?,%d,%d,%d)\n", low, high, number));
if (number < low || number > high)
if (number < low || number > high)
return (EOF);
bit_set(bits, (number - low));

View File

@ -23,6 +23,7 @@
#include <ctype.h>
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@ -190,7 +191,7 @@ int load_env(char *envstr, FILE * f) {
Debug(DPARS, ("load_env, read <%s>\n", envstr));
str = envstr;
val = str = envstr;
state = NAMEI;
quotechar = '\0';
c = envstr;
@ -281,7 +282,7 @@ char *env_get(const char *name, char **envp) {
while ((p = *envp++) != NULL) {
if (!(q = strchr(p, '=')))
continue;
if ((q - p) == len && !strncmp(p, name, len))
if ((size_t)(q - p) == len && !strncmp(p, name, len))
return (q + 1);
}
return (NULL);

View File

@ -72,8 +72,8 @@ void job_add(entry * e, user * u) {
e->envp = tenvp;
} else {
log_it(uname, getpid(), "ERROR", "getpwnam() failed - user unknown",errno);
Debug(DSCH | DEXT, ("%s:%d pid=%d time=%ld getpwnam(%s) failed errno=%d error=%s\n",
__FILE__,__LINE__,getpid(),time(NULL),uname,errno,strerror(errno)));
Debug(DSCH | DEXT, ("%s:%d pid=%d time=%lld getpwnam(%s) failed errno=%d error=%s\n",
__FILE__,__LINE__,getpid(),(long long)time(NULL),uname,errno,strerror(errno)));
return;
}

View File

@ -59,8 +59,9 @@
#define ROOT_UID 0 /* don't change this, it really must be root */
#define ROOT_USER "root" /* ditto */
#define MAX_USER_ENVS 1000 /* maximum environment variables in user's crontab */
#define MAX_USER_ENTRIES 1000 /* maximum crontab entries in user's crontab */
#define MAX_USER_ENTRIES 10000 /* maximum crontab entries in user's crontab */
#define MAX_GARBAGE 32768 /* max num of chars of comments and whitespaces between entries */
#define MAX_CLOSE_FD 10000 /* max fd num to close when spawning a child process */
/* NOTE: these correspond to DebugFlagNames,
* defined below.
@ -129,6 +130,9 @@
#define LAST_DOW 7
#define DOW_COUNT (LAST_DOW - FIRST_DOW + 1)
#define TMAX(a,b) ((a)>(b)?(a):(b))
#define TMIN(a,b) ((a)<(b)?(a):(b))
/*
* Because crontab/at files may be owned by their respective users we
* take extreme care in opening them. If the OS lacks the O_NOFOLLOW

View File

@ -315,9 +315,6 @@ void acquire_daemonlock(int closeflag) {
return;
}
if (NoFork == 1)
return; //move along, nothing to do here...
if (fd == -1) {
pidfile = _PATH_CRON_PID;
/* Initial mode is 0600 to prevent flock() race/DoS. */
@ -460,76 +457,6 @@ int skip_comments(FILE * file) {
return TRUE;
}
/* int in_file(const char *string, FILE *file, int error)
* return TRUE if one of the lines in file matches string exactly,
* FALSE if no lines match, and error on error.
*/
static int in_file(const char *string, FILE * file, int error) {
char line[MAX_TEMPSTR];
char *endp;
if (fseek(file, 0L, SEEK_SET))
return (error);
while (fgets(line, MAX_TEMPSTR, file)) {
if (line[0] != '\0') {
endp = &line[strlen(line) - 1];
if (*endp != '\n')
return (error);
*endp = '\0';
if (0 == strcmp(line, string))
return (TRUE);
}
}
if (ferror(file))
return (error);
return (FALSE);
}
/* int allowed(const char *username, const char *allow_file, const char *deny_file)
* returns TRUE if (allow_file exists and user is listed)
* or (deny_file exists and user is NOT listed).
* root is always allowed.
*/
int allowed(const char *username, const char *allow_file,
const char *deny_file) {
FILE *fp;
int isallowed;
char buf[128];
if (getuid() == 0)
return TRUE;
isallowed = FALSE;
if ((fp = fopen(allow_file, "r")) != NULL) {
isallowed = in_file(username, fp, FALSE);
fclose(fp);
if ((getuid() == 0) && (!isallowed)) {
snprintf(buf, sizeof (buf),
"root used -u for user %s not in cron.allow", username);
log_it("crontab", getpid(), "warning", buf, 0);
isallowed = TRUE;
}
}
else if ((fp = fopen(deny_file, "r")) != NULL) {
isallowed = !in_file(username, fp, FALSE);
fclose(fp);
if ((getuid() == 0) && (!isallowed)) {
snprintf(buf, sizeof (buf),
"root used -u for user %s in cron.deny", username);
log_it("crontab", getpid(), "warning", buf, 0);
isallowed = TRUE;
}
}
#ifdef WITH_AUDIT
if (isallowed == FALSE) {
int audit_fd = audit_open();
audit_log_user_message(audit_fd, AUDIT_USER_START, "cron deny",
NULL, NULL, NULL, 0);
close(audit_fd);
}
#endif
return (isallowed);
}
void log_it(const char *username, PID_T xpid, const char *event,
const char *detail, int err) {
#if defined(LOG_FILE) || DEBUGGING

View File

@ -36,10 +36,14 @@
* PIDDIR must end in '/'.
* (Don't ask why the default is "/etc/".)
*/
#ifdef _PATH_VARRUN
# define PIDDIR _PATH_VARRUN
#ifdef CRON_PID_DIR
# define PIDDIR CRON_PID_DIR "/"
#else
# define PIDDIR SYSCONFDIR "/"
# ifdef _PATH_VARRUN
# define PIDDIR _PATH_VARRUN
# else
# define PIDDIR SYSCONFDIR "/"
# endif
#endif
#define PIDFILE "crond.pid"
#define _PATH_CRON_PID PIDDIR PIDFILE

View File

@ -81,12 +81,19 @@ FILE *cron_popen(char *program, const char *type, struct passwd *pw, char **jobe
if (!pids) {
if ((fds = getdtablesize()) <= 0)
return (NULL);
if (fds > MAX_CLOSE_FD)
fds = MAX_CLOSE_FD; /* avoid allocating too much memory */
if (!(pids = (PID_T *) malloc((u_int) ((size_t)fds * sizeof (PID_T)))))
return (NULL);
memset((char *) pids, 0, (size_t)fds * sizeof (PID_T));
}
if (pipe(pdes) < 0)
return (NULL);
if (pdes[0] >= fds || pdes[1] >= fds) {
(void) close(pdes[0]);
(void) close(pdes[1]);
return NULL;
}
/* break up string into pieces */
for (argc = 0, cp = program; argc < MAX_ARGS; cp = NULL)
@ -145,14 +152,16 @@ FILE *cron_popen(char *program, const char *type, struct passwd *pw, char **jobe
}
/* parent; assume fdopen can't fail... */
if (*type == 'r') {
fd = pdes[0];
iop = fdopen(pdes[0], type);
(void) close(pdes[1]);
}
else {
fd = pdes[1];
iop = fdopen(pdes[1], type);
(void) close(pdes[0]);
}
pids[fileno(iop)] = pid;
pids[fd] = pid;
pfree:
return (iop);
@ -168,7 +177,8 @@ int cron_pclose(FILE * iop) {
* pclose returns -1 if stream is not associated with a
* `popened' command, or, if already `pclosed'.
*/
if (pids == 0 || pids[fdes = fileno(iop)] == 0)
fdes = fileno(iop);
if (pids == NULL || fdes >= fds || pids[fdes] == 0L)
return (-1);
(void) fclose(iop);

View File

@ -121,6 +121,7 @@ pw_dup(const struct passwd *pw) {
cp += ssize;
}
/* cppcheck-suppress[memleak symbolName=cp] memory originally pointed to by cp returned via newpw */
return (newpw);
}

View File

@ -120,8 +120,8 @@ int cron_set_job_security_context(entry *e, user *u ATTRIBUTE_UNUSED,
/* "minute-ly" job: Every minute for given hour/dow/month/dom.
* Ensure that these jobs never run in the same minute:
*/
minutely_time = time(0);
Debug(DSCH, ("Minute-ly job. Recording time %lu\n", minutely_time));
minutely_time = time(NULL);
Debug(DSCH, ("Minute-ly job. Recording time %lld\n", (long long)minutely_time));
}
#ifdef WITH_PAM
@ -169,7 +169,7 @@ int cron_set_job_security_context(entry *e, user *u ATTRIBUTE_UNUSED,
*jobenv = build_env(e->envp);
time_t job_run_time = time(0L);
time_t job_run_time = time(NULL);
if ((minutely_time > 0) && ((job_run_time / 60) != (minutely_time / 60))) {
/* if a per-minute job is delayed into the next minute
@ -350,12 +350,12 @@ cron_get_job_range(user * u, security_context_t * ucontextp, char **jobenv) {
if (is_selinux_enabled() <= 0)
return 0;
if (ucontextp == 0L)
if (ucontextp == NULL)
return -1;
*ucontextp = 0L;
*ucontextp = NULL;
if ((range = env_get("MLS_LEVEL", jobenv)) != 0L) {
if ((range = env_get("MLS_LEVEL", jobenv)) != NULL) {
context_t ccon;
if (!(ccon = context_new(u->scontext))) {
log_it(u->name, getpid(), "context_new FAILED for MLS_LEVEL",
@ -404,7 +404,7 @@ static int cron_change_selinux_range(user * u, security_context_t ucontext) {
if (is_selinux_enabled() <= 0)
return 0;
if (u->scontext == 0L) {
if (u->scontext == NULL) {
if (security_getenforce() > 0) {
log_it(u->name, getpid(), "NULL security context for user", "", 0);
return -1;
@ -592,7 +592,7 @@ get_security_context(const char *name, int crontab_fd,
void free_security_context(security_context_t * scontext) {
if (*scontext != NULL) {
freecon(*scontext);
*scontext = 0L;
*scontext = NULL;
}
}
#endif
@ -675,3 +675,74 @@ static char **build_env(char **cronenv) {
return jobenv;
#endif
}
/* int in_file(const char *string, FILE *file, int error)
* return TRUE if one of the lines in file matches string exactly,
* FALSE if no lines match, and error on error.
*/
static int in_file(const char *string, FILE * file, int error) {
char line[MAX_TEMPSTR];
char *endp;
if (fseek(file, 0L, SEEK_SET))
return (error);
while (fgets(line, MAX_TEMPSTR, file)) {
if (line[0] != '\0') {
endp = &line[strlen(line) - 1];
if (*endp != '\n')
return (error);
*endp = '\0';
if (0 == strcmp(line, string))
return (TRUE);
}
}
if (ferror(file))
return (error);
return (FALSE);
}
/* int allowed(const char *username, const char *allow_file, const char *deny_file)
* returns TRUE if (allow_file exists and user is listed)
* or (deny_file exists and user is NOT listed).
* root is always allowed.
*/
int allowed(const char *username, const char *allow_file,
const char *deny_file) {
FILE *fp;
int isallowed;
char buf[128];
if (getuid() == 0)
return TRUE;
isallowed = FALSE;
if ((fp = fopen(allow_file, "r")) != NULL) {
isallowed = in_file(username, fp, FALSE);
fclose(fp);
if ((getuid() == 0) && (!isallowed)) {
snprintf(buf, sizeof (buf),
"root used -u for user %s not in cron.allow", username);
log_it("crontab", getpid(), "warning", buf, 0);
isallowed = TRUE;
}
}
else if ((fp = fopen(deny_file, "r")) != NULL) {
isallowed = !in_file(username, fp, FALSE);
fclose(fp);
if ((getuid() == 0) && (!isallowed)) {
snprintf(buf, sizeof (buf),
"root used -u for user %s in cron.deny", username);
log_it("crontab", getpid(), "warning", buf, 0);
isallowed = TRUE;
}
}
#ifdef WITH_AUDIT
if (isallowed == FALSE) {
int audit_fd = audit_open();
audit_log_user_message(audit_fd, AUDIT_USER_START, "cron deny",
NULL, NULL, NULL, 0);
close(audit_fd);
}
#endif
return (isallowed);
}

View File

@ -124,6 +124,16 @@ load_user (int crontab_fd, struct passwd *pw, const char *uname,
}
status = load_env (envstr, file);
switch (status) {
case ERR:
/* If envstr has content, we reached EOF
* without a newline, and the line will be
* ignored.
*/
if (envstr[0] != '\0') {
FileName = tabname;
log_error("missing newline before EOF");
}
break;
case FALSE:
++entries;
if (!u->system && entries > MAX_USER_ENTRIES) {