mirror of https://gitee.com/openkylin/ucf.git
Import Upstream version 3.0038+nmu1
This commit is contained in:
commit
3a0feb4ad0
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,211 @@
|
|||
2008-02-21 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucfq (process):
|
||||
srivasta@debian.org--lenny/ucf--devel--3.0--patch-2 Niko
|
||||
Tyni says ucfq /path/to/file never gives any output. It
|
||||
looks like the problem is that ^/ is matched twice with
|
||||
the global option (m//g) on the filename in
|
||||
ucf::process(), so the second one fails looking for the
|
||||
next match. I don't see the need for global match here,
|
||||
and removing the /g fixesthis for me.
|
||||
(report): srivasta@debian.org--lenny/ucf--devel--3.0--patch-2
|
||||
Major changes to ensure that the modified column
|
||||
actually contains a valid value. This whole script needs
|
||||
a rewrite.
|
||||
|
||||
2007-11-30 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf (newsum):
|
||||
srivasta@debian.org--lenny/ucf--devel--3.0--patch-1 For
|
||||
"keep current" and "threeway merge", ucf expects answers
|
||||
from debconf which differ from what is specified in the
|
||||
template master. Frans Pop suggested using the Choices-C
|
||||
feature of debconf, which is relatively new, but defines
|
||||
a fixed alias for each option which Debconf will then
|
||||
use in db_get and db_set operations -- so no more
|
||||
matching the template in the code.
|
||||
|
||||
2007-09-19 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf (choice_keep_current):
|
||||
srivasta@debian.org--lenny/ucf--devel--3.0--base-0
|
||||
Change the name to fit the changed template
|
||||
|
||||
2007-05-05 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf (show_diff):
|
||||
srivasta@debian.org--lenny/ucf--devel--2.0--patch-1
|
||||
Users using a Graphical frontend are surprised when the
|
||||
display apparently just blocks when they ask to see a
|
||||
diff (or 3-way diff) of the configuration file being
|
||||
handled, when actually the diff is displayed on the
|
||||
terminal window ucf was run on. Until the debconf-escape
|
||||
utility and the escape CAPB support, db_subst ran into
|
||||
newline and line length issues. Patch from Michael Vogt.
|
||||
|
||||
2007-04-17 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf.1: srivasta@debian.org--lenny/ucf--devel--2.0--base-0
|
||||
Document that ucf now tries to preserve owner/permission
|
||||
bits for the file.
|
||||
|
||||
* ucf: srivasta@debian.org--lenny/ucf--devel--2.0--base-0 As far
|
||||
as possible, preserve file attributes like ownership and
|
||||
permission by using cp -pf instead of just cp -f.
|
||||
|
||||
2007-02-25 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucfr (safe_conf_file):
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--versionfix-4
|
||||
Reincorporate the fix from the NMU. Add a space before
|
||||
the echo.
|
||||
|
||||
2007-02-24 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf.1: srivasta@debian.org--etch/ucf--devel--2.0--versionfix-3
|
||||
Add documentation clarifying the primary use for ucf.
|
||||
|
||||
* ucfr (safe_conf_file):
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--versionfix-2
|
||||
Add $progname: prefix to all error messages.
|
||||
|
||||
2007-01-18 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucfr.1: srivasta@debian.org--etch/ucf--devel--2.0--versionfix-1
|
||||
Emphasize that the full path to the configuration file
|
||||
is expected.
|
||||
|
||||
* ucfq.1: srivasta@debian.org--etch/ucf--devel--2.0--versionfix-1
|
||||
Ditto.
|
||||
|
||||
* ucfr (safe_conf_file):
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--versionfix-1
|
||||
Issue a diagnostic, and exit gracefully if the
|
||||
registration request has not provided a full path to the
|
||||
configuration file. For lenny, the graceful exit shall
|
||||
be changed into die with a error message.
|
||||
|
||||
* ucfq (process):
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--versionfix-1
|
||||
Issue a diagnostic, and exit gracefully if the query has
|
||||
not provided a full path to the configuration file. For
|
||||
lenny, the graceful exit shall be changed into die with
|
||||
a error message.
|
||||
|
||||
* ucf: srivasta@debian.org--etch/ucf--devel--2.0--patch-20 Typo
|
||||
fix.
|
||||
|
||||
* ucf.1: srivasta@debian.org--etch/ucf--devel--2.0--patch-20 Typo
|
||||
fix.
|
||||
|
||||
2006-11-16 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucfr.1: srivasta@debian.org--etch/ucf--devel--2.0--patch-18 Typo
|
||||
fixes: cofiguration -> configuration, asociating ->
|
||||
associating, mutiple -> multiple
|
||||
|
||||
* ucfq.1: srivasta@debian.org--etch/ucf--devel--2.0--patch-18 Typo
|
||||
Fix: modfied -> modified
|
||||
|
||||
* ucf.1: srivasta@debian.org--etch/ucf--devel--2.0--patch-18 Typo
|
||||
fix: "witht he" -> "with the"
|
||||
|
||||
2006-10-23 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf (TEMP): srivasta@debian.org--etch/ucf--devel--2.0--patch-17
|
||||
Use readlink to canonicalize the path names presented to
|
||||
ucf. This ensures that we keep track of information
|
||||
about the correct file in ucf, even if it is referred to
|
||||
differently (like, multiple ///s, or a/../a/)
|
||||
|
||||
* ucfq: srivasta@debian.org--etch/ucf--devel--2.0--patch-16 The
|
||||
package name is ucf, not Ucf. Fixes the usage help
|
||||
output.
|
||||
|
||||
2006-09-11 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf.1 (needed):
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--patch-15 Typo fix.
|
||||
|
||||
2006-08-20 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf.1: srivasta@debian.org--etch/ucf--devel--2.0--patch-14
|
||||
Document various extensions optionally used by ucf to
|
||||
store copies of versions of configuration files ucf is
|
||||
working with.
|
||||
|
||||
2006-06-16 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf (safe_dest_file):
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--patch-12
|
||||
Improve the handling of finding a sensible pager. This
|
||||
now handles a messed up /etc/alternatives/paper
|
||||
setting. Also included sensible pager as an
|
||||
alternative, and fall back to /bin/more if
|
||||
needed. Also, allow for readlink failures.
|
||||
|
||||
2006-04-11 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf.1: srivasta@debian.org--etch/ucf--devel--2.0--patch-8 Added
|
||||
documentation for the --state-dir option.
|
||||
|
||||
* ucfr.1: Documentation for the new command ucfr
|
||||
|
||||
* ucfr: New file. Associates, and disassociates, a package name
|
||||
with configuration files.
|
||||
|
||||
* Makefile (check):
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--patch-8 Added
|
||||
a check for ucfr
|
||||
(install):
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--patch-8
|
||||
Install ucfr and manual page as well
|
||||
|
||||
* ucf (NEW_SUFFIX):
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--patch-7 Added
|
||||
new variables to hold the suffix we use todenote the
|
||||
{maintainers, old, new} versions of a file. Used to be
|
||||
dpkg-{dist,old,new}, now it is ucf-{dist,old,new}.
|
||||
|
||||
2005-09-20 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf (newsum): srivasta@debian.org--etch/ucf--devel--2.0--patch-4
|
||||
Added support for side-by-side diffs, This is very
|
||||
similar to doing a standard diff, apart from calling
|
||||
sdiff instead (and change the option switches around as
|
||||
needed.
|
||||
|
||||
2005-09-01 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* examples/postrm:
|
||||
srivasta@debian.org--etch/ucf--devel--2.0--patch-2 only
|
||||
use ucf if it is available
|
||||
|
||||
2005-08-08 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf: srivasta@debian.org--etch/ucf--devel--2.0--patch-1 Add code
|
||||
to determine the value of UCF_FORCE_CONFFMISS, looking
|
||||
at the command line, env variable, config file, or
|
||||
default (the default being unset). No command line
|
||||
option is currently available, but the underpinning are
|
||||
there. Replace the destination file, if missing, and iff
|
||||
the variable is set.
|
||||
|
||||
* ucf.1: srivasta@debian.org--etch/ucf--devel--2.0--patch-1
|
||||
Document UCF_FORCE_CONFFMISS. This environment variable
|
||||
is only applicable when the installed destination file
|
||||
does not exist (perhaps due to user removal),and forces
|
||||
ucf to recreate the missing file (the default behaviour
|
||||
is to honor the users wishes and not recreate the
|
||||
locally deleted file).
|
||||
|
||||
2005-06-25 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* ucf (safe_dest_file):
|
||||
srivasta@debian.org--etch/ucf--devel--0.1--base-0 Well,
|
||||
setting VERBOSE to 0 is the same as being quiet,
|
||||
according to the man page. Unfortunately, the code
|
||||
actually looked to see if VERBOSE was set (even if set
|
||||
to 0). Now, we unset VERBOSE if the user had set it to
|
||||
0, making everyone happy.
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
############################ -*- Mode: Makefile -*- ###########################
|
||||
## Makefile<ucf> ---
|
||||
## Author : Manoj Srivastava ( srivasta@glaurung.green-gryphon.com )
|
||||
## Created On : Tue Nov 18 22:00:27 2003
|
||||
## Created On Node : glaurung.green-gryphon.com
|
||||
## Last Modified By : Manoj Srivastava
|
||||
## Last Modified On : Sun Apr 16 16:32:23 2006
|
||||
## Last Machine Used: glaurung.internal.golden-gryphon.com
|
||||
## Update Count : 6
|
||||
## Status : Unknown, Use with caution!
|
||||
## HISTORY :
|
||||
## Description :
|
||||
##
|
||||
###############################################################################
|
||||
prefix = $(DESTDIR)
|
||||
package = ucf
|
||||
|
||||
ETCDIR = $(prefix)/etc
|
||||
BINDIR = $(prefix)/usr/bin
|
||||
DEBLIBDIR = $(prefix)/var/lib/$(package)
|
||||
DEBDOCDIR = $(prefix)/usr/share/doc/$(package)
|
||||
MANDIR = $(prefix)/usr/share/man/
|
||||
MAN1DIR = $(MANDIR)/man1
|
||||
MAN5DIR = $(MANDIR)/man5
|
||||
|
||||
# install commands
|
||||
install_file := /usr/bin/install -p -o root -g root -m 644
|
||||
install_program := /usr/bin/install -p -o root -g root -m 755
|
||||
make_directory := /usr/bin/install -p -d -o root -g root -m 755
|
||||
|
||||
all build: check
|
||||
|
||||
check:
|
||||
bash -n ucf
|
||||
bash -n ucfr
|
||||
perl -wc ucfq
|
||||
bash -n debian/ucf.preinst
|
||||
bash -n debian/ucf.postinst
|
||||
bash -n debian/ucf.postrm
|
||||
|
||||
install:
|
||||
$(make_directory) $(BINDIR)
|
||||
$(make_directory) $(ETCDIR)
|
||||
$(make_directory) $(MAN1DIR)
|
||||
$(make_directory) $(MAN5DIR)
|
||||
$(make_directory) $(DEBLIBDIR)
|
||||
$(make_directory) $(DEBDOCDIR)/examples
|
||||
$(install_program) ucf $(BINDIR)
|
||||
$(install_file) ucf.1 $(MAN1DIR)
|
||||
gzip -9fq $(MAN1DIR)/ucf.1
|
||||
$(install_program) ucfr $(BINDIR)
|
||||
$(install_file) ucfr.1 $(MAN1DIR)
|
||||
gzip -9fq $(MAN1DIR)/ucfr.1
|
||||
$(install_program) ucfq $(BINDIR)
|
||||
$(install_file) ucfq.1 $(MAN1DIR)
|
||||
gzip -9fq $(MAN1DIR)/ucfq.1
|
||||
$(install_program) lcf $(BINDIR)
|
||||
$(install_file) lcf.1 $(MAN1DIR)
|
||||
gzip -9fq $(MAN1DIR)/lcf.1
|
||||
$(install_file) ucf.conf.5 $(MAN5DIR)
|
||||
gzip -9fq $(MAN5DIR)/ucf.conf.5
|
||||
$(install_file) ucf.conf $(ETCDIR)
|
||||
$(install_file) debian/changelog $(DEBDOCDIR)/changelog
|
||||
gzip -9frq $(DEBDOCDIR)
|
||||
# make sure the copyright file is not compressed
|
||||
$(install_file) debian/copyright $(DEBDOCDIR)/copyright
|
||||
$(install_file) examples/postinst $(DEBDOCDIR)/examples/
|
||||
$(install_file) examples/postrm $(DEBDOCDIR)/examples/
|
||||
|
||||
clean distclean:
|
||||
@echo nothing to do for clean
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
2007-04-17 Manoj Srivastava <srivasta@debian.org>
|
||||
|
||||
* postrm: srivasta@debian.org--lenny/ucf--devel--2.0--base-0 Now
|
||||
ucf creates .ucf-new, .ucf-old, and .ucf-dist suffixes,
|
||||
so the example is updated to clean the new names.
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
#! /bin/sh
|
||||
# postinst.skeleton
|
||||
# Skeleton maintainer script showing all the possible cases.
|
||||
# Written by Charles Briscoe-Smith, March-June 1998. Public Domain.
|
||||
|
||||
# Abort if any command returns an error value
|
||||
set -e
|
||||
|
||||
# This script is called as the last step of the installation of the
|
||||
# package. All the package's files are in place, dpkg has already done
|
||||
# its automatic conffile handling, and all the packages we depend of
|
||||
# are already fully installed and configured.
|
||||
|
||||
# The following idempotent stuff doesn't generally need protecting
|
||||
# against being run in the abort-* cases.
|
||||
|
||||
# Install info files into the dir file
|
||||
: install-info --quiet --section "section pattern" "Section Title" \
|
||||
: --description="Name of the document" /usr/info/foo.info
|
||||
|
||||
# Create stub directories under /usr/local
|
||||
: if test ! -d /usr/local/lib/foo; then
|
||||
: if test ! -d /usr/local/lib; then
|
||||
: if mkdir /usr/local/lib; then
|
||||
: chown root.staff /usr/local/lib || true
|
||||
: chmod 2775 /usr/local/lib || true
|
||||
: fi
|
||||
: fi
|
||||
: if mkdir /usr/local/lib/foo; then
|
||||
: chown root.staff /usr/local/lib/foo || true
|
||||
: chmod 2775 /usr/local/lib/foo || true
|
||||
: fi
|
||||
: fi
|
||||
|
||||
# Ensure the menu system is updated
|
||||
: [ ! -x /usr/bin/update-menus ] || /usr/bin/update-menus
|
||||
|
||||
# Arrange for a daemon to be started at system boot time
|
||||
: update-rc.d foo default >/dev/null
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
# Configure this package. If the package must prompt the user for
|
||||
# information, do it here.
|
||||
:
|
||||
|
||||
# Activate menu-methods script
|
||||
: chmod a+x /etc/menu-methods/foo
|
||||
|
||||
# Update ld.so cache
|
||||
: ldconfig
|
||||
|
||||
# Make our version of a program available
|
||||
: update-alternatives \
|
||||
: --install /usr/bin/program program /usr/bin/alternative 50 \
|
||||
: --slave /usr/share/man/man1/program.1.gz program.1.gz \
|
||||
: /usr/share/man/man1/alternative.1.gz
|
||||
|
||||
# Tell ucf that the file in /usr/share/foo is the latest
|
||||
# maintainer version, and let it handle how to manage the real
|
||||
# confuguration file in /etc. This is how a static configuration
|
||||
# file can be handled:
|
||||
ucf /usr/share/foo/configuration /etc/foo.conf
|
||||
ucfr foo /etc/foo.conf
|
||||
|
||||
### We could also do this on the fly. The following is from Tore
|
||||
### Anderson:
|
||||
|
||||
#. /usr/share/debconf/confmodule
|
||||
|
||||
### find out what the user answered.
|
||||
# db_get foo/run_on_boot
|
||||
# run_on_boot=$RET
|
||||
# db_stop
|
||||
|
||||
### safely create a temporary file to generate our suggested
|
||||
### configuration file.
|
||||
# tempfile=`tempfile`
|
||||
# cat << _eof > $tempfile
|
||||
### Configuration file for Foo.
|
||||
|
||||
### this was answered by you, the user in a debconf dialogue
|
||||
# RUNONBOOT=$run_on_boot
|
||||
|
||||
### this was not, as it has a sane default value.
|
||||
# COLOUROFSKY=blue
|
||||
|
||||
#_eof
|
||||
|
||||
### Note that some versions of debconf do not release stdin, so
|
||||
### the following invocation of ucf may not work, since the stdin
|
||||
### is never connected to ucfr.
|
||||
|
||||
### now, invoke ucf, which will take care of the rest, and ask
|
||||
### the user if he wants to update his file, if it is modified.
|
||||
#ucf $tempfile /etc/foo.conf
|
||||
|
||||
### done! now we'll just clear up our cruft.
|
||||
#rm -f $tempfile
|
||||
|
||||
|
||||
# There are three sub-cases:
|
||||
if test "${2+set}" != set; then
|
||||
# We're being installed by an ancient dpkg which doesn't remember
|
||||
# which version was most recently configured, or even whether
|
||||
# there is a most recently configured version.
|
||||
:
|
||||
|
||||
elif test -z "$2" -o "$2" = "<unknown>"; then
|
||||
# The package has not ever been configured on this system, or was
|
||||
# purged since it was last configured.
|
||||
:
|
||||
|
||||
else
|
||||
# Version $2 is the most recently configured version of this
|
||||
# package.
|
||||
:
|
||||
|
||||
fi ;;
|
||||
abort-upgrade)
|
||||
# Back out of an attempt to upgrade this package FROM THIS VERSION
|
||||
# to version $2. Undo the effects of "prerm upgrade $2".
|
||||
:
|
||||
|
||||
;;
|
||||
abort-remove)
|
||||
if test "$2" != in-favour; then
|
||||
echo "$0: undocumented call to \`postinst $*'" 1>&2
|
||||
exit 0
|
||||
fi
|
||||
# Back out of an attempt to remove this package, which was due to
|
||||
# a conflict with package $3 (version $4). Undo the effects of
|
||||
# "prerm remove in-favour $3 $4".
|
||||
:
|
||||
|
||||
;;
|
||||
abort-deconfigure)
|
||||
if test "$2" != in-favour -o "$5" != removing; then
|
||||
echo "$0: undocumented call to \`postinst $*'" 1>&2
|
||||
exit 0
|
||||
fi
|
||||
# Back out of an attempt to deconfigure this package, which was
|
||||
# due to package $6 (version $7) which we depend on being removed
|
||||
# to make way for package $3 (version $4). Undo the effects of
|
||||
# "prerm deconfigure in-favour $3 $4 removing $6 $7".
|
||||
:
|
||||
|
||||
;;
|
||||
*) echo "$0: didn't understand being called with \`$1'" 1>&2
|
||||
exit 0;;
|
||||
esac
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,115 @@
|
|||
#! /bin/sh
|
||||
# postrm.skeleton
|
||||
# Skeleton maintainer script showing all the possible cases.
|
||||
# Written by Charles Briscoe-Smith, March-June 1998. Public Domain.
|
||||
|
||||
# Abort if any command returns an error value
|
||||
set -e
|
||||
|
||||
# This script is called twice during the removal of the package; once
|
||||
# after the removal of the package's files from the system, and as
|
||||
# the final step in the removal of this package, after the package's
|
||||
# conffiles have been removed.
|
||||
|
||||
# Ensure the menu system is updated
|
||||
: [ ! -x /usr/bin/update-menus ] || /usr/bin/update-menus
|
||||
|
||||
case "$1" in
|
||||
remove)
|
||||
# This package is being removed, but its configuration has not yet
|
||||
# been purged.
|
||||
:
|
||||
|
||||
# Remove diversion
|
||||
: dpkg-divert --package foo --remove --rename \
|
||||
: --divert /usr/bin/other.real /usr/bin/other
|
||||
|
||||
# ldconfig is NOT needed during removal of a library, only during
|
||||
# installation
|
||||
|
||||
;;
|
||||
purge)
|
||||
# This package has previously been removed and is now having
|
||||
# its configuration purged from the system.
|
||||
:
|
||||
|
||||
# we mimic dpkg as closely as possible, so we remove configuration
|
||||
# files with dpkg backup extensions too:
|
||||
### Some of the following is from Tore Anderson:
|
||||
for ext in '~' '%' .bak .ucf-new .ucf-old .ucf-dist; do
|
||||
rm -f /etc/foo.conf$ext
|
||||
done
|
||||
|
||||
# remove the configuration file itself
|
||||
rm -f /etc/foo.conf
|
||||
|
||||
# and finally clear it out from the ucf database
|
||||
if which ucf >/dev/null; then
|
||||
ucf --purge /etc/foo.conf
|
||||
fi
|
||||
if which ucfr >/dev/null; then
|
||||
ucfr --purge foo /etc/foo.conf
|
||||
fi
|
||||
|
||||
# Remove symlinks from /etc/rc?.d
|
||||
: update-rc.d foo remove >/dev/null
|
||||
|
||||
;;
|
||||
disappear)
|
||||
if test "$2" != overwriter; then
|
||||
echo "$0: undocumented call to \`postrm $*'" 1>&2
|
||||
exit 0
|
||||
fi
|
||||
# This package has been completely overwritten by package $3
|
||||
# (version $4). All our files are already gone from the system.
|
||||
# This is a special case: neither "prerm remove" nor "postrm remove"
|
||||
# have been called, because dpkg didn't know that this package would
|
||||
# disappear until this stage.
|
||||
:
|
||||
|
||||
;;
|
||||
upgrade)
|
||||
# About to upgrade FROM THIS VERSION to version $2 of this package.
|
||||
# "prerm upgrade" has been called for this version, and "preinst
|
||||
# upgrade" has been called for the new version. Last chance to
|
||||
# clean up.
|
||||
:
|
||||
|
||||
;;
|
||||
failed-upgrade)
|
||||
# About to upgrade from version $2 of this package TO THIS VERSION.
|
||||
# "prerm upgrade" has been called for the old version, and "preinst
|
||||
# upgrade" has been called for this version. This is only used if
|
||||
# the previous version's "postrm upgrade" couldn't handle it and
|
||||
# returned non-zero. (Fix old postrm bugs here.)
|
||||
:
|
||||
|
||||
;;
|
||||
abort-install)
|
||||
# Back out of an attempt to install this package. Undo the effects of
|
||||
# "preinst install...". There are two sub-cases.
|
||||
:
|
||||
|
||||
if test "${2+set}" = set; then
|
||||
# When the install was attempted, version $2's configuration
|
||||
# files were still on the system. Undo the effects of "preinst
|
||||
# install $2".
|
||||
:
|
||||
|
||||
else
|
||||
# We were being installed from scratch. Undo the effects of
|
||||
# "preinst install".
|
||||
:
|
||||
|
||||
fi ;;
|
||||
abort-upgrade)
|
||||
# Back out of an attempt to upgrade this package from version $2
|
||||
# TO THIS VERSION. Undo the effects of "preinst upgrade $2".
|
||||
:
|
||||
|
||||
;;
|
||||
*) echo "$0: didn't understand being called with \`$1'" 1>&2
|
||||
exit 0;;
|
||||
esac
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,260 @@
|
|||
#!/bin/bash
|
||||
# -*- Mode: Sh -*-
|
||||
# lcf ---
|
||||
# Author : Manoj Srivastava ( srivasta@glaurung.green-gryphon.com )
|
||||
# Created On : Mon Feb 25 12:04:52 2002
|
||||
# Created On Node : glaurung.green-gryphon.com
|
||||
# Last Modified By : Manoj Srivastava
|
||||
# Last Modified On : Mon Feb 25 12:06:54 2002
|
||||
# Last Machine Used: glaurung.green-gryphon.com
|
||||
# Update Count : 2
|
||||
# Status : Unknown, Use with caution!
|
||||
# HISTORY :
|
||||
# Description :
|
||||
#
|
||||
#
|
||||
|
||||
# make sure we exit on error
|
||||
set -e
|
||||
|
||||
# set the version and revision
|
||||
progname="$(basename $0)"
|
||||
pversion='Revision: 3.00'
|
||||
|
||||
######################################################################
|
||||
######## #########
|
||||
######## Utility functions #########
|
||||
######## #########
|
||||
######################################################################
|
||||
setq() {
|
||||
# Variable Value Doc_string
|
||||
if [ "x$2" = "x" ]; then
|
||||
echo >&2 "$progname: Unable to determine $3"
|
||||
exit 1;
|
||||
else
|
||||
if [ "x$VERBOSE" != "x" ]; then
|
||||
echo "$progname: $3 is $2";
|
||||
fi
|
||||
eval "$1=\"\$2\"";
|
||||
fi
|
||||
}
|
||||
|
||||
withecho () {
|
||||
echo "$@" >&2
|
||||
"$@"
|
||||
}
|
||||
|
||||
usageversion () {
|
||||
cat >&2 <<END
|
||||
Debian GNU/Linux $progname $pversion.
|
||||
Copyright (C) 2002 Manoj Srivastava.
|
||||
This is free software; see the GNU General Public Licence for copying
|
||||
conditions. There is NO warranty.
|
||||
|
||||
Usage: $progname [options] dest_file src_dir
|
||||
Options:
|
||||
-h, --help print this message
|
||||
-s foo, --src-dir foo Set the src dir (historical md5sums live here)
|
||||
-d [n], --debug [n] Set the Debug level to N
|
||||
-n, --no-action Dry run. No action is actually taken.
|
||||
-v, --verbose Make the script verbose
|
||||
|
||||
By default, the directory the new_file lives in is assumed to be the src-dir,
|
||||
which is where we look for any historical md5sums.
|
||||
|
||||
END
|
||||
}
|
||||
|
||||
######################################################################
|
||||
######## #########
|
||||
######## Command line args #########
|
||||
######## #########
|
||||
######################################################################
|
||||
#
|
||||
# Long term variables#
|
||||
#
|
||||
docmd='YES'
|
||||
action='withecho'
|
||||
DEBUG=0
|
||||
VERBOSE=''
|
||||
statedir='/var/lib/ucf';
|
||||
|
||||
|
||||
# Note that we use `"$@"' to let each command-line parameter expand to a
|
||||
# separate word. The quotes around `$@' are essential!
|
||||
# We need TEMP as the `eval set --' would nuke the return value of getopt.
|
||||
TEMP=$(getopt -o hs:d:D::nv -n "$progname" \
|
||||
--long help,src-dir:,dest-dir:DEBUG::,no-action,verbose \
|
||||
-- "$@")
|
||||
|
||||
if [ $? != 0 ] ; then
|
||||
echo "Error handling options.Terminating..." >&2 ;
|
||||
exit 1 ;
|
||||
fi
|
||||
|
||||
# Note the quotes around `$TEMP': they are essential!
|
||||
eval set -- "$TEMP"
|
||||
|
||||
while true ; do
|
||||
case "$1" in
|
||||
-h|--help) usageversion; exit 0 ;;
|
||||
-n|--no-action) action='echo'; docmd='NO'; shift ;;
|
||||
-v|--verbose) VERBOSE=1; shift ;;
|
||||
-s|--src-dir)
|
||||
opt_source_dir="$2"; shift 2 ;;
|
||||
-d|--debug)
|
||||
# d has an optional argument. As we are in quoted mode,
|
||||
# an empty parameter will be generated if its optional
|
||||
# argument is not found.
|
||||
case "$2" in
|
||||
"") setq DEBUG 1 "The Debug value"; shift 2 ;;
|
||||
*) setq DEBUG "$2" "The Debug value"; shift 2 ;;
|
||||
esac ;;
|
||||
--) shift ; break ;;
|
||||
*) echo "Internal error!" ; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $# != 2 ]; then
|
||||
echo >&2 "*** ERROR: Need exactly two arguments, got $#";
|
||||
echo >&2 ""
|
||||
usageversion;
|
||||
exit 0 ;
|
||||
fi
|
||||
|
||||
setq dest_file "$1" "The Destination file";
|
||||
setq source_dir "$2" "The source directory";
|
||||
|
||||
|
||||
# Load site defaults and over rides.
|
||||
if [ -f /etc/ucf.conf ]; then
|
||||
. /etc/ucf.conf
|
||||
fi
|
||||
|
||||
# Command line, env variable, config file, or default
|
||||
if [ "X$source_dir" = "X" ]; then
|
||||
if [ ! "x$opt_source_dir" = "x" ]; then
|
||||
setq source_dir "$opt_source_dir" "The Source directory"
|
||||
elif [ ! "x$UCF_SOURCE_DIR" = "x" ]; then
|
||||
setq source_dir "$UCF_SOURCE_DIR" "The Source directory"
|
||||
elif [ ! "x$conf_source_dir" = "x" ]; then
|
||||
setq source_dir "$conf_source_dir" "The Source directory"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d "$source_dir" ]; then
|
||||
echo >&2 "The source dir does not exist. Stopping now."
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
if [ "X$dest_file" = "X" ]; then
|
||||
echo >&2 "Uknown file to search for. Stopping now."
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
old_mdsum_dir="$source_dir/$(basename ${new_file}).md5sum.d";
|
||||
old_mdsum_file="$source_dir/$(basename ${new_file}).md5sum";
|
||||
|
||||
|
||||
if [ -e "$statedir/hashfile" -a ! -r "$statedir/hashfile" ]; then
|
||||
echo >&2 "$progname: do not have read privilege to the state data"
|
||||
if [ "X$docmd" = "XYES" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
# test and see if this file exists in the database
|
||||
if [ -e "$statedir/hashfile" ]; then
|
||||
if [ "X$VERBOSE" != "X" ]; then
|
||||
echo >&2 "The hash file exists";
|
||||
echo grep "[[:space:]]${dest_file}$" "$statedir/hashfile";
|
||||
grep "[[:space:]]${dest_file}$" "$statedir/hashfile" ;
|
||||
fi
|
||||
lastsum=$(grep "[[:space:]]${dest_file}$" "$statedir/hashfile" | \
|
||||
awk '{print $1;}' );
|
||||
fi
|
||||
|
||||
if [ "X$lastsum" = "X" ]; then
|
||||
echo >&2 "$progname: No record of file in databse. Stopping now."
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
if [ $DEBUG -gt 0 ]; then
|
||||
cat <<EOF
|
||||
The new start file is \`$new_file\'
|
||||
The destination is \`$dest_file\'
|
||||
The history is kept under \'$source_dir\'
|
||||
EOF
|
||||
if [ -s "$dest_file" ]; then
|
||||
echo "The destination file exists, and has md5sum:"
|
||||
$action md5sum "$dest_file"
|
||||
else
|
||||
echo "The destination file does not exist."
|
||||
fi
|
||||
if [ "X$lastsum" != "X" ]; then
|
||||
echo "The old md5sum exists, and is:"
|
||||
echo "$lastsum"
|
||||
else
|
||||
echo "The old md5sum does not exist."
|
||||
fi
|
||||
if [ -e "$new_file" ]; then
|
||||
echo "The new file exists, and has md5sum:"
|
||||
$action md5sum "$new_file"
|
||||
else
|
||||
echo "The new file does not exist."
|
||||
fi
|
||||
if [ -d "$old_mdsum_dir" ]; then
|
||||
echo "The historical md5sum dir $old_mdsum_dir exists"
|
||||
elif [ -f "$old_mdsum_file" ]; then
|
||||
echo "The histotical md5sum file $old_mdsum_file exists"
|
||||
else
|
||||
echo "Historical md5sums are not available"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$old_mdsum_dir" -o -f "$old_mdsum_file" ]; then
|
||||
if [ -d "$old_mdsum_dir" ]; then
|
||||
for file in ${old_mdsum_dir}/*; do
|
||||
oldsum="$(awk '{print $1}' $file)";
|
||||
if [ "$oldsum" = "$destsum" ]; then
|
||||
# Bingo!
|
||||
echo "$(awk '{print $2}' $file)";
|
||||
exit 0;
|
||||
fi
|
||||
done
|
||||
elif [ -f "$old_mdsum_file" ]; then
|
||||
oldsum=$(grep "^${destsum}" "$old_mdsum_file")
|
||||
if [ "X$oldsum" != "X" ]; then
|
||||
# Bingo
|
||||
echo $(grep "^${destsum}" "$old_mdsum_file" | awk '{print $2}')
|
||||
exit 0;
|
||||
fi
|
||||
fi
|
||||
# Well, nothing matched. We now check to see if the
|
||||
# maintainer has an opinion on how to set the ``md5sum of the
|
||||
# previously installed version'', since we have no way of
|
||||
# determining that automatically. Please note that unless
|
||||
# there are limited number of previously released packages
|
||||
# (like just one), the maintainer is also making a guess at
|
||||
# this point by supplying a historical md5sum default file.
|
||||
if [ "X$VERBOSE" != "X" ]; then
|
||||
echo >&2 "Histotical md5sums did not match."
|
||||
fi
|
||||
if [ -d "$old_mdsum_dir" ]; then
|
||||
if [ -e "${old_mdsum_dir}/default" ]; then
|
||||
echo default;
|
||||
exit 0;
|
||||
fi
|
||||
elif [ -f "$old_mdsum_file" ]; then
|
||||
oldsum=$(grep "[[:space:]]default$" "$old_mdsum_file" | \
|
||||
awk '{print $1;}')
|
||||
if [ "X$oldsum" != "X" ]; then
|
||||
# Bingo
|
||||
echo default;
|
||||
exit 0;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
exit 0;
|
|
@ -0,0 +1,85 @@
|
|||
.\" -*- Mode: Nroff -*-
|
||||
.\" lcf.1 ---
|
||||
.\" Author : Manoj Srivastava ( srivasta@green-gryphon.com )
|
||||
.\" Created On : Fri Feb 1 11:17:32 2002
|
||||
.\" Created On Node : glaurung.green-gryphon.com
|
||||
.\" Last Modified By : Manoj Srivastava
|
||||
.\" Last Modified On : Mon May 2 01:09:42 2005
|
||||
.\" Last Machine Used: glaurung.internal.golden-gryphon.com
|
||||
.\" Update Count : 28
|
||||
.\" Status : Unknown, Use with caution!
|
||||
.\" HISTORY :
|
||||
.\" Description :
|
||||
.\"
|
||||
.\" Copyright (c) 2002 Manoj Srivastava <srivasta@debian.org>
|
||||
.\"
|
||||
.\" This is free documentation; 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.
|
||||
.\"
|
||||
.\" The GNU General Public License's references to "object code"
|
||||
.\" and "executables" are to be interpreted as the output of any
|
||||
.\" document formatting or typesetting system, including
|
||||
.\" intermediate and printed output.
|
||||
.\"
|
||||
.\" This manual 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 manual; if not, write to the Free
|
||||
.\" Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
.\" 02111-1307, USA.
|
||||
.\"
|
||||
.\" $Id: lcf.1,v 1.1 2002/02/26 20:12:06 srivasta Exp $
|
||||
.TH LCF 1 "Feb 1 2002" "Debian" "Debian GNU/Linux manual"
|
||||
.SH NAME
|
||||
lcf \- Determine which of the historical versions of a config is installed
|
||||
.SH SYNOPSIS
|
||||
.B lcf
|
||||
.I [options]
|
||||
.I <Destination File Name>
|
||||
.I <Historical MD5SUM source directory>
|
||||
.SH DESCRIPTION
|
||||
This script, given a destination file name, and a directory containing
|
||||
md5sums of historical versions of the file, attempts to determine if
|
||||
the installed version corresponds to a historical version. lcf uses
|
||||
the same algorithm that ucf uses, and should exhibit the same
|
||||
behaviour.
|
||||
.PP
|
||||
The source directory is the place where historical md5sums are
|
||||
expected to live. Specifically, the historical md5sums are looked for
|
||||
in either the file
|
||||
.I ${filename}.md5sum,
|
||||
or the subdirectory
|
||||
.I ${filename}.md5sum.d/
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B "-h, --help"
|
||||
Print a short usage message
|
||||
.TP
|
||||
.B "-n, --no-action"
|
||||
Dry run. Print the actions that would be taken if the script is
|
||||
invoked, but take no action.
|
||||
.TP
|
||||
.B "-d [n], --debug [n]"
|
||||
Set the debug level to the (optional) level
|
||||
.I n
|
||||
(n defaults to 1). This turns on copious debugging information.
|
||||
.TP
|
||||
.B "-v, --verbose"
|
||||
Make the script be very verbose about setting internal variables.
|
||||
.SH FILES
|
||||
.PP
|
||||
.I /var/lib/ucf/hashfile,
|
||||
.I /etc/ucf.conf
|
||||
.SH "SEE ALSO"
|
||||
ucf(1)
|
||||
ucf.conf(5).
|
||||
.SH BUGS
|
||||
There are no bugs. Any resemblance thereof is delirium. Really.
|
||||
.SH AUTHOR
|
||||
This manual page was written Manoj Srivastava <srivasta@debian.org>,
|
||||
for the Debian GNU/Linux system.
|
|
@ -0,0 +1,369 @@
|
|||
.\" -*- Mode: Nroff -*-
|
||||
.\" updateConfFile.1 ---
|
||||
.\" Author : Manoj Srivastava ( srivasta@green-gryphon.com )
|
||||
.\" Created On : Fri Feb 1 11:17:32 2002
|
||||
.\" Created On Node : glaurung.green-gryphon.com
|
||||
.\" Last Modified By : Manoj Srivastava
|
||||
.\" Last Modified On : Tue Apr 11 14:46:06 2006
|
||||
.\" Last Machine Used: glaurung.internal.golden-gryphon.com
|
||||
.\" Update Count : 53
|
||||
.\" Status : Unknown, Use with caution!
|
||||
.\" HISTORY :
|
||||
.\" Description :
|
||||
.\"
|
||||
.\" Copyright (c) 2002 Manoj Srivastava <srivasta@debian.org>
|
||||
.\"
|
||||
.\" This is free documentation; 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.
|
||||
.\"
|
||||
.\" The GNU General Public License's references to "object code"
|
||||
.\" and "executables" are to be interpreted as the output of any
|
||||
.\" document formatting or typesetting system, including
|
||||
.\" intermediate and printed output.
|
||||
.\"
|
||||
.\" This manual 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 manual; if not, write to the Free
|
||||
.\" Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
.\" 02111-1307, USA.
|
||||
.\"
|
||||
.\" $Id: ucf.1,v 1.10 2003/09/28 23:29:21 srivasta Exp $
|
||||
.TH UCF 1 "May 30 2008" "Debian" "Debian GNU/Linux manual"
|
||||
.SH NAME
|
||||
ucf \- Update Configuration File: preserve user changes in configuration files
|
||||
.SH SYNOPSIS
|
||||
.B ucf
|
||||
.RI [ options "] "
|
||||
.I <New File>
|
||||
.I <Destination>
|
||||
.PP
|
||||
.B ucf
|
||||
.RI [ options "] "
|
||||
.I \-\-purge
|
||||
.I <Destination>
|
||||
.SH DESCRIPTION
|
||||
This utility provides a means of asking the user whether or not to
|
||||
accept new versions of configuration files provided by the package
|
||||
maintainer, with various heuristics designed to minimize
|
||||
interaction time. It uses debconf to interact with the user, as per Debian
|
||||
policy. In the SYNOPSIS above,
|
||||
.I New file
|
||||
is the configuration file as provided by the package (either shipped
|
||||
with the package, or generated by the maintainer scripts on the fly),
|
||||
and
|
||||
.I Destination
|
||||
is the location (usually under /etc) where the real configuration file
|
||||
lives, and is potentially modified by the end user. Since the files
|
||||
edited would be real files, and not symbolic links,
|
||||
.B ucf
|
||||
follows and resolves symbolic links before acting. As far as
|
||||
possible, ucf attempts to preserve the ownership and permission of
|
||||
the
|
||||
.I New file
|
||||
as it is copied to the new location.
|
||||
.PP
|
||||
This script attempts to provide conffile like handling for files
|
||||
installed under
|
||||
.I /etc
|
||||
not
|
||||
shipped in a
|
||||
.B Debian
|
||||
package, but handled by the postinst instead.
|
||||
.B Debian
|
||||
policy states that files under
|
||||
.I /etc
|
||||
which are configuration files
|
||||
.B must
|
||||
preserve user changes, and this applies to files handled by maintainer
|
||||
scripts as well. Using
|
||||
.B ucf,
|
||||
one may ship a bunch of default configuration files somewhere in
|
||||
.I /usr
|
||||
(
|
||||
.I /usr/share/<pkg>
|
||||
is a good location), and maintain files in
|
||||
.I /etc,
|
||||
preserving user changes and in general offering the same facilities
|
||||
while upgrading that
|
||||
.B dpkg
|
||||
normally provides for
|
||||
.I \*(lqconffiles\*(rq
|
||||
.PP
|
||||
Additionally, this script provides facilities for transitioning a file
|
||||
that had not been provided
|
||||
.I conffile
|
||||
like protection to come under this
|
||||
schema, and attempts to minimize questions asked at install
|
||||
time. Indeed, the transitioning facility is better than the one
|
||||
offered by
|
||||
.B dpkg
|
||||
while transitioning a file from a
|
||||
.I non\-conffile
|
||||
to
|
||||
.I conffile
|
||||
status. The second form in the SYNOPSIS above is for purging
|
||||
information about the configuration file when the package is purged;
|
||||
and is critical for allowing smooth reinstallations.
|
||||
.PP
|
||||
During the course of operations, when working with configuration files,
|
||||
.B ucf
|
||||
optionally creates copies of versions of the configuration file in
|
||||
question. For example, a file with the suffix
|
||||
.I "ucf-old"
|
||||
holds the old version of a configuration file replaced by
|
||||
.B ucf.
|
||||
Also, copies of the configuration file with the suffixes
|
||||
.I "ucf-new"
|
||||
and
|
||||
.I "ucf-dist"
|
||||
may be created; and the maintainer scripts should consider purging
|
||||
copies of the configuration file with these extensions during purge.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B "\-h, \-\-help"
|
||||
Print a short usage message
|
||||
.TP
|
||||
.B "\-n, \-\-no\-action"
|
||||
Dry run. Print the actions that would be taken if the script is
|
||||
invoked, but take no action.
|
||||
.TP
|
||||
.B "\-d[n], \-\-debug=[n]"
|
||||
Set the debug level to the (optional) level
|
||||
.I n
|
||||
(n defaults to 1). Please note there must be no spaces before the
|
||||
optional digit n. This turns on copious debugging information.
|
||||
.TP
|
||||
.B "\-p, \-\-purge"
|
||||
Removes all vestiges of the file from the state hashfile. This is
|
||||
required to allow a package to be reinstalled after it is purged;
|
||||
since otherwise, the real configuration file is removed, but it
|
||||
remains in the hash file; and on reinstall no action is taken, since
|
||||
the md5sum of the new file matches that in the hashfile. In short,
|
||||
remember to use this option in the postrm for every configuration file
|
||||
managed by ucf when the package is being purged (assuming ucf itself
|
||||
exists).
|
||||
.I Note:
|
||||
ucf does not actually touch the file on disk in this operation, so any
|
||||
file removals are still the responsibility of the calling package.
|
||||
.TP
|
||||
.B "\-v, \-\-verbose"
|
||||
Make the script be very verbose about setting internal variables.
|
||||
.TP
|
||||
.B "\-s foo, \-\-src\-dir foo"
|
||||
Set the source directory (historical md5sums are expected to live in
|
||||
files and sub directories of this directory) to foo. By default, the
|
||||
directory the new_file lives in is assumed to be the source
|
||||
directory. Setting this option overrides settings in the environment
|
||||
variable
|
||||
.B UCF_SOURCE_DIR,
|
||||
and in the configuration file variable
|
||||
.B conf_source_dir.
|
||||
.TP
|
||||
.B "\-\-sum\-file foo"
|
||||
Force the historical md5sums to be read from this file, rather than
|
||||
defaulting to living in the source directory. Setting this option
|
||||
overrides settings in the environment variable
|
||||
.B UCF_OLD_MDSUM_FILE,
|
||||
and in the configuration file variable
|
||||
.B conf_old_mdsum_file.
|
||||
.TP
|
||||
.B "\-\-three\-way"
|
||||
This turns on the option, during installation, for the user to be
|
||||
offered a chance to see a merge of the changes between old maintainer
|
||||
version and the new maintainer version into the local copy of the
|
||||
configuration file. If the user likes what they see, they can ask to
|
||||
have these changes merged in. This allows one to get new upstream
|
||||
changes merged in even while retaining local modifications to the
|
||||
configuration file. This is accomplished by taking the configuration
|
||||
file and stashing it in a cache area during registration, and using
|
||||
diff3 during the install (the stashed file name is a munged version of
|
||||
the full path of the configuration file to avoid name space clashes).
|
||||
.TP
|
||||
.B "\-\-debconf\-ok"
|
||||
Indicate that it is ok for
|
||||
.I ucf
|
||||
to use an already running debconf instance for prompting (it has
|
||||
always been ok to use ucf when debconf is not running -- it shall
|
||||
invoke debconf as needed).
|
||||
.TP
|
||||
.B "\-\-debconf\-template foo"
|
||||
Instruct ucf to use the named multiselect debconf template instead of
|
||||
the normal ucf-provided debconf template. The caller is responsible for
|
||||
ensuring that the named template exists and has a list of choices
|
||||
matching those for the default ucf template, and should set
|
||||
Choices\-C: ${CHOICES} to ensure the returned values match those from
|
||||
the default template. Note that the choices must be different according
|
||||
to whether the
|
||||
.B \-\-three\-way
|
||||
option is also set.
|
||||
.TP
|
||||
.B "\-\-state\-dir /path/to/dir"
|
||||
Set the state directory to /path/to/dir instead of the default
|
||||
.I /var/lib/ucf.
|
||||
Used mostly for testing.
|
||||
.SH USAGE
|
||||
The most common case usage is pretty simple: a single line invocation
|
||||
in the postinst on configure, and another single line in the postrm to
|
||||
tell
|
||||
.B ucf
|
||||
to forget about the configuration file on purge
|
||||
(using the \-\-purge option) is all that is needed (assuming ucf is
|
||||
still on the system).
|
||||
.PP
|
||||
It is recommended that you also register any file being managed by
|
||||
.B ucf
|
||||
with the ucf registry; this associates the configuration file with the
|
||||
package it belongs to. This is done with a simple call to
|
||||
.B ucfr.
|
||||
Users may then query the association between a configuration file and
|
||||
the package using the tool
|
||||
.B ucfq.
|
||||
Please see the appropriate manual pages for details.
|
||||
.PP
|
||||
If a file maintained by maintainer scripts is being transitioned from an
|
||||
unprotected status to the protection afforded by the script, the
|
||||
maintainer can help ease the transition by reducing the questions that
|
||||
may be asked at installation time. Specifically, questions should not
|
||||
be asked if the file in question is an unmodified version that was one
|
||||
shipped in a previous version of this package; and the maintainer can
|
||||
help by telling the script about the historical md5sums that published
|
||||
versions of this file contained.
|
||||
.PP
|
||||
The way to do this is to either create a file called
|
||||
.B <New file>.md5sum,
|
||||
with one md5sum on each line, (the file names you use are ignored, except
|
||||
for the entry named default), or create a directory, called
|
||||
.B <New file>.md5sum.d,
|
||||
which should contain any number of files, each containing a single
|
||||
line, namely, the md5sum of a previous version of
|
||||
.B <New file>.
|
||||
The names of these files are not important, with one exception: The
|
||||
file called default is treated specially. For example, the author
|
||||
personally uses either package version numbers or release code names,
|
||||
like
|
||||
.I 7.6.3,
|
||||
or
|
||||
.I potato.
|
||||
If none of the historical md5sums match, we are almost certain that
|
||||
either the historical record of md5sums is not complete, or the user
|
||||
has changed the configuration file.
|
||||
.SS "The default historical md5sum"
|
||||
The exception to the rule about names mentioned earlier is that if no
|
||||
md5sums match, and if the file
|
||||
.B <New file>.md5sum.d/default
|
||||
exists, or if there is a line corresponding to a
|
||||
.I default
|
||||
file in
|
||||
.B <New file>.md5sum,
|
||||
it shall be used as the default md5sum of the
|
||||
.I previous
|
||||
version of the package assumed to have been installed on this machine.
|
||||
As you can see, unless there are limited number of previously released
|
||||
packages (like just one), the maintainer is also making an informed
|
||||
guess, but the option is provided to the maintainer.
|
||||
.PP
|
||||
If the file
|
||||
.B <New file>.md5sum,
|
||||
or the directory
|
||||
.B <New file>.md5sum.d
|
||||
does not exist, or none of the md5sums match, we test the installed
|
||||
.I <Destination>
|
||||
file to see whether it is the same as the
|
||||
.I <New file>.
|
||||
If not, we ask the user whether they want us to replace the file.
|
||||
.PP
|
||||
An additional facility is also offered: optionally, ucf can store one
|
||||
old version of the maintainers copy of the configuration file, and,
|
||||
on upgrade, calculate the changes made in the maintainers version of
|
||||
the configuration file, and apply that patch to the local version of
|
||||
the file (on user request, of course). There is also a preview
|
||||
facility where the user can inspect the results of such a merge,
|
||||
before asking the action to be taken.
|
||||
.SH "ENVIRONMENT VARIABLES"
|
||||
The variable
|
||||
.B UCF_FORCE_CONFFNEW,
|
||||
if set, forces the new file to always overwrite the installed
|
||||
destination file, while the variable
|
||||
.B UCF_FORCE_CONFFOLD,
|
||||
if set silently retains the installed file.
|
||||
.B UCF_FORCE_CONFFMISS
|
||||
is only applicable when the installed destination file does not exist
|
||||
(perhaps due to user removal),and forces ucf to recreate the missing
|
||||
file (the default behaviour is to honor the users wishes and not
|
||||
recreate the locally deleted file).
|
||||
.SH FILES
|
||||
This script creates the file
|
||||
.I new_file.md5sum,
|
||||
and it may copy the file (presumably shipped with the package)
|
||||
.I <New file>
|
||||
to its destination,
|
||||
.I <Destination>.
|
||||
.PP
|
||||
.I /var/lib/ucf/hashfile,
|
||||
and
|
||||
.I /var/lib/ucf/hashfile.X,
|
||||
where
|
||||
.I X
|
||||
is a small integer, where previous versions of the hashfile are
|
||||
stored.
|
||||
.PP
|
||||
.I /etc/ucf.conf
|
||||
.SH EXAMPLES
|
||||
If the package
|
||||
.I foo
|
||||
wants to use ucf to handle user interaction for configuration file
|
||||
.I foo.conf,
|
||||
a version of which is provided in the package as
|
||||
.I /usr/share/foo/configuration,
|
||||
a simple invocation of ucf in the post inst file is all that is
|
||||
needed:
|
||||
.PP
|
||||
.B ucf
|
||||
.I /usr/share/foo/configuration
|
||||
.I /etc/foo.conf
|
||||
.PP
|
||||
On purge, one should tell ucf to forget about the file (see detailed
|
||||
examples in /usr/share/doc/ucf/examples):
|
||||
.PP
|
||||
.B ucf
|
||||
.I \-\-purge
|
||||
.I /etc/foo.conf
|
||||
Please note that purge can also be used to make ucf forget the
|
||||
previous state of the files, and when the package is next installed or
|
||||
updated, ucf will ask the user to replace the current cofiguration
|
||||
file. Do this if you want to change your decision to not update to a
|
||||
maintainer provided version of the configuration file.
|
||||
.PP
|
||||
The motivation for this script was to provide conffile like handling
|
||||
for start files for emacs lisp packages (for example,
|
||||
.I /etc/emacs21/site\-start.d/50psgml\-init.el
|
||||
) These start files are not
|
||||
shipped with the package, instead, they are installed during the
|
||||
post installation configuration phase by the script
|
||||
.I /usr/lib/emacsen\-common/emacs\-package\-install $package_name.
|
||||
.PP
|
||||
This script is meant to be invoked by the packages install script at
|
||||
.I /usr/lib/emacsen\-common/packages/install/$package_name
|
||||
for each
|
||||
flavour of installed emacsen by calling it with the proper values of
|
||||
new file (
|
||||
.I /usr/share/emacs/site\-lisp/<pkg>/<pkg\-init.el
|
||||
), and dest file
|
||||
(
|
||||
.I /etc/emacs21/site\-start.d/50<pkg\-init.el
|
||||
), and it should do the rest.
|
||||
.SH "SEE ALSO"
|
||||
ucf.conf(5), ucfr(1), ucfq(1), and diff3(1).
|
||||
The
|
||||
.B Debian
|
||||
Emacs policy, shipped with the package
|
||||
.I emacsen\-common.
|
||||
.SH AUTHOR
|
||||
This manual page was written Manoj Srivastava <srivasta@debian.org>,
|
||||
for the Debian GNU/Linux system.
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# This file is a bourne shell snippet, and is sourced by the
|
||||
# ucf script for configuration.
|
||||
#
|
||||
|
||||
# Debugging information: The default value is 0 (no debugging
|
||||
# information is printed). To change the default behavior, uncomment
|
||||
# the following line and set the value to 1.
|
||||
#
|
||||
# DEBUG=0
|
||||
|
||||
# Verbosity: The default value is 0 (quiet). To change the default
|
||||
# behavior, uncomment the following line and set the value to 1.
|
||||
#
|
||||
# VERBOSE=0
|
||||
|
||||
|
||||
# The src directory. This is the directory where the historical
|
||||
# md5sums for a file are looked for. Specifically, the historical
|
||||
# md5sums are looked for in the subdirectory ${filename}.md5sum.d/
|
||||
#
|
||||
# conf_source_dir=/some/path/
|
||||
|
||||
# Force the installed file to be retained. The default is have this
|
||||
# variable unset, which makes the script ask in case of doubt. To
|
||||
# change the default behavior, uncomment the following line and set
|
||||
# the value to YES
|
||||
#
|
||||
# conf_force_conffold=YES
|
||||
|
||||
# Force the installed file to be overridden. The default is have this
|
||||
# variable unset, which makes the script ask in case of doubt. To
|
||||
# change the default behavior, uncomment the following line and set
|
||||
# the value to YES
|
||||
#
|
||||
# conf_force_conffnew=YES
|
||||
|
||||
# Please note that only one of conf_force_conffold and
|
||||
# conf_force_conffnew should be set.
|
|
@ -0,0 +1,120 @@
|
|||
.\" -*- Mode: Nroff -*-
|
||||
.\" updateConfFile.1 ---
|
||||
.\" Author : Manoj Srivastava ( srivasta@green-gryphon.com )
|
||||
.\" Created On : Fri Feb 1 11:17:32 2002
|
||||
.\" Created On Node : glaurung.green-gryphon.com
|
||||
.\" Last Modified By : Manoj Srivastava
|
||||
.\" Last Modified On : Mon Apr 19 12:16:51 2004
|
||||
.\" Last Machine Used: glaurung.internal.golden-gryphon.com
|
||||
.\" Update Count : 28
|
||||
.\" Status : Unknown, Use with caution!
|
||||
.\" HISTORY :
|
||||
.\" Description :
|
||||
.\" Copyright (c) 2002 Manoj Srivastava <srivasta@debian.org>
|
||||
.\"
|
||||
.\" This is free documentation; 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.
|
||||
.\"
|
||||
.\" The GNU General Public License's references to "object code"
|
||||
.\" and "executables" are to be interpreted as the output of any
|
||||
.\" document formatting or typesetting system, including
|
||||
.\" intermediate and printed output.
|
||||
.\"
|
||||
.\" This manual 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 manual; if not, write to the Free
|
||||
.\" Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
.\" 02111-1307, USA.
|
||||
.\"
|
||||
.\" $Id: ucf.conf.5,v 1.2 2002/02/25 18:07:21 srivasta Exp $
|
||||
.\"
|
||||
.TH UCF.CONF 5 "Feb 12 2002" "Debian" "Debian GNU/Linux manual"
|
||||
.SH NAME
|
||||
ucf.conf \- site\-wide configuration file for
|
||||
.B ucf
|
||||
.SH SYNOPSIS
|
||||
.I /etc/ucf.conf
|
||||
.SH "DESCRIPTION"
|
||||
The file
|
||||
.I /etc/ucf.conf
|
||||
is actually a
|
||||
.BR "Bourne Shell"
|
||||
snippet included during the package build process, and hence you may
|
||||
put any shell directive in that file (just make very sure you know
|
||||
what you are doing).
|
||||
.PP
|
||||
All the variables have reasonable default values, and some may be
|
||||
overridden on a per run or a per individual basis by using
|
||||
environment variables, and all configurable variables can be
|
||||
overridden by options to the scripts themselves.
|
||||
.PP
|
||||
The value of a variable can be set so:
|
||||
.TP 3
|
||||
a)
|
||||
Defaults exist in the rules file. These are the values used if no
|
||||
customization is done.
|
||||
.IP b)
|
||||
Some variables can be set in the config file
|
||||
.I /etc/ucf.conf.
|
||||
These values override the defaults.
|
||||
.IP c)
|
||||
Some variables can also be set by setting a corresponding environment
|
||||
variable. These values override the config file and the defaults.
|
||||
.IP d)
|
||||
Using script command line
|
||||
options. All configurable variables may be set by this method, and
|
||||
will override the other methods above.
|
||||
.SH "Configuration File options"
|
||||
At the moment, the user modifiable variables supported are:
|
||||
.TP 18
|
||||
.B DEBUG
|
||||
Debugging information: The default value is 0 (no debugging
|
||||
information is printed). To enable debugging output, set the value to
|
||||
1.
|
||||
.TP
|
||||
.B VERBOSE
|
||||
Verbosity: The default value is 0 (quiet). To change the default
|
||||
behavior, set the value to 1.
|
||||
.TP
|
||||
.B conf_force_conffold
|
||||
Force the installed file to be retained. The default is to have this
|
||||
variable unset, which makes the script ask in case of doubt. This can
|
||||
be overridden by the environment variable
|
||||
.B UCF_FORCE_CONFFOLD
|
||||
.TP
|
||||
.B conf_force_conffnew
|
||||
Force the installed file to be overridden. The default is to have this
|
||||
variable unset, which makes the script ask in case of doubt. This can
|
||||
be overridden by the environment variable
|
||||
.B UCF_FORCE_CONFFNEW
|
||||
.TP
|
||||
.B conf_source_dir
|
||||
This is the directory where the historical md5sums for a file are
|
||||
looked for. Specifically, the historical md5sums are looked for in
|
||||
either the file
|
||||
.I ${filename}.md5sum,
|
||||
or the subdirectory
|
||||
.I ${filename}.md5sum.d/
|
||||
.TP
|
||||
.B conf_old_mdsum_file
|
||||
Force the historical md5sums to be read from this file, rather than
|
||||
defaulting to living in the source directory. Setting this option
|
||||
overrides settings in the environment variable
|
||||
.B UCF_OLD_MDSUM_FILE
|
||||
.SH Files
|
||||
System\-wide defaults are placed in
|
||||
.I /etc/ucf.conf,
|
||||
.SH "SEE ALSO"
|
||||
.BR ucf (1),
|
||||
.SH BUGS
|
||||
There are no bugs. Any resemblance thereof is delirium. Really.
|
||||
.SH AUTHOR
|
||||
This manual page was written by Manoj Srivastava <srivasta@debian.org>,
|
||||
for the Debian GNU/Linux system.
|
||||
|
|
@ -0,0 +1,851 @@
|
|||
#!/usr/bin/perl
|
||||
# -*- Mode: Cperl -*-
|
||||
# ucfq ---
|
||||
# Author : Manoj Srivastava ( srivasta@glaurung.internal.golden-gryphon.com )
|
||||
# Created On : Wed Apr 12 14:51:16 2006
|
||||
# Created On Node : glaurung.internal.golden-gryphon.com
|
||||
# Last Modified By : Manoj Srivastava
|
||||
# Last Modified On : Fri Apr 14 19:30:45 2006
|
||||
# Last Machine Used: glaurung.internal.golden-gryphon.com
|
||||
# Update Count : 81
|
||||
# Status : Unknown, Use with caution!
|
||||
# HISTORY :
|
||||
# Description :
|
||||
#
|
||||
# arch-tag: 1390e09f-ee31-4d7f-a968-bd539ea061a0
|
||||
#
|
||||
=head1 NAME
|
||||
|
||||
ucfq - query ucf registry and hashfile about configuration file details.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
|
||||
|
||||
package ucf;
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
|
||||
# set the version and revision
|
||||
($main::MYNAME = $main::0) =~ s|.*/||;
|
||||
$main::Author = "Manoj Srivastava";
|
||||
$main::AuthorMail = "srivasta\@debian.org";
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
usage: ucfq [options] (file|package)[file|package ...]
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
{ # scope for ultra-private meta-object for class attributes
|
||||
|
||||
my %Ucf =
|
||||
(
|
||||
Optdesc =>
|
||||
{
|
||||
'help|h' => sub {print ucf->Usage(); exit 0;},
|
||||
'with-colons|w!' => sub {$::ConfOpts{"Colons"}= "$_[1]";},
|
||||
'state-dir=s' => sub {$::ConfOpts{"StateDir"}= "$_[1]";},
|
||||
'debug|d' => sub {$::ConfOpts{"DEBUG"}+= "$_[1]";},
|
||||
'verbose|v' => sub {$::ConfOpts{"VERBOSE"}+= "$_[1]";}
|
||||
},
|
||||
Usage => qq(Usage: $main::MYNAME [options]
|
||||
Author: $main::Author <$main::AuthorMail>
|
||||
where options are:
|
||||
--help This message.
|
||||
--debug Turn on debugging mode.
|
||||
--verbose Make the script more verbose.
|
||||
--with-colons A compact, machine readable version of the output.
|
||||
--state-dir </path/> Set the state directory to /path/ instead of the
|
||||
default /var/lib/ucf.
|
||||
|
||||
),
|
||||
Defaults =>
|
||||
{
|
||||
"Colons" => 0,
|
||||
"DEBUG" => 0,
|
||||
"VERBOSE" => 0,
|
||||
"StateDir" => '/var/lib/ucf'
|
||||
}
|
||||
);
|
||||
# tri-natured: function, class method, or object method
|
||||
sub _classobj {
|
||||
my $obclass = shift || __PACKAGE__;
|
||||
my $class = ref($obclass) || $obclass;
|
||||
no strict "refs"; # to convert sym ref to real one
|
||||
return \%$class;
|
||||
}
|
||||
|
||||
for my $datum (keys %Ucf ) {
|
||||
no strict "refs";
|
||||
*$datum = sub {
|
||||
use strict "refs";
|
||||
my ($self, $newvalue) = @_;
|
||||
$Ucf{$datum} = $newvalue if @_ > 1;
|
||||
return $Ucf{$datum};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 3
|
||||
|
||||
=item B<--help> B<h> Print out a usage message.
|
||||
|
||||
=item B<--debug> B<-d> Turn on debugging mode.
|
||||
|
||||
=item B<--verbose> B<-v> Make the script more verbose..
|
||||
|
||||
=item B<--with-colons> B<-w>
|
||||
|
||||
=over 2
|
||||
|
||||
Normally, the script presents the information in a human readable
|
||||
tabular format, but that may be harder for a machine to parse. With
|
||||
this option, the output is a compact, colon separated line, with no
|
||||
dividers, headers, or footer.
|
||||
|
||||
=back
|
||||
|
||||
=item B<--state-dr> dir
|
||||
|
||||
=over 2
|
||||
|
||||
Set the state directory to C</path/to/dir> instead of the default
|
||||
C</var/lib/ucf>. Used mostly for testing.
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
This script takes a set of arguments, each of which is a package or a
|
||||
path to a configuration file, and outputs the associated package, if
|
||||
any, if the file exists on disk, and whether it has been modfied by te
|
||||
user. The output is either a human readable tabular form, or a
|
||||
compact colon-separated machine friendly format.
|
||||
|
||||
This script can potentially be used in package C<postinst> scripts
|
||||
during purge to query the system for configuration files that may
|
||||
still exist on the system, and whether these files have been locally
|
||||
modified by the user -- assuming that the package registered all the
|
||||
configuration files with B<ucf> using C<ucfr>.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 INTERNALS
|
||||
|
||||
=head2 Class Methods
|
||||
|
||||
All class methods mediate access to class variables. All class
|
||||
methods can be invoked with zero or one parameters. When invoked with
|
||||
the optional parameter, the class method sets the value of the
|
||||
underlying class data. In either case, the value of the underlying
|
||||
variable is returned.
|
||||
|
||||
=cut
|
||||
|
||||
=head1 Class ucf
|
||||
|
||||
This is a combination view and controller class that mediates between
|
||||
the user and the internal model classes.
|
||||
|
||||
|
||||
=head2 new
|
||||
|
||||
This is the constructor for the class. It takes a number of optional
|
||||
parameters. If the parameter B<Colons> is present, then the output
|
||||
will be compact. The parameters B<DEBUG> and B<VERBOSE> turn on
|
||||
additional diagnostics from the script.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $this = shift;
|
||||
my %params = @_;
|
||||
my $class = ref($this) || $this;
|
||||
my $self = {};
|
||||
|
||||
bless $self => $class;
|
||||
|
||||
# validate and sanitize the settings
|
||||
$self->validate(%params);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 validate
|
||||
|
||||
This routine is responsible for ensuring that the parameters passed in
|
||||
(presumably from the command line) are given preference.
|
||||
|
||||
=cut
|
||||
|
||||
sub validate{
|
||||
my $this = shift;
|
||||
my %params = @_;
|
||||
my $defaults = $this->Defaults();
|
||||
|
||||
|
||||
# Make sure runtime options override what we get from the config file
|
||||
for my $option (keys %params) {
|
||||
$this->{Con_Ref}->{"$option"} = $params{"$option"};
|
||||
}
|
||||
|
||||
# Ensure that if default parameters have not been set on the comman
|
||||
# line on in the configuration file, if any, we use the built in
|
||||
# defaults.
|
||||
for my $default (keys %$defaults) {
|
||||
if (! defined $this->{Con_Ref}->{"$default"}) {
|
||||
$this->{Con_Ref}->{"$default"} = $defaults->{"$default"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=head2 get_config_ref
|
||||
|
||||
This routine returns a reference to the configuration hash
|
||||
|
||||
=cut
|
||||
|
||||
sub get_config_ref {
|
||||
|
||||
my $this = shift;
|
||||
return $this->{Con_Ref};
|
||||
}
|
||||
|
||||
=head2 dump_config
|
||||
|
||||
This routine returns a C<Data::Dumper> for debugging purposes
|
||||
|
||||
=cut
|
||||
|
||||
sub dump_config {
|
||||
my $this = shift;
|
||||
for (keys %{$this->{Con_Ref}}) {
|
||||
print "$_ = [${$this->{Con_Ref}}{$_}]\n"
|
||||
}
|
||||
}
|
||||
|
||||
=head2 process
|
||||
|
||||
This routine is the work horse routine -- it parses the command line
|
||||
arguments, and queries the on disk databases, determines of the files
|
||||
exist, and have been modified.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
sub process {
|
||||
my $this = shift;
|
||||
|
||||
# Step 1: Process all arguments in sequence.
|
||||
# Step 2: determine if the arument given is a package name (no / in
|
||||
# arg)
|
||||
|
||||
%{$this->{packages}} = map { +"$_" => 1} grep {! m,/,} @ARGV;
|
||||
%{$this->{configs}} = map { +"$_" => 1} grep { m,/,} @ARGV;
|
||||
$this->{pkg_list} = object_list->new;
|
||||
$this->{file_list} = object_list->new;
|
||||
$this->{registry_proxy} =
|
||||
registry->new("StateDir" => $this->{Con_Ref}->{StateDir});
|
||||
$this->{hashfile_proxy} =
|
||||
hashfile->new("StateDir" => $this->{Con_Ref}->{StateDir});
|
||||
|
||||
for (keys %{$this->{packages}} ) {
|
||||
my $package = pkg->new('Name' => "$_");
|
||||
$this->{pkg_list}->element($_, $package);
|
||||
}
|
||||
for (keys %{$this->{configs}}) {
|
||||
warn "Need a fully qualified path name for config file \"$_\"\n"
|
||||
unless m,^/,;
|
||||
# Don't die for etch
|
||||
exit 0 unless m,^/,;
|
||||
|
||||
my $file = conffile->new('Name' => "$_");
|
||||
$this->{file_list}->element($_, $file);
|
||||
}
|
||||
# Step 3: If so, gather all files associated with the package
|
||||
for my $package ($this->{pkg_list}->list) {
|
||||
my $pkg_files = $this->{registry_proxy}->list_files($package);
|
||||
for my $file (@$pkg_files) {
|
||||
if (! defined $this->{file_list}->element($file)) {
|
||||
my $ret = conffile->new('Name' => "$file");
|
||||
$this->{file_list}->element($file, $ret);
|
||||
}
|
||||
$this->{file_list}->element($file)->conffile_package($package);
|
||||
}
|
||||
}
|
||||
# Step 4: for all configuration files, determine package (unless
|
||||
# already determined), if any
|
||||
# Step 5: For each configuration file, check if it exists
|
||||
# Step 6: For each existing file, see if it has been changed
|
||||
|
||||
for my $file ($this->{file_list}->list) {
|
||||
$this->{file_list}->element($file)->conffile_hash($file, $this->{hashfile_proxy}->hash($file));
|
||||
if (! defined $this->{file_list}->element($file)->conffile_package) {
|
||||
$this->{file_list}->element($file)->conffile_package($this->{registry_proxy}->find_pkg($file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=head2 report
|
||||
|
||||
This routine generates a nicely formatted report based on the
|
||||
information gathered during the processing. There are two kinds of
|
||||
reports, the first being a user friendly tabular form, the second
|
||||
(turned on by the C<-w> option) a easily parseable colon separated
|
||||
report.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
our ($out_pkg, $out_file, $there, $mod);
|
||||
|
||||
format STDOUT_TOP =
|
||||
Configuration file Package Exists Changed
|
||||
.
|
||||
|
||||
format STDOUT =
|
||||
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<< @||| @|||
|
||||
$out_file, $out_pkg, $there,$mod
|
||||
.
|
||||
|
||||
sub report {
|
||||
my $this = shift;
|
||||
for my $file (sort $this->{file_list}->list) {
|
||||
($out_pkg, $out_file, $there, $mod) =
|
||||
$this->{file_list}->element($file)->conffile_report;
|
||||
if ($this->{Con_Ref}->{Colons}) {
|
||||
print "$out_file:$out_pkg:$there:$mod\n";
|
||||
}
|
||||
else {
|
||||
write;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=head1 Class registry
|
||||
|
||||
This moel class encapsulates the package-configuration file
|
||||
associations registry. It parses the data in the registry, and
|
||||
provides methods to query the registry based either on package name,
|
||||
or the full path of the configuration file.
|
||||
|
||||
=cut
|
||||
|
||||
package registry;
|
||||
use strict;
|
||||
|
||||
=head2 new
|
||||
|
||||
This is the constructor for the class. It takes a required parameter
|
||||
B<StateDir>, and based on that, proceeds toparse the registry and
|
||||
populate internal data structures.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $this = shift;
|
||||
my %params = @_;
|
||||
my $class = ref($this) || $this;
|
||||
my $self = {};
|
||||
|
||||
die "Missing required parameter StateDir"
|
||||
unless $params{StateDir};
|
||||
|
||||
if (-e "$params{StateDir}/registry") {
|
||||
if (! -r "$params{StateDir}/registry") {
|
||||
die "Can't read registry file $params{StateDir}/registry:$!";
|
||||
}
|
||||
open (REG, "$params{StateDir}/registry") ||
|
||||
die "Can't read registry file $params{StateDir}/registry:$!";
|
||||
while (<REG>) {
|
||||
chomp;
|
||||
my ($pkg, $file) = m/^(\S+)\s+(\S+)$/;
|
||||
$self->{Packages}->{$file} = $pkg;
|
||||
if (exists $self->{List}->{$pkg}) {
|
||||
push @{$self->{List}->{$pkg}}, $file;
|
||||
}
|
||||
else {
|
||||
$self->{List}->{$pkg} = [ $file ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bless $self => $class;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 list_files
|
||||
|
||||
This routine queries the registry and lists all configuration files
|
||||
associated with the given package. Takes the package name as a
|
||||
required parameter.
|
||||
|
||||
=cut
|
||||
|
||||
sub list_files {
|
||||
my $this = shift;
|
||||
my $pkg = shift;
|
||||
|
||||
if (exists $this->{List}->{$pkg}) {
|
||||
return [ @{$this->{List}->{$pkg}} ];
|
||||
}
|
||||
else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
=head2 find_pkg
|
||||
|
||||
This routine queries the registry for the package associated with the
|
||||
given file. Takes the path of the configuration file as a required
|
||||
parameter.
|
||||
|
||||
=cut
|
||||
|
||||
sub find_pkg {
|
||||
my $this = shift;
|
||||
my $file = shift;
|
||||
|
||||
if (exists $this->{Packages}->{$file}) {
|
||||
return $this->{Packages}->{$file};
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
=head1 Class hashfile
|
||||
|
||||
This moel class encapsulates the configuration file hash database. It
|
||||
parses the data in the database, and provides methods to query the
|
||||
hash of the configuration file.
|
||||
|
||||
=cut
|
||||
|
||||
package hashfile;
|
||||
use strict;
|
||||
|
||||
sub new {
|
||||
my $this = shift;
|
||||
my %params = @_;
|
||||
my $class = ref($this) || $this;
|
||||
my $self = {};
|
||||
|
||||
die "Missing required parameter StateDir"
|
||||
unless $params{StateDir};
|
||||
|
||||
|
||||
if (-e "$params{StateDir}/hashfile") {
|
||||
if (! -r "$params{StateDir}/hashfile") {
|
||||
die "Can't read registry file $params{StateDir}/hashfile:$!";
|
||||
}
|
||||
open (HASH, "$params{StateDir}/hashfile") ||
|
||||
die "Can't read registry file $params{StateDir}/hashfile:$!";
|
||||
while (<HASH>) {
|
||||
chomp;
|
||||
my ($hash, $file) = m/^(\S+)\s+(\S+)$/;
|
||||
$self->{$file} = $hash
|
||||
}
|
||||
}
|
||||
|
||||
bless $self => $class;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
=head2 hash
|
||||
|
||||
This routine queries the database for the hash associated with the
|
||||
developers version of the given file. Takes the path of the
|
||||
configuration file as a required parameter.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
sub hash {
|
||||
my $this = shift;
|
||||
my $file = shift;
|
||||
my $value = shift;
|
||||
|
||||
if ($value) {
|
||||
$this->{$file} = $value;
|
||||
}
|
||||
return $this->{$file};
|
||||
}
|
||||
|
||||
=head1 class conffile
|
||||
|
||||
This is the encapsulation of a configuration file metadata.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
package conffile;
|
||||
use strict;
|
||||
use Cwd qw{abs_path};
|
||||
|
||||
|
||||
=head2 new
|
||||
|
||||
This is the constructor for the class. It takes a number of optional
|
||||
parameters. If the parameter B<Colons> is present, then the output
|
||||
will be compact. The parameters B<DEBUG> and B<VERBOSE> turn on
|
||||
additional diagnostics from the script.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $this = shift;
|
||||
my %params = @_;
|
||||
my $class = ref($this) || $this;
|
||||
my $self = {};
|
||||
|
||||
die "Missing required parameter Name"
|
||||
unless $params{Name};
|
||||
$self->{Name} = $params{Name};
|
||||
$self->{Package} = $params{Package}
|
||||
if $params{Package};
|
||||
$self->{Exists} = 'Yes' if -e $self->{Name};
|
||||
if ($self->{Exists}) {
|
||||
$self->{Name} = abs_path( $self->{Name});
|
||||
}
|
||||
bless $self => $class;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
=head2 conffile_package
|
||||
|
||||
This routine is the accessor method of the internal attribute that
|
||||
holds package name associated with the file. If an optional C<value>
|
||||
is present, updates the value of the attribute.
|
||||
|
||||
=cut
|
||||
|
||||
sub conffile_package {
|
||||
my $this = shift;
|
||||
my $value = shift;
|
||||
|
||||
if ($value ) {
|
||||
$this->{Package} = $value;
|
||||
}
|
||||
if (exists $this->{Package}) {
|
||||
return $this->{Package};
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
=head2 conffile_exists
|
||||
|
||||
This routine is the accessor method of the internal attribute that
|
||||
holds the information whether the file exists on disk or not.
|
||||
|
||||
=cut
|
||||
|
||||
sub conffile_exists {
|
||||
my $this = shift;
|
||||
my $name = shift;
|
||||
my $value = shift;
|
||||
|
||||
die "Missing required parameter Name"
|
||||
unless $name;
|
||||
if (exists $this->{Exists}) {
|
||||
return $this->{Exists};
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
=head2 conffile_modified
|
||||
|
||||
This routine is the accessor method of the internal attribute that
|
||||
holds the information whether the file exists on disk or not. If an
|
||||
optional C<value> is present, updates the value of the attribute.
|
||||
|
||||
=cut
|
||||
|
||||
sub conffile_modified {
|
||||
my $this = shift;
|
||||
my $name = shift;
|
||||
my $value = shift;
|
||||
|
||||
die "Missing required parameter Name"
|
||||
unless $name;
|
||||
if ($value ) {
|
||||
$this->{Modified} = $value;
|
||||
}
|
||||
if (exists $this->{Modified}) {
|
||||
return $this->{Modified};
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
=head2 conffile_hash
|
||||
|
||||
This routine is the accessor method of the internal attribute that
|
||||
holds the hash for the developers version of the file. If an optional
|
||||
C<value> is present, updates the value of the attribute. It also
|
||||
notes whether or not the file is modified from the developers version.
|
||||
|
||||
=cut
|
||||
|
||||
sub conffile_hash {
|
||||
my $this = shift;
|
||||
my $name = shift;
|
||||
my $value = shift;
|
||||
|
||||
die "Missing required parameter Name"
|
||||
unless $name;
|
||||
if ($value ) {
|
||||
$this->{Hash} = $value;
|
||||
if (-e "$name") {
|
||||
if (-x "/usr/bin/md5sum") {
|
||||
open (NEWHASH, "/usr/bin/md5sum $name |") ||
|
||||
die "Could not run md5sum: $!";
|
||||
while (<NEWHASH>) {
|
||||
chomp;
|
||||
my ($hash, $dummy) = m/^(\S+)\s+(\S+)$/;
|
||||
if ("$hash" ne "$value") {
|
||||
$this->{Modified} = 'Yes';
|
||||
}
|
||||
else {
|
||||
$this->{Modified} = 'No';
|
||||
}
|
||||
}
|
||||
close NEWHASH;
|
||||
}
|
||||
else {
|
||||
die "Could not find /usr/bin/md5sum .\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (exists $this->{Hash}) {
|
||||
return $this->{Hash};
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
sub conffile_report {
|
||||
my $this = shift;
|
||||
return $this->{Package} ? $this->{Package} : "",
|
||||
$this->{Name}, $this->{Exists} ? $this->{Exists} : "",
|
||||
$this->{Modified}? $this->{Modified} : "";
|
||||
}
|
||||
|
||||
|
||||
=head1 CLASS PKG
|
||||
|
||||
This is an encapsulation of package metadata. Packages may be
|
||||
associated with configuration files.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
package pkg;
|
||||
use strict;
|
||||
|
||||
|
||||
=head2 new
|
||||
|
||||
This is the constructor for the class. It takes a number of optional
|
||||
parameters. If the parameter B<Colons> is present, then the output
|
||||
will be compact. The parameters B<DEBUG> and B<VERBOSE> turn on
|
||||
additional diagnostics from the script.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $this = shift;
|
||||
my %params = @_;
|
||||
my $class = ref($this) || $this;
|
||||
my $self = {};
|
||||
|
||||
die "Missing required parameter Name"
|
||||
unless $params{Name};
|
||||
$self->{Name} = $params{Name};
|
||||
|
||||
bless $self => $class;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub list_files {
|
||||
my $this = shift;
|
||||
return [];
|
||||
}
|
||||
|
||||
=head1 CLASS object_list
|
||||
|
||||
This is a clas which holds lists of object names, either packages or
|
||||
configuration file object names. It provides methods to add, access,
|
||||
and remove objects, as well as an option to list all elements in the
|
||||
list.
|
||||
|
||||
=cut
|
||||
|
||||
package object_list;
|
||||
use strict;
|
||||
|
||||
|
||||
|
||||
=head2 new
|
||||
|
||||
This is the constructor for the class. It takes no arguments.
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $this = shift;
|
||||
my %params = @_;
|
||||
my $class = ref($this) || $this;
|
||||
my $self = {};
|
||||
|
||||
$self->{"List"} = ();
|
||||
|
||||
bless $self => $class;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 element
|
||||
|
||||
This is an accessor method for elements of the list. If an optional
|
||||
value argument exists, it creates or updates the element associtated
|
||||
with the vaslue. Takes in a required name, which is used as a kay, and
|
||||
an optional value argument. The value is returned.
|
||||
|
||||
=cut
|
||||
|
||||
sub element {
|
||||
my $this = shift;
|
||||
my $name = shift;
|
||||
my $value = shift;
|
||||
|
||||
die "Missing required parameter Name"
|
||||
unless $name;
|
||||
if ($value) {
|
||||
$this->{"List"}->{$name} = $value;
|
||||
}
|
||||
if (exists $this->{"List"}->{$name}) {
|
||||
return $this->{"List"}->{$name};
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
=head2 remove
|
||||
|
||||
Removes elements from the list. Take in an required name, which is
|
||||
used as the key for the element to delete.
|
||||
|
||||
=cut
|
||||
|
||||
sub remove {
|
||||
my $this = shift;
|
||||
my $name = shift;
|
||||
die "Missing required parameter Name"
|
||||
unless $name;
|
||||
delete $this->{"List"}->{$name}
|
||||
if (exists $this->{"List"}->{$name} );
|
||||
}
|
||||
|
||||
=head2 list
|
||||
|
||||
This routine lists all the elements in the list. It does not take any
|
||||
options.
|
||||
|
||||
=cut
|
||||
|
||||
sub list {
|
||||
my $this = shift;
|
||||
|
||||
return keys %{$this->{"List"}};
|
||||
}
|
||||
|
||||
package main;
|
||||
use Getopt::Long;
|
||||
|
||||
sub main {
|
||||
my $optdesc = ucf->Optdesc();
|
||||
my $parser = new Getopt::Long::Parser;
|
||||
$parser->configure("bundling");
|
||||
$parser->getoptions (%$optdesc);
|
||||
my $query = ucf->new(%::ConfOpts);
|
||||
$query->process;
|
||||
$query->report;
|
||||
}
|
||||
|
||||
&main;
|
||||
|
||||
exit 0;
|
||||
|
||||
=head1 CAVEATS
|
||||
|
||||
This is very inchoate, at the moment, and needs testing.
|
||||
|
||||
=cut
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None Known so far.
|
||||
|
||||
=cut
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Manoj Srivastava <srivasta\@debian.org>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This script is a part of the Ucf package, and is
|
||||
|
||||
Copyright (c) 2006 Manoj Srivastava <srivasta\@debian.org>
|
||||
|
||||
This program is free software; you can redistribute it and / or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
|
@ -0,0 +1,235 @@
|
|||
.\" -*- Mode: Nroff -*-
|
||||
.\" ucfq.1 ---
|
||||
.\" Author : Manoj Srivastava ( srivasta@glaurung.internal.golden-gryphon.com )
|
||||
.\" Created On : Sun Apr 16 16:29:21 2006
|
||||
.\" Created On Node : glaurung.internal.golden-gryphon.com
|
||||
.\" Last Modified By : Manoj Srivastava
|
||||
.\" Last Modified On : Sun Apr 16 16:31:08 2006
|
||||
.\" Last Machine Used: glaurung.internal.golden-gryphon.com
|
||||
.\" Update Count : 2
|
||||
.\" Status : Unknown, Use with caution!
|
||||
.\" HISTORY :
|
||||
.\" Description :
|
||||
.\"
|
||||
.\" arch-tag: daf13e00-a69c-45f0-80a1-b6f3b8bdb14b
|
||||
.\"
|
||||
.\" Copyright (c) 2006 Manoj Srivastava <srivasta@debian.org>
|
||||
.\"
|
||||
.\" This is free documentation; 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.
|
||||
.\"
|
||||
.\" The GNU General Public License's references to "object code"
|
||||
.\" and "executables" are to be interpreted as the output of any
|
||||
.\" document formatting or typesetting system, including
|
||||
.\" intermediate and printed output.
|
||||
.\"
|
||||
.\" This manual 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 manual; if not, write to the Free
|
||||
.\" Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
.\" 02111-1307, USA.
|
||||
.\"
|
||||
|
||||
.\" ========================================================================
|
||||
.de Sh \" Subsection heading
|
||||
.br
|
||||
.if t .Sp
|
||||
.ne 5
|
||||
.PP
|
||||
\fB\\$1\fR
|
||||
.PP
|
||||
..
|
||||
.de Sp \" Vertical space (when we can't use .PP)
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.de Vb \" Begin verbatim text
|
||||
.ft CW
|
||||
.nf
|
||||
.ne \\$1
|
||||
..
|
||||
.de Ve \" End verbatim text
|
||||
.ft R
|
||||
.fi
|
||||
..
|
||||
.\" Set up some character translations and predefined strings. \*(-- will
|
||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
||||
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
||||
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
||||
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
||||
.\" nothing in troff, for use with C<>.
|
||||
.tr \(*W-
|
||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
||||
.ie n \{\
|
||||
. ds -- \(*W-
|
||||
. ds PI pi
|
||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||
. ds L" ""
|
||||
. ds R" ""
|
||||
. ds C` ""
|
||||
. ds C' ""
|
||||
'br\}
|
||||
.el\{\
|
||||
. ds -- \|\(em\|
|
||||
. ds PI \(*p
|
||||
. ds L" ``
|
||||
. ds R" ''
|
||||
'br\}
|
||||
.\"
|
||||
.\" If the F register is turned on, we'll generate index entries on stderr for
|
||||
.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
|
||||
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
||||
.\" output yourself in some meaningful fashion.
|
||||
.if \nF \{\
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
..
|
||||
. nr % 0
|
||||
. rr F
|
||||
.\}
|
||||
.\"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.hy 0
|
||||
.if n .na
|
||||
.\"
|
||||
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
||||
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
||||
. \" fudge factors for nroff and troff
|
||||
.if n \{\
|
||||
. ds #H 0
|
||||
. ds #V .8m
|
||||
. ds #F .3m
|
||||
. ds #[ \f1
|
||||
. ds #] \fP
|
||||
.\}
|
||||
.if t \{\
|
||||
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
|
||||
. ds #V .6m
|
||||
. ds #F 0
|
||||
. ds #[ \&
|
||||
. ds #] \&
|
||||
.\}
|
||||
. \" simple accents for nroff and troff
|
||||
.if n \{\
|
||||
. ds ' \&
|
||||
. ds ` \&
|
||||
. ds ^ \&
|
||||
. ds , \&
|
||||
. ds ~ ~
|
||||
. ds /
|
||||
.\}
|
||||
.if t \{\
|
||||
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
|
||||
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
|
||||
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
|
||||
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
|
||||
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
|
||||
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
|
||||
.\}
|
||||
. \" troff and (daisy-wheel) nroff accents
|
||||
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
|
||||
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
|
||||
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
|
||||
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
|
||||
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
|
||||
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
|
||||
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
|
||||
.ds ae a\h'-(\w'a'u*4/10)'e
|
||||
.ds Ae A\h'-(\w'A'u*4/10)'E
|
||||
. \" corrections for vroff
|
||||
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
|
||||
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
|
||||
. \" for low resolution devices (crt and lpr)
|
||||
.if \n(.H>23 .if \n(.V>19 \
|
||||
\{\
|
||||
. ds : e
|
||||
. ds 8 ss
|
||||
. ds o a
|
||||
. ds d- d\h'-1'\(ga
|
||||
. ds D- D\h'-1'\(hy
|
||||
. ds th \o'bp'
|
||||
. ds Th \o'LP'
|
||||
. ds ae ae
|
||||
. ds Ae AE
|
||||
.\}
|
||||
.rm #[ #] #H #V #F C
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.TH UCFQ 1 "2006-04-16" "perl v5.8.8" "User Contributed Perl Documentation"
|
||||
.SH NAME
|
||||
ucfq \- query the ucf database
|
||||
.SH "SYNOPSIS"
|
||||
.Vb 1
|
||||
\& usage: ucfq [options] (/path/to/file|package)[/path/to/file|package ...]
|
||||
.Ve
|
||||
.SH "OPTIONS"
|
||||
.IP "\fB\-\-help\fR \fBh\fR Print out a usage message." 3
|
||||
.PD 0
|
||||
.IP "\fB\-\-debug\fR \fB\-d\fR Turn on debugging mode." 3
|
||||
.IP "\fB\-\-verbose\fR \fB\-v\fR Make the script more verbose.." 3
|
||||
.IP "\fB\-\-with\-colons\fR \fB\-w\fR" 3
|
||||
.RS 3
|
||||
.PD
|
||||
.RS 2
|
||||
Normally, the script presents the information in a human readable
|
||||
tabular format, but that may be harder for a machine to parse. With
|
||||
this option, the output is a compact, colon separated line, with no
|
||||
dividers, headers, or footer.
|
||||
.RE
|
||||
.RE
|
||||
.RS 3
|
||||
.RE
|
||||
.IP "\fB\-\-state\-dr\fR dir" 3
|
||||
.RS 3
|
||||
.RS 2
|
||||
Set the state directory to \f(CW\*(C`/path/to/dir\*(C'\fR instead of the default
|
||||
\&\f(CW\*(C`/var/lib/ucf\*(C'\fR. Used mostly for testing.
|
||||
.RE
|
||||
.RE
|
||||
.RS 3
|
||||
.RE
|
||||
.SH "DESCRIPTION"
|
||||
This script takes a set of arguments, each of which is a package name
|
||||
(and thus does not contain a /) or a full path to a configuration
|
||||
file, and outputs the associated package, if any, if the file exists
|
||||
on disk, and whether it has been modified by the user. The output is
|
||||
either a human readable tabular form, or a compact colon-separated
|
||||
machine friendly format.
|
||||
.PP
|
||||
This script can potentially be used in package \f(CW\*(C`postrm\*(C'\fR scripts
|
||||
during purge to query the system for configuration files that may
|
||||
still exist on the system, and whether these files have been locally
|
||||
modified by the user \*(-- assuming that the package registered all the
|
||||
configuration files with \fBucf\fR using \f(CW\*(C`ucfr\*(C'\fR.
|
||||
.SH "CAVEATS"
|
||||
This is very inchoate, at the moment, and needs testing.
|
||||
.SH "BUGS"
|
||||
None Known so far.
|
||||
.SH "AUTHOR"
|
||||
Manoj Srivastava <srivasta\e@debian.org>
|
||||
.SH "COPYRIGHT AND LICENSE"
|
||||
This script is a part of the Ucf package, and is
|
||||
.PP
|
||||
Copyright (c) 2006 Manoj Srivastava <srivasta\e@debian.org>
|
||||
.PP
|
||||
This program is free software; you can redistribute it and / or modify
|
||||
it under the terms of the \s-1GNU\s0 General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.PP
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but \s-1WITHOUT\s0 \s-1ANY\s0 \s-1WARRANTY\s0; without even the implied warranty of
|
||||
\&\s-1MERCHANTABILITY\s0 or \s-1FITNESS\s0 \s-1FOR\s0 A \s-1PARTICULAR\s0 \s-1PURPOSE\s0. See the
|
||||
\&\s-1GNU\s0 General Public License for more details.
|
||||
.PP
|
||||
You should have received a copy of the \s-1GNU\s0 General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, \s-1MA\s0 02111\-1307 \s-1USA\s0
|
|
@ -0,0 +1,336 @@
|
|||
#! /bin/bash
|
||||
# -*- Mode: Sh -*-
|
||||
# ucfr ---
|
||||
# Author : Manoj Srivastava ( srivasta@glaurung.internal.golden-gryphon.com )
|
||||
# Created On : Tue Apr 11 11:09:15 2006
|
||||
# Created On Node : glaurung.internal.golden-gryphon.com
|
||||
# Last Modified By : Manoj Srivastava
|
||||
# Last Modified On : Tue Apr 11 13:50:58 2006
|
||||
# Last Machine Used: glaurung.internal.golden-gryphon.com
|
||||
# Update Count : 43
|
||||
# Status : Unknown, Use with caution!
|
||||
# HISTORY :
|
||||
# Description :
|
||||
#
|
||||
# Register a configuration file as belonging to a package
|
||||
#
|
||||
# arch-tag: 6e1d33fe-a930-41ce-8d0f-c87f87b19918
|
||||
#
|
||||
|
||||
# make sure we exit on error
|
||||
set -e
|
||||
|
||||
# set the version and revision
|
||||
progname=$(basename "$0")
|
||||
pversion='Revision 3.00'
|
||||
######################################################################
|
||||
######## #########
|
||||
######## Utility functions #########
|
||||
######## #########
|
||||
######################################################################
|
||||
setq() {
|
||||
# Variable Value Doc_string
|
||||
if [ "x$2" = "x" ]; then
|
||||
echo >&2 "$progname: Unable to determine $3"
|
||||
exit 1;
|
||||
else
|
||||
if [ "x$VERBOSE" != "x" ]; then
|
||||
echo >&2 "$progname: $3 is $2";
|
||||
fi
|
||||
eval "$1=\"\$2\"";
|
||||
fi
|
||||
}
|
||||
|
||||
withecho () {
|
||||
echo "$@" >&2
|
||||
"$@"
|
||||
}
|
||||
|
||||
|
||||
purge_from_registry () {
|
||||
if [ ! -e "$statedir/registry" ]; then
|
||||
echo >&2 "$progname: Internal error: $statedir/registry does not exist";
|
||||
exit 6;
|
||||
fi
|
||||
|
||||
if [ "$count" -eq 0 ]; then
|
||||
if [ "X$VERBOSE" != "X" ]; then
|
||||
echo >&2 "$progname: Association already purged. No changes.";
|
||||
fi
|
||||
exit 0;
|
||||
fi
|
||||
old_pkg=$(egrep "[[:space:]]${real_conf_file_re}$" "$statedir/registry" | \
|
||||
awk '{print $1;}' );
|
||||
if [ "$pkg" != "$old_pkg" ]; then
|
||||
echo >&2 "ucfr: Association belongs to $old_pkg, not $pkg";
|
||||
if [ "X$FORCE" = "X" ]; then
|
||||
echo >&2 "ucfr: Aborting";
|
||||
exit 5;
|
||||
fi
|
||||
fi
|
||||
|
||||
# OK, so we have something to purge.
|
||||
for i in $(/usr/bin/seq 6 -1 0); do
|
||||
if [ -e "${statedir}/registry.${i}" ]; then
|
||||
if [ "X$docmd" = "XYES" ]; then
|
||||
cp -f "${statedir}/registry.${i}" "${statedir}/registry.$(($i + 1))"
|
||||
else
|
||||
echo cp -f "${statedir}/registry.${i}" "${statedir}/registry.$(($i + 1))"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [ "X$docmd" = "XYES" ]; then
|
||||
cp -f "$statedir/registry" "$statedir/registry.0"
|
||||
else
|
||||
echo cp -f "$statedir/registry" "$statedir/registry.0"
|
||||
fi
|
||||
if [ "X$docmd" = "XYES" ]; then
|
||||
set +e
|
||||
if [ "X$VERBOSE" != "X" ]; then
|
||||
echo "egrep -v [[:space:]]${real_conf_file_re}$ $statedir/registry >\\"
|
||||
echo " $statedir/registry.tmp || true";
|
||||
fi
|
||||
#echo "egrep -v [[:space:]]${real_conf_file_re}$ $statedir/registry"
|
||||
egrep -v "[[:space:]]${real_conf_file_re}$" "$statedir/registry" > \
|
||||
"$statedir/registry.tmp" || true;
|
||||
if [ "X$docmd" = "XYES" ]; then
|
||||
mv -f "$statedir/registry.tmp" "$statedir/registry"
|
||||
else
|
||||
echo mv -f "$statedir/registry.tmp" "$statedir/registry"
|
||||
fi
|
||||
set -e
|
||||
fi
|
||||
}
|
||||
|
||||
replace_in_registry () {
|
||||
if [ ! -e "$statedir/registry" ]; then
|
||||
echo >&2 "$progname: Internal error: $statedir/registry does not exist";
|
||||
exit 6;
|
||||
fi
|
||||
if [ "$count" -eq 1 ]; then
|
||||
old_pkg=$(egrep "[[:space:]]${real_conf_file_re}$" "$statedir/registry" | \
|
||||
awk '{print $1;}' );
|
||||
|
||||
if [ "$pkg" != "$old_pkg" ]; then
|
||||
if [ "X$FORCE" = "X" ]; then
|
||||
echo >&2 "$progname: Attempt from package $pkg to take ${real_conf_file} away from package $old_pkg";
|
||||
echo >&2 "ucfr: Aborting.";
|
||||
exit 4;
|
||||
fi
|
||||
else
|
||||
if [ "X$VERBOSE" != "X" ]; then
|
||||
echo >&2 "$progname: Association already recorded. No changes.";
|
||||
fi
|
||||
exit 0;
|
||||
fi
|
||||
fi
|
||||
|
||||
for i in $(/usr/bin/seq 6 -1 0); do
|
||||
if [ -e "${statedir}/registry.${i}" ]; then
|
||||
if [ "X$docmd" = "XYES" ]; then
|
||||
cp -f "${statedir}/registry.${i}" \
|
||||
"${statedir}/registry.$(($i + 1))"
|
||||
else
|
||||
echo cp -f "${statedir}/registry.${i}" \
|
||||
"${statedir}/registry.$(($i + 1))"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [ "X$docmd" = "XYES" ]; then
|
||||
cp -f "$statedir/registry" "$statedir/registry.0"
|
||||
else
|
||||
echo cp -f "$statedir/registry" "$statedir/registry.0"
|
||||
fi
|
||||
if [ "X$docmd" = "XYES" ]; then
|
||||
set +e
|
||||
if [ "X$VERBOSE" != "X" ]; then
|
||||
echo "egrep -v \"[[:space:]]${real_conf_file_re}$\" \"$statedir/registry\" \\"
|
||||
echo " $statedir/registry.tmp || true"
|
||||
echo "echo \"$pkg $real_conf_file\" >> \"$statedir/registry.tmp\""
|
||||
echo "mv -f $statedir/registry.tmp $statedir/registry"
|
||||
fi
|
||||
egrep -v "[[:space:]]${real_conf_file_re}$" "$statedir/registry" > \
|
||||
"$statedir/registry.tmp" || true;
|
||||
echo "$pkg $real_conf_file" >> "$statedir/registry.tmp";
|
||||
mv -f "$statedir/registry.tmp" "$statedir/registry"
|
||||
set -e
|
||||
else
|
||||
echo "egrep -v \"[[:space:]]${real_conf_file_re}$\" \"$statedir/registry\" \\"
|
||||
echo " $statedir/registry.tmp || true"
|
||||
echo "echo \"$pkg $real_conf_file\" >> \"$statedir/registry.tmp\""
|
||||
echo "mv -f $statedir/registry.tmp $statedir/registry"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
usageversion () {
|
||||
cat >&2 <<END
|
||||
Debian GNU/Linux $progname $pversion.
|
||||
Copyright (C) 2002-2006 Manoj Srivastava.
|
||||
This is free software; see the GNU General Public Licence for copying
|
||||
conditions. There is NO warranty.
|
||||
|
||||
Usage: $progname [options] package_name path_for_configuration_file
|
||||
Options:
|
||||
-h, --help print this message
|
||||
-f --force Force the association, even if another package
|
||||
used to own the configuration file.
|
||||
-d [n], --debug [n] Set the Debug level to N
|
||||
-n, --no-action Dry run. No action is actually taken.
|
||||
-v, --verbose Make the script verbose
|
||||
-p, --purge Remove any reference to the package/file association
|
||||
from the records
|
||||
--state-dir bar Set the state directory to bar instead of the
|
||||
default '/var/lib/ucf'. Used mostly for testing.
|
||||
END
|
||||
|
||||
}
|
||||
|
||||
######################################################################
|
||||
######## #########
|
||||
######## Command line args #########
|
||||
######## #########
|
||||
######################################################################
|
||||
#
|
||||
# Long term variables#
|
||||
#
|
||||
docmd='YES'
|
||||
action='withecho'
|
||||
action=
|
||||
DEBUG=0
|
||||
VERBOSE=''
|
||||
statedir='/var/lib/ucf';
|
||||
THREEWAY=
|
||||
|
||||
# Note that we use `"$@"' to let each command-line parameter expand to a
|
||||
# separate word. The quotes around `$@' are essential!
|
||||
# We need TEMP as the `eval set --' would nuke the return value of getopt.
|
||||
TEMP=$(getopt -a -o hd::D::fnvp -n "$progname" \
|
||||
--long help,debug::,DEBUG::,force,no-action,purge,verbose,state-dir: \
|
||||
-- "$@")
|
||||
|
||||
if [ $? != 0 ] ; then
|
||||
echo "Error handling options.Terminating..." >&2 ;
|
||||
exit 1 ;
|
||||
fi
|
||||
|
||||
# Note the quotes around `$TEMP': they are essential!
|
||||
eval set -- "$TEMP"
|
||||
|
||||
while true ; do
|
||||
case "$1" in
|
||||
-h|--help) usageversion; exit 0 ;;
|
||||
-n|--no-action) action='echo'; docmd='NO'; shift ;;
|
||||
-v|--verbose) VERBOSE=1; shift ;;
|
||||
-f|--force) FORCE=1; shift ;;
|
||||
--state-dir) opt_state_dir="$2"; shift 2 ;;
|
||||
-D|-d|--debug|--DEBUG)
|
||||
# d has an optional argument. As we are in quoted mode,
|
||||
# an empty parameter will be generated if its optional
|
||||
# argument is not found.
|
||||
case "$2" in
|
||||
"") setq DEBUG 1 "The Debug value"; shift 2 ;;
|
||||
*) setq DEBUG "$2" "The Debug value"; shift 2 ;;
|
||||
esac ;;
|
||||
-p|--purge) PURGE=YES; shift ;;
|
||||
--) shift ; break ;;
|
||||
*) echo >&2 "$progname: Internal error!" ; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
# Need to run as root, or else the
|
||||
if test "$(id -u)" != 0; then
|
||||
if [ "$docmd" = "YES" ]; then
|
||||
echo "$progname: Need to be run as root." >&2
|
||||
echo "$progname: Setting up no action mode." >&2
|
||||
action='echo';
|
||||
docmd='NO';
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $# != 2 ]; then
|
||||
echo >&2 "$progname: *** ERROR: Need exactly two arguments, got $#";
|
||||
echo >&2 ""
|
||||
usageversion;
|
||||
exit 3 ;
|
||||
fi
|
||||
|
||||
# We have here a configuration file, which can be a symlink, and may
|
||||
# contain characters that are unsafe in regular expressions
|
||||
setq pkg "$1" "The Package name";
|
||||
setq conf_file "$2" "The Configuration file";
|
||||
setq real_conf_file "$(readlink -q -m $conf_file)" "The (real) Configuration file";
|
||||
|
||||
pkg_re="$(echo $pkg | sed -e 's,+,\\+,')"
|
||||
conf_file_re="$(echo $conf_file | sed -e 's,+,\\+,')"
|
||||
real_conf_file_re="$(echo $real_conf_file | sed -e 's,+,\\+,')"
|
||||
|
||||
case $conf_file_re in
|
||||
/*)
|
||||
: echo fine
|
||||
;;
|
||||
*)
|
||||
echo >&2 "$progname: Need a fully qualified path for the file \"$conf_file\""
|
||||
# Don't exit with an error for etch'
|
||||
exit 0;
|
||||
esac
|
||||
|
||||
# Load site defaults and over rides.
|
||||
if [ -f /etc/ucf.conf ]; then
|
||||
. /etc/ucf.conf
|
||||
fi
|
||||
|
||||
# Command line, env variable, config file, or default
|
||||
if [ ! "x$opt_state_dir" = "x" ]; then
|
||||
setq statedir "$opt_state_dir" "The State directory"
|
||||
elif [ ! "x$UCF_STATE_DIR" = "x" ]; then
|
||||
setq statedir "$UCF_STATE_DIR" "The State directory"
|
||||
elif [ ! "x$conf_state_dir" = "x" ]; then
|
||||
setq statedir "$conf_state_dir" "The State directory"
|
||||
else
|
||||
setq statedir '/var/lib/ucf' "The State directory"
|
||||
fi
|
||||
|
||||
# VERBOSE of 0 is supposed to be the same as not setting VERBOSE
|
||||
if [ "X$VERBOSE" = "X0" ]; then
|
||||
VERBOSE=''
|
||||
fi
|
||||
|
||||
#
|
||||
if [ -e "$statedir/registry" -a ! -w "$statedir/registry" ]; then
|
||||
echo >&2 "$progname: do not have write privilege to the registry data"
|
||||
if [ "X$docmd" = "XYES" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
# test and see if this file exists in the database
|
||||
if [ ! -d "$statedir" ]; then
|
||||
$action mkdir -p "$statedir"
|
||||
fi
|
||||
|
||||
if [ ! -f "$statedir/registry" ]; then
|
||||
$action touch "$statedir/registry"
|
||||
fi
|
||||
|
||||
|
||||
if [ "X$VERBOSE" != "X" ]; then
|
||||
echo >&2 "$progname: The registry exists"
|
||||
fi
|
||||
|
||||
# sanity check
|
||||
count=$(egrep --count "[[:space:]]${real_conf_file_re}$" "$statedir/registry") || true
|
||||
|
||||
if [ "$count" -ge 2 ]; then
|
||||
echo >&2 "$progname: Corrupt registry: Duplicate entries for ${conf_file}";
|
||||
egrep "[[:space:]]${real_conf_file_re}$" "$statedir/registry";
|
||||
exit "$count";
|
||||
fi
|
||||
|
||||
if [ "X$PURGE" != "X" ]; then
|
||||
$action purge_from_registry
|
||||
else
|
||||
$action replace_in_registry
|
||||
fi
|
||||
|
||||
|
||||
exit 0;
|
|
@ -0,0 +1,175 @@
|
|||
.\" -*- Mode: Nroff -*-
|
||||
.\" ucfr.1 ---
|
||||
.\" Author : Manoj Srivastava ( srivasta@glaurung.internal.golden-gryphon.com )
|
||||
.\" Created On : Tue Apr 11 13:58:23 2006
|
||||
.\" Created On Node : glaurung.internal.golden-gryphon.com
|
||||
.\" Last Modified By : Manoj Srivastava
|
||||
.\" Last Modified On : Tue Apr 11 14:43:23 2006
|
||||
.\" Last Machine Used: glaurung.internal.golden-gryphon.com
|
||||
.\" Update Count : 14
|
||||
.\" Status : Unknown, Use with caution!
|
||||
.\" HISTORY :
|
||||
.\" Description :
|
||||
.\"
|
||||
.\" arch-tag: f2f569c2-5b54-4e5d-83f0-d2a39e103ecb
|
||||
.\"
|
||||
.\" Copyright (c) 2006 Manoj Srivastava <srivasta@debian.org>
|
||||
.\"
|
||||
.\" This is free documentation; 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.
|
||||
.\"
|
||||
.\" The GNU General Public License's references to "object code"
|
||||
.\" and "executables" are to be interpreted as the output of any
|
||||
.\" document formatting or typesetting system, including
|
||||
.\" intermediate and printed output.
|
||||
.\"
|
||||
.\" This manual 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 manual; if not, write to the Free
|
||||
.\" Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
.\" 02111-1307, USA.
|
||||
.\"
|
||||
.TH UCFR 1 "Feb 16 2018" "Debian" "Debian GNU/Linux manual"
|
||||
.SH NAME
|
||||
ucfr \- Update Configuration File Registry: associate packages with configuration files
|
||||
.SH SYNOPSIS
|
||||
.B ucfr
|
||||
.RI [ options "] "
|
||||
.I <Package>
|
||||
.I <Path to configuration file>
|
||||
.SH DESCRIPTION
|
||||
Where
|
||||
.I Package
|
||||
is the package associated with the configuration file (and, in some
|
||||
sense, its owner), and
|
||||
.I Path to configuration file
|
||||
is the full path to the location (usually under /etc) where the
|
||||
configuration file lives, and is potentially modified by the end
|
||||
user. Please note that usually this means that we register actual
|
||||
files, and not symbolic links to files.
|
||||
.B ucfr
|
||||
will follow symbolic links and register the real file, and not the
|
||||
symbolic link.
|
||||
.PP
|
||||
This script maintains an association between configuration files and
|
||||
packages, and is meant to help provide facilities that
|
||||
.I dpkg
|
||||
provides conffiles for configuration files and not shipped in a
|
||||
.B Debian
|
||||
package, but handled by the postinst by
|
||||
.I ucf
|
||||
instead. This script is idempotent, associating a package to a file
|
||||
multiple times is not an error. It is normally an error to try to
|
||||
associate a file which is already associated with another package, but
|
||||
this can be overridden by using the
|
||||
.I \-\-force
|
||||
option.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B "\-h, \-\-help"
|
||||
Print a short usage message
|
||||
.TP
|
||||
.B "\-n, \-\-no\-action"
|
||||
Dry run. Print the actions that would be taken if the script is
|
||||
invoked, but take no action.
|
||||
.TP
|
||||
.B "\-d [n], \-\-debug [n]"
|
||||
Set the debug level to the (optional) level
|
||||
.I n
|
||||
(n defaults to 1). This turns on copious debugging information.
|
||||
.TP
|
||||
.B "\-p, \-\-purge"
|
||||
Removes all vestiges of the association between the named package and
|
||||
the configuration file from the registry. The association must already
|
||||
exist; if the configuration file is associated with some other
|
||||
package, an error happens, unless the option
|
||||
.I \-\-force
|
||||
is also given. In that case, the any associations for the
|
||||
configuration file are removed from the registry, whether or not the
|
||||
package name matches. This action is idempotent, asking for an
|
||||
association to be purged multiple times does not result in an error,
|
||||
since attempting to remove an non-existent association is silently
|
||||
ignored unless the
|
||||
.I \-\-verbose
|
||||
option is used (in which case it just issues a diagnostic).
|
||||
.TP
|
||||
.B "\-v, \-\-verbose"
|
||||
Make the script be very verbose about setting internal variables.
|
||||
.TP
|
||||
.B "\-f, \-\-force"
|
||||
This option forces operations requested even if the configuration file
|
||||
in consideration is owned by another package. This allows a package to
|
||||
.I "hijack"
|
||||
a configuration file from another package, or to purge the
|
||||
association between the file and some other package in the registry.
|
||||
.TP
|
||||
.B "\-\-state\-dir /path/to/dir"
|
||||
Set the state directory to /path/to/dir instead of the default
|
||||
.I /var/lib/ucf.
|
||||
Used mostly for testing.
|
||||
.SH USAGE
|
||||
The most common case usage is pretty simple: a single line invocation
|
||||
in the postinst on configure, and another single line in the postrm to
|
||||
tell
|
||||
.B ucfr
|
||||
to forget about the association with the configuration file on purge
|
||||
(using the \-\-purge option) is all that is needed (assuming ucfr is
|
||||
still on the system).
|
||||
.SH FILES
|
||||
.I /var/lib/ucf/registry,
|
||||
and
|
||||
.I /var/lib/ucf/registry.X,
|
||||
where
|
||||
.I X
|
||||
is a small integer, where previous versions of the registry are
|
||||
stored.
|
||||
.PP
|
||||
.I /etc/ucf.conf
|
||||
.SH EXAMPLES
|
||||
If the package
|
||||
.I foo
|
||||
wants to use ucfr to associate itself with a configuration file
|
||||
.I foo.conf,
|
||||
a simple invocation of ucfr in the postinst file is all that is
|
||||
needed:
|
||||
.PP
|
||||
.B ucfr
|
||||
.I foo
|
||||
.I /etc/foo.conf
|
||||
.PP
|
||||
On purge, one should tell ucf to forget about the file (see detailed
|
||||
examples in /usr/share/doc/ucf/examples):
|
||||
.PP
|
||||
.B ucfr
|
||||
.I \-\-purge
|
||||
.I foo
|
||||
.I /etc/foo.conf
|
||||
.PP
|
||||
If you want to remove all the conf files for a given package
|
||||
.I foo,
|
||||
the simplest way is to use
|
||||
.B ucfq.
|
||||
For example
|
||||
.PP
|
||||
.B ucfq
|
||||
.I \-w
|
||||
.I foo |
|
||||
.B cut
|
||||
.I \-d : \-f 1 |
|
||||
.B while read
|
||||
.I cfile ;
|
||||
.B do
|
||||
.B ucfr
|
||||
.I \-v $cfile ;
|
||||
.B done
|
||||
.SH "SEE ALSO"
|
||||
ucf(1), ucf.conf(5).
|
||||
.SH AUTHOR
|
||||
This manual page was written Manoj Srivastava <srivasta@debian.org>,
|
||||
for the Debian GNU/Linux system.
|
Loading…
Reference in New Issue