initial commit of file from CVS for e-smith-lib on Wed 12 Jul 08:58:46 BST 2023
This commit is contained in:
parent
6d7e97ea37
commit
a527984040
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
*.rpm
|
||||
*.log
|
||||
*spec-20*
|
||||
*.tar.xz
|
21
Makefile
Normal file
21
Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
# Makefile for source rpm: e-smith-lib
|
||||
# $Id: Makefile,v 1.1 2016/02/05 22:44:50 stephdl Exp $
|
||||
NAME := e-smith-lib
|
||||
SPECFILE = $(firstword $(wildcard *.spec))
|
||||
|
||||
define find-makefile-common
|
||||
for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
|
||||
endef
|
||||
|
||||
MAKEFILE_COMMON := $(shell $(find-makefile-common))
|
||||
|
||||
ifeq ($(MAKEFILE_COMMON),)
|
||||
# attept a checkout
|
||||
define checkout-makefile-common
|
||||
test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2
|
||||
endef
|
||||
|
||||
MAKEFILE_COMMON := $(shell $(checkout-makefile-common))
|
||||
endif
|
||||
|
||||
include $(MAKEFILE_COMMON)
|
16
README.md
16
README.md
@ -1,3 +1,17 @@
|
||||
# e-smith-lib
|
||||
# <img src="https://www.koozali.org/images/koozali/Logo/Png/Koozali_logo_2016.png" width="25%" vertical="auto" style="vertical-align:bottom"> e-smith-lib
|
||||
|
||||
SMEServer Koozali developed git repo for e-smith-lib smeserver
|
||||
|
||||
## Wiki
|
||||
<br />https://wiki.koozali.org/
|
||||
|
||||
## Bugzilla
|
||||
Show list of outstanding bugs: [here](https://bugs.koozali.org/buglist.cgi?component=e-smith-lib&product=SME%20Server%2010.X&query_format=advanced&limit=0&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=CONFIRMED)
|
||||
|
||||
## Description
|
||||
|
||||
<br />*This description has been generated by an LLM AI system and cannot be relied on to be fully correct.*
|
||||
*Once it has been checked, then this comment will be deleted*
|
||||
<br />
|
||||
|
||||
E-smith-lib is an open source software that enables users to quickly and easily create, edit, and share digital content. The platform offers a variety of tools and features that make it easy for users to create and edit a variety of digital documents, such as text documents, audio files, video files, and photographs. It also allows users to collaborate with other users, share digital content, and manage digital workflow. E-smith-lib also features a powerful search engine that can help users locate digital content quickly. Additionally, it offers a variety of templates for quickly creating digital documents, and provides support for multiple languages and different operating systems. The software is easy to use and offers a convenient way for users to manage their digital content.
|
||||
|
131
additional/Artistic
Normal file
131
additional/Artistic
Normal file
@ -0,0 +1,131 @@
|
||||
|
||||
|
||||
|
||||
|
||||
The "Artistic License"
|
||||
|
||||
Preamble
|
||||
|
||||
The intent of this document is to state the conditions under which a
|
||||
Package may be copied, such that the Copyright Holder maintains some
|
||||
semblance of artistic control over the development of the package,
|
||||
while giving the users of the package the right to use and distribute
|
||||
the Package in a more-or-less customary fashion, plus the right to make
|
||||
reasonable modifications.
|
||||
|
||||
Definitions:
|
||||
|
||||
"Package" refers to the collection of files distributed by the
|
||||
Copyright Holder, and derivatives of that collection of files
|
||||
created through textual modification.
|
||||
|
||||
"Standard Version" refers to such a Package if it has not been
|
||||
modified, or has been modified in accordance with the wishes
|
||||
of the Copyright Holder as specified below.
|
||||
|
||||
"Copyright Holder" is whoever is named in the copyright or
|
||||
copyrights for the package.
|
||||
|
||||
"You" is you, if you're thinking about copying or distributing
|
||||
this Package.
|
||||
|
||||
"Reasonable copying fee" is whatever you can justify on the
|
||||
basis of media cost, duplication charges, time of people involved,
|
||||
and so on. (You will not be required to justify it to the
|
||||
Copyright Holder, but only to the computing community at large
|
||||
as a market that must bear the fee.)
|
||||
|
||||
"Freely Available" means that no fee is charged for the item
|
||||
itself, though there may be fees involved in handling the item.
|
||||
It also means that recipients of the item may redistribute it
|
||||
under the same conditions they received it.
|
||||
|
||||
1. You may make and give away verbatim copies of the source form of the
|
||||
Standard Version of this Package without restriction, provided that you
|
||||
duplicate all of the original copyright notices and associated disclaimers.
|
||||
|
||||
2. You may apply bug fixes, portability fixes and other modifications
|
||||
derived from the Public Domain or from the Copyright Holder. A Package
|
||||
modified in such a way shall still be considered the Standard Version.
|
||||
|
||||
3. You may otherwise modify your copy of this Package in any way, provided
|
||||
that you insert a prominent notice in each changed file stating how and
|
||||
when you changed that file, and provided that you do at least ONE of the
|
||||
following:
|
||||
|
||||
a) place your modifications in the Public Domain or otherwise make them
|
||||
Freely Available, such as by posting said modifications to Usenet or
|
||||
an equivalent medium, or placing the modifications on a major archive
|
||||
site such as uunet.uu.net, or by allowing the Copyright Holder to include
|
||||
your modifications in the Standard Version of the Package.
|
||||
|
||||
b) use the modified Package only within your corporation or organization.
|
||||
|
||||
c) rename any non-standard executables so the names do not conflict
|
||||
with standard executables, which must also be provided, and provide
|
||||
a separate manual page for each non-standard executable that clearly
|
||||
documents how it differs from the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
4. You may distribute the programs of this Package in object code or
|
||||
executable form, provided that you do at least ONE of the following:
|
||||
|
||||
a) distribute a Standard Version of the executables and library files,
|
||||
together with instructions (in the manual page or equivalent) on where
|
||||
to get the Standard Version.
|
||||
|
||||
b) accompany the distribution with the machine-readable source of
|
||||
the Package with your modifications.
|
||||
|
||||
c) give non-standard executables non-standard names, and clearly
|
||||
document the differences in manual pages (or equivalent), together
|
||||
with instructions on where to get the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
5. You may charge a reasonable copying fee for any distribution of this
|
||||
Package. You may charge any fee you choose for support of this
|
||||
Package. You may not charge a fee for this Package itself. However,
|
||||
you may distribute this Package in aggregate with other (possibly
|
||||
commercial) programs as part of a larger (possibly commercial) software
|
||||
distribution provided that you do not advertise this Package as a
|
||||
product of your own. You may embed this Package's interpreter within
|
||||
an executable of yours (by linking); this shall be construed as a mere
|
||||
form of aggregation, provided that the complete Standard Version of the
|
||||
interpreter is so embedded.
|
||||
|
||||
6. The scripts and library files supplied as input to or produced as
|
||||
output from the programs of this Package do not automatically fall
|
||||
under the copyright of this Package, but belong to whoever generated
|
||||
them, and may be sold commercially, and may be aggregated with this
|
||||
Package. If such scripts or library files are aggregated with this
|
||||
Package via the so-called "undump" or "unexec" methods of producing a
|
||||
binary executable image, then distribution of such an image shall
|
||||
neither be construed as a distribution of this Package nor shall it
|
||||
fall under the restrictions of Paragraphs 3 and 4, provided that you do
|
||||
not represent such an executable image as a Standard Version of this
|
||||
Package.
|
||||
|
||||
7. C subroutines (or comparably compiled subroutines in other
|
||||
languages) supplied by you and linked into this Package in order to
|
||||
emulate subroutines and variables of the language defined by this
|
||||
Package shall not be considered part of this Package, but are the
|
||||
equivalent of input as in Paragraph 6, provided these subroutines do
|
||||
not change the language in any way that would cause it to fail the
|
||||
regression tests for the language.
|
||||
|
||||
8. Aggregation of this Package with a commercial distribution is always
|
||||
permitted provided that the use of this Package is embedded; that is,
|
||||
when no overt attempt is made to make this Package's interfaces visible
|
||||
to the end user of the commercial distribution. Such use shall not be
|
||||
construed as a distribution of this Package.
|
||||
|
||||
9. The name of the Copyright Holder may not be used to endorse or promote
|
||||
products derived from this software without specific prior written permission.
|
||||
|
||||
10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
The End
|
340
additional/Copying
Normal file
340
additional/Copying
Normal file
@ -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
|
||||
|
||||
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.
|
33
additional/LICENSE
Normal file
33
additional/LICENSE
Normal file
@ -0,0 +1,33 @@
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
|
||||
|
||||
Perl Kit, Version 5.0
|
||||
|
||||
Copyright 1989-2001, Larry Wall
|
||||
All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of either:
|
||||
|
||||
a) the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 1, or (at your option) any
|
||||
later version, or
|
||||
|
||||
b) the "Artistic License" which comes with this Kit.
|
||||
|
||||
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 either
|
||||
the GNU General Public License or the Artistic License for more details.
|
||||
|
||||
You should have received a copy of the Artistic License with this
|
||||
Kit, in the file named "Artistic". If not, I'll be glad to provide one.
|
||||
|
||||
You should also have received a copy of the GNU General Public License
|
||||
along with this program in the file named "Copying". If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307, USA or visit their web page on the internet at
|
||||
http://www.gnu.org/copyleft/gpl.html.
|
||||
|
790
additional/e-smith-lib.spec
Normal file
790
additional/e-smith-lib.spec
Normal file
@ -0,0 +1,790 @@
|
||||
# $Id: e-smith-lib.spec,v 1.24 2010/10/11 22:27:51 slords Exp $
|
||||
|
||||
Summary: e-smith server and gateway - library module
|
||||
%define name e-smith-lib
|
||||
Name: %{name}
|
||||
%define version 2.4.0
|
||||
%define release 1
|
||||
Version: %{version}
|
||||
Release: %{release}%{?dist}
|
||||
License: Artistic
|
||||
Group: Networking/Daemons
|
||||
Source: %{name}-%{version}.tar.xz
|
||||
BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot
|
||||
BuildArchitectures: noarch
|
||||
BuildRequires: e-smith-devtools >= 1.6.3-01
|
||||
Obsoletes: %{name}-Tai64n
|
||||
Obsoletes: whiptail
|
||||
Requires: dialog
|
||||
Requires: perl, perl(Text::Template)
|
||||
Requires: perl(Time::HiRes), perl(MIME::Base64)
|
||||
Requires: perl(Authen::PAM), perl(I18N::AcceptLanguage)
|
||||
Requires: perl(I18N::LangTags) >= 0.27
|
||||
Requires: perl(Net::IPv4Addr) >= 0.10
|
||||
|
||||
%description
|
||||
e-smith server and gateway software - library module.
|
||||
|
||||
%changelog
|
||||
* Fri Jan 25 2013 Shad L. Lords <slords@mail.com> 2.4.0-1.sme
|
||||
- Bump version in prep for SME9
|
||||
|
||||
* Mon Oct 11 2010 Shad L. Lords <slords@mail.com> 2.2.0-7.sme
|
||||
- Serialize configure_peers to prevent errors [SME: 5831]
|
||||
|
||||
* Fri Feb 5 2010 Stephen Noble <support@dungog.net> 2.2.0-6.sme
|
||||
- adds the hwaddr parameter to probeAdapters() [SME: 4528]
|
||||
|
||||
* Thu Feb 4 2010 Shad L. Lords <slords@mail.com> 2.2.0-5.sme
|
||||
- Update path for 64-bit compatibility [SME: 5756]
|
||||
|
||||
* Tue Dec 22 2009 Filippo Carletti <filippo.carletti@gmail.com> 2.2.0-4.sme
|
||||
- Really apply previous patch in the spec file. [SME: 5659]
|
||||
|
||||
* Wed Dec 9 2009 Charlie Brady <charlieb@budge.apana.org.au> 2.2.0-3.sme
|
||||
- Add patch (Federico Simoncelli) to prevent re-use of uids. [SME: 5659]
|
||||
|
||||
* Mon Oct 13 2008 Shad L. Lords <slords@mail.com> 2.2.0-2.sme
|
||||
- Add patch to support multiple samba roles [SME: 4172]
|
||||
|
||||
* Tue Oct 7 2008 Shad L. Lords <slords@mail.com> 2.2.0-1.sme
|
||||
- Roll new stream to separate sme7/sme8 trees [SME: 4633]
|
||||
|
||||
* Wed Aug 20 2008 Shad L. Lords <slords@mail.com> 1.19.0-1
|
||||
- Roll new dev stream.
|
||||
|
||||
* Sat Aug 9 2008 Shad L. Lords <slords@mail.com> 1.18.0-28
|
||||
- Read /dev/urandmon instead of /dev/random [SME: 4492]
|
||||
|
||||
* Sat Aug 9 2008 Shad L. Lords <slords@mail.com> 1.18.0-27
|
||||
- Make dialog not use STDERR for return values [SME: 3663]
|
||||
- Remove requires for whiptail. No longer needed [SME: 4491]
|
||||
|
||||
* Thu Jul 31 2008 Shad L. Lords <slords@mail.com> 1.18.0-26
|
||||
- Make binmode properties of db class [SME: 4317]
|
||||
- Add new navigation db & utf8 classes [SME: 4317]
|
||||
|
||||
* Wed Apr 2 2008 Shad L. Lords <slords@mail.com> 1.18.0-25
|
||||
- Add .utf8 to locale unless server-console [SME: 4162]
|
||||
- Add new languages to langtag2locale [SME: 4163]
|
||||
|
||||
* Sun Mar 30 2008 Shad L. Lords <slords@mail.com> 1.18.0-24
|
||||
- Gracefully handle encoding errors in navigation dbs [SME: 4147]
|
||||
|
||||
* Wed Mar 26 2008 Shad L. Lords <slords@mail.com> 1.18.0-23
|
||||
- Make PAM conv routine not look for english strings [SME: 4117]
|
||||
|
||||
* Tue Mar 25 2008 Shad L. Lords <slords@mail.com> 1.18.0-22
|
||||
- Fix wide output to syslog and allow navigations db to be utf8 [SME: 4101]
|
||||
|
||||
* Mon Mar 10 2008 Shad L. Lords <slords@mail.com> 1.18.0-21
|
||||
- Output navigation in UTF-8 [SME: 3858]
|
||||
|
||||
* Sun Jan 20 2008 Gavin Weight <gweight@gmail.com> 1.18.0-20
|
||||
- Call smbpasswd -e - to reset user correctly. [SME: 3755]
|
||||
|
||||
* Tue Jan 08 2008 Stephen Noble <support@dungog.net> 1.18.0-19
|
||||
- modify validate password strong match for console [SME: 2173]
|
||||
|
||||
* Thu Nov 01 2007 Gavin Weight <gweight@gmail.com> 1.18.0-18
|
||||
- Fix I18N.pm file descriptor leak. [SME: 3509]
|
||||
|
||||
* Wed Oct 31 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-17
|
||||
- Remove undocumented and unused template metadata handling from
|
||||
generic_template_expand action (Take II). [SME: 2798]
|
||||
|
||||
* Fri Jun 1 2007 Shad L. Lords <slords@mail.com> 1.18.0-16
|
||||
- pam_unix requires passwords >= 6 [SME: 3039]
|
||||
|
||||
* Mon May 21 2007 Shad L. Lords <slords@mail.com> 1.18.0-15
|
||||
- Fix ip addr shift to work on 64-bit
|
||||
|
||||
* Sun Apr 29 2007 Shad L. Lords <slords@mail.com>
|
||||
- Clean up spec so package can be built by koji/plague
|
||||
|
||||
* Thu Apr 05 2007 Shad L. Lords <slords@mail.com> 1.18.0-14
|
||||
- Reverse changes for 1.18.0-12 as it is being used. [SME: 2838]
|
||||
|
||||
* Wed Apr 04 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-13
|
||||
- Allow gauge console widget to be used without following message_page.
|
||||
[SME: 2832].
|
||||
|
||||
* Mon Mar 26 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-12
|
||||
- Remove undocumented and unused template metadata handling from
|
||||
generic_template_expand action. [SME: 2798]
|
||||
|
||||
* Mon Mar 26 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-11
|
||||
- Split logfile rotation code out of generic_template_expand.
|
||||
Code moved to a new action in e-smith-base. [SME: 2795]
|
||||
|
||||
* Mon Mar 19 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-10
|
||||
Don't try to read template.metadata from subdirectories (affects
|
||||
initialize_database_defaults). [SME: 2690]
|
||||
|
||||
* Fri Mar 16 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-9
|
||||
- Allow template.metadata to be provided via a directory of
|
||||
small files. [SME: 2690]
|
||||
- Add support for a DELETE boolean template.metadata item. [SME: 2691]
|
||||
|
||||
* Wed Feb 28 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-8
|
||||
- Add gauge widget to esmith::console. [SME: 2579]
|
||||
|
||||
* Sun Feb 25 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-7
|
||||
- Default infobox height to 8 rows, and allow override via params.
|
||||
[SME: 2560]
|
||||
|
||||
* Fri Feb 23 2007 Shad L. Lords <slords@mail.com> 1.18.0-6
|
||||
- Really fix clear parameter for inputbox dialog screen [SME: 2533]
|
||||
|
||||
* Fri Feb 23 2007 Shad L. Lords <slords@mail.com> 1.18.0-5
|
||||
- Fix clear parameter for dialog screens [SME: 2533]
|
||||
|
||||
* Thu Feb 22 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-4
|
||||
- switch esmith::console::password_page() to use dialog rather than
|
||||
whiptail. [SME: 2534]
|
||||
|
||||
* Thu Feb 22 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-3
|
||||
- Add infobox widget. [SME: 2533]
|
||||
|
||||
* Sun Jan 28 2007 Shad L. Lords <slords@mail.com> 1.18.0-2
|
||||
- Fix backtitle spacing for new dialog menus [SME: 2328]
|
||||
|
||||
* Fri Jan 26 2007 Shad L. Lords <slords@mail.com> 1.18.0-1
|
||||
- Roll stable stream. [SME: 2328]
|
||||
|
||||
* Tue Dec 15 2006 Federico Simoncelli <federico.simoncelli@gmail.com> 1.17.0-8
|
||||
- Added the validatePassword function to esmith::util. [SME: 2100]
|
||||
|
||||
* Thu Dec 07 2006 Shad L. Lords <slords@mail.com>
|
||||
- Update to new release naming. No functional changes.
|
||||
- Make Packager generic
|
||||
|
||||
* Fri Nov 24 2006 Gordon Rowell <gordonr@gormand.com.au> 1.17.0-06
|
||||
- Allow optional path to peeers directory in
|
||||
esmith::tcpsvd::configure_peers() [SME: 2086]
|
||||
|
||||
* Tue Nov 14 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-05
|
||||
- Allow defaulno option to esmith::console::yesno.
|
||||
- Fix I/O redirection in esmith::console::new.
|
||||
|
||||
* Tue Nov 07 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-04
|
||||
- Allow display of "0" in iesmith::cgi::genSmallCell. [SME: 2038]
|
||||
|
||||
* Mon Oct 23 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-03
|
||||
- Make dialog the default console app, with whiptail used only when
|
||||
required.
|
||||
|
||||
* Wed Oct 11 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-02
|
||||
- Allow 'dialog' to be called from esmith::console. [SME: 1958]
|
||||
|
||||
* Wed Oct 11 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-01
|
||||
- Roll development branch.
|
||||
|
||||
* Mon Sep 25 2006 Charlie Brady <charlie_brady@mitel.com> 1.16.0-06
|
||||
- Fix problem with greedy RE in template.metadata parsing. [SME: 1906]
|
||||
|
||||
* Fri Sep 08 2006 Charlie Brady <charlie_brady@mitel.com> 1.16.0-05
|
||||
- Fix taint problem in template.metadata handling. [SME: 1906]
|
||||
|
||||
* Thu Apr 13 2006 Charlie Brady <charlie_brady@mitel.com> 1.16.0-04
|
||||
- Use "kudzu --probe --class network" for NIC detection. [SME: 727]
|
||||
|
||||
* Fri Apr 7 2006 Gordon Rowell <gordonr@gormand.com.au> 1.16.0-03
|
||||
- Don't call smbpasswd -e - setting the password is sufficient [SME: 1193]
|
||||
|
||||
* Tue Mar 28 2006 Gordon Rowell <gordonr@gormand.com.au> 1.16.0-02
|
||||
- Log previous contents of db entry in DELETE log [SME: 1066]
|
||||
|
||||
* Tue Mar 14 2006 Charlie Brady <charlie_brady@mitel.com> 1.16.0-01
|
||||
- Roll to stable stream version number. [SME: 1016]
|
||||
|
||||
* Fri Mar 10 2006 Charlie Brady <charlie_brady@mitel.com> 1.15.4-02
|
||||
- Suppress warning from genSmallCell if text is undefined. [SME: 986]
|
||||
|
||||
* Fri Feb 17 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.4-01
|
||||
- Roll patches up to 1.15.3-42
|
||||
- Trim changelog prior to 1.15.0-01 [SME: 828]
|
||||
|
||||
* Thu Feb 16 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-42
|
||||
- Adjust console title bar to 'SME Server' [SME: 726]
|
||||
|
||||
* Tue Feb 14 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-41
|
||||
- Reworded text for template-begin and change URL to /development/
|
||||
rather than /custom/ [SME: 773]
|
||||
|
||||
* Mon Feb 13 2006 Charlie Brady <charlie_brady@mitel.com> 1.15.3-40
|
||||
- Update URL in default template-begin fragment. [SME: 773]
|
||||
|
||||
* Sat Feb 11 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-39
|
||||
- Remove obsolete e-smith-lib-Tai64n package. [SME: 689]
|
||||
|
||||
* Sat Feb 11 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-38
|
||||
- [Null changelog for missing version - we accidentally skipped
|
||||
this version.]
|
||||
|
||||
* Sat Feb 11 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-37
|
||||
- Fix get_all_by_prop in scalar context. [SME: 669,721]
|
||||
|
||||
* Mon Feb 6 2006 Shad L. Lords <slords@mail.com> 1.15.3-37
|
||||
- Add ability to pass many props to get_all_by_prop [SME: 669]
|
||||
|
||||
* Mon Jan 23 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-36
|
||||
- Fix warning during pseudonym deletion. [SME: 491]
|
||||
|
||||
* Fri Jan 20 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-35
|
||||
- Fix up use of Sys::Syslog::syslog. [SME: 526]
|
||||
|
||||
* Thu Jan 19 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-34
|
||||
- Remove running of kudzu during NIC probing. TODO: Find a solution
|
||||
to system reconfiguration when new hardware is added. [SME: 192]
|
||||
|
||||
* Tue Jan 10 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-33
|
||||
- Fold a.b.c.d/255.255.255.255 to a.b.c.d in local_access_spec() to
|
||||
work around bugs in applications which don't accept such specs.
|
||||
[SME: 430]
|
||||
|
||||
* Mon Jan 9 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-32
|
||||
- Check whether an accounts db record exists before trying to create
|
||||
the dot and underscore pseudonyms (new_record will fail silently)
|
||||
and check that the records are pseudonyms before deleting them [SME: 24]
|
||||
|
||||
* Mon Jan 9 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-31
|
||||
- And update POD for last change [SME: 24]
|
||||
|
||||
* Mon Jan 9 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-30
|
||||
- Allow dot and underscore in account names [SME: 24]
|
||||
|
||||
* Tue Dec 27 2005 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-29
|
||||
- Remove newlines from cluck() string and just note that the old
|
||||
path was used [SME: 365]
|
||||
|
||||
* Sat Dec 25 2005 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-28
|
||||
- If db exists in both the old and new locations in
|
||||
initialize_default_databases, rename the one in the new
|
||||
location to db.time(), avoiding the conflict and saving the
|
||||
evidence in case it is needed later [SME: 229]
|
||||
|
||||
* Mon Dec 05 2005 Mark Knox <mark_knox@mitel.com>
|
||||
- [1.15.3-27]
|
||||
- Moved queueing logic to separate daemon, replaced with FIFO IPC [BZ252
|
||||
|
||||
* Thu Dec 01 2005 Mark Knox <mark_knox@mitel.com>
|
||||
- [1.15.3-26]
|
||||
- Added event queueing (open source portion) for clustered systems [BZ250]
|
||||
|
||||
* Wed Nov 30 2005 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-25
|
||||
- Bump release number only
|
||||
|
||||
* Thu Nov 24 2005 Gordon Rowell <gordonr@e-smith.com>
|
||||
- [1.15.3-24]
|
||||
- Add missing 'use Locale::gettext' to esmith::console.pm [MN00108804]
|
||||
|
||||
* Sun Nov 20 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-23]
|
||||
- Clarify logic for stopped services in adjust-services. [SF: 1357629]
|
||||
|
||||
* Sun Nov 20 2005 Gordon Rowell <gordonr@e-smith.com>
|
||||
- [1.15.3-22]
|
||||
- Correct adjust-services logic for stopped services [SF: 1357629]
|
||||
|
||||
* Wed Nov 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-21]
|
||||
- Allow services2adjust directories to contain files rather than just dangling
|
||||
symlinks. Files can contain more than one actions to perform. [SF: 1270644]
|
||||
|
||||
* Wed Nov 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-20]
|
||||
- Also don't start services if we just want to "once" them. [SF: 1357629]
|
||||
|
||||
* Wed Nov 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-19]
|
||||
- Fix restart of enabled supervised services which we are attempting to stop.
|
||||
[SF: 1357629]
|
||||
|
||||
* Tue Nov 15 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-18]
|
||||
- Set default for $type in esmith::cgi::genSmallCell, to prevent some log
|
||||
noise. [SF: 1357830]
|
||||
|
||||
* Tue Nov 15 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-17]
|
||||
- Pass $EVENT to template expansions in generic_template_expand.
|
||||
[SF: MN00106104]
|
||||
|
||||
* Tue Nov 15 2005 Gordon Rowell <gordonr@e-smith.com>
|
||||
- [1.15.3-16]
|
||||
- Redirect esmith::config calls on old db paths to the new
|
||||
location [SF: 1335865]
|
||||
|
||||
* Thu Oct 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-15]
|
||||
- Fix a few minor spec file portability issues. [SF: 1339729]
|
||||
|
||||
* Wed Oct 26 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-14]
|
||||
- Add it and de to the langtag2locale fixups. [SF: 1338236]
|
||||
|
||||
* Tue Oct 11 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-13]
|
||||
- Build driver list from .ko files as well as .o files. Untaint driver
|
||||
names while building list. [SF: 1323270]
|
||||
|
||||
* Mon Sep 26 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-12]
|
||||
- Fix "defaults" handling so that values which evaluate to false are
|
||||
not overridden by default. [SF: 1303885]
|
||||
|
||||
* Fri Sep 23 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-11]
|
||||
- Untaint db names before attempting to move them. [MN00098405]
|
||||
|
||||
* Thu Sep 22 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-10]
|
||||
- Provide networks method in esmith::NetworksDB. [SF: 1296099]
|
||||
- Support a "localhost" configuration in esmith::tcpsvd:configure_peers
|
||||
[SF: 1294719]
|
||||
|
||||
* Tue Sep 20 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-09]
|
||||
- Remove deprecated functions from esmith::utils. [SF: 1295851]
|
||||
- Include only "network" records in local_access_spec. [SF: 1296099]
|
||||
|
||||
* Mon Sep 12 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-08]
|
||||
- Remove warning about explicit path in esmith::db::_db_path.
|
||||
[SF: 1286294]
|
||||
|
||||
* Fri Sep 9 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-07]
|
||||
- Tolerate, but warn about, symlinks in /home/e-smith. [SF: 1216546]
|
||||
|
||||
* Fri Sep 9 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-06]
|
||||
- Reduce the noise from _file_path() in esmith::DB::db. [SF: 1286294]
|
||||
|
||||
* Wed Sep 7 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-05]
|
||||
- Fix operation of expandTemplate when taint check is enabled.
|
||||
[SF: 1284301]
|
||||
|
||||
* Wed Aug 17 2005 Mark Knox <markk@e-smith.com>
|
||||
- [1.15.3-04]
|
||||
- Added open_local and open_ro_local methods for clustering [markk MN00094831]
|
||||
|
||||
* Tue Aug 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-03]
|
||||
- Fix POD error in util.pm.
|
||||
|
||||
* Wed Jul 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-02]
|
||||
- Move databases default location from /home/e-smith to /home/e-smith/db.
|
||||
During esmith::utils::initialize_default_databases, move from old to new
|
||||
location before doing db migrate actions. [SF: 1216546]
|
||||
|
||||
* Wed Jul 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-01]
|
||||
- Roll a new development stream - 1.15.3
|
||||
|
||||
* Wed Jul 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.2-04]
|
||||
- Remove broken MergeDB stuff. [SF: 1246315]
|
||||
|
||||
* Wed Jul 27 2005 Mark Knox <markk@e-smith.com>
|
||||
- [1.15.2-03]
|
||||
- Fixed misleading comment in util.pm
|
||||
- Added 'use' statements in Record classes for SOAP compatibility
|
||||
- Fixed undefined max_len warning
|
||||
- Added explicit writeconf calls in db::Record.pm, needed for setting props
|
||||
via SOAP
|
||||
|
||||
* Tue Jul 19 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.2-02]
|
||||
- Allow db open API to use default path if a simple filename
|
||||
is provided as arg. This is preparation for move of dbs to
|
||||
/home/e-smith/db. Patch by Shad Lords.
|
||||
|
||||
* Mon Jul 18 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.2-01]
|
||||
- Roll new development stream - 1.15.2
|
||||
|
||||
* Fri Jul 15 2005 Mark Knox <markk@e-smith.com>
|
||||
- [1.15.1-44]
|
||||
- Tweak to allow calling _writeconf from SOAP [markk MN00090738]
|
||||
|
||||
* Tue Jun 21 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-43]
|
||||
- Ensure that esmith::util::LdapPassword returns bare string without
|
||||
newline terminator.
|
||||
|
||||
* Sun Jun 12 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-42]
|
||||
- Remove .rpmsave and .rpmnew symlinks (as well as files). [SF: 1217969]
|
||||
- Handle missing description in pcitables entries.
|
||||
|
||||
* Sun Jun 12 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-41]
|
||||
- Provide feedback (via log messages) from services2adjust. [SF: 1218920]
|
||||
|
||||
* Mon May 30 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-40]
|
||||
- Add preinstall scripting to create required accounts/groups if they
|
||||
don't already exist. [SF: 1210723]
|
||||
|
||||
* Thu May 5 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-39]
|
||||
- Show Text::Template error text rather than inappropriate $! if template
|
||||
expansion fails.
|
||||
- Change error to warning if a config item is set with an empty "type"
|
||||
property.
|
||||
|
||||
* Thu May 5 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-38]
|
||||
- Fix esmith::DB::get_prop_and_delete fail if prop is "false" [From Gordon].
|
||||
|
||||
* Tue May 3 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-37]
|
||||
- Update directory list so that ethernet drivers from kernel-unsupported are
|
||||
added to "choose by driver" list.
|
||||
|
||||
* Sat Mar 19 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-36]
|
||||
- Rework esmith::tcpsvd::configure_peers so that it doesn't chdir.
|
||||
- Fix generic_template_expand so that templates.metadata doesn't
|
||||
need to set OUTPUT_FILENAME is TEMPLATE_PATH is changed. This
|
||||
matches what expand-template already does.
|
||||
|
||||
* Fri Mar 18 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-35]
|
||||
- Change numerous calls to "croak" in esmith::template
|
||||
to "carp ...; return", so that problem with any single
|
||||
template expansion doesn't terminate calling program.
|
||||
[MN00075009]
|
||||
|
||||
* Wed Mar 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-34]
|
||||
- Add missing "use esmith::util" in esmith::tcpsvd.
|
||||
|
||||
* Wed Mar 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-33]
|
||||
- Add esmith::tcpsvd library for managing tcpsvd "peers"
|
||||
directories.
|
||||
|
||||
* Mon Mar 14 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-32]
|
||||
- Make template expansion message more succinct.
|
||||
|
||||
* Thu Mar 10 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-31]
|
||||
- Remove pseudonyms of pseudonyms when removing user
|
||||
accounts. Adapted from patch submitted by Shad. [MN00039941]
|
||||
|
||||
* Wed Feb 23 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-30]
|
||||
- Fix incompatibility with CentOS's CGI.pm.
|
||||
|
||||
* Tue Feb 22 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-29]
|
||||
- Fix bug in output to empty file when FILTER is used
|
||||
during template expansion. [charlieb MN00050075]
|
||||
|
||||
* Tue Feb 22 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-28]
|
||||
- Refresh contents of /etc/sysconfig/hwconf before listing
|
||||
network adaptors [MN00069993]
|
||||
- Fix typo in documentation of esmith::DB::db - reported from Tanna -
|
||||
http://www.livejournal.com/users/gcrumb/61169.html (thanks Dan!)
|
||||
|
||||
* Wed Feb 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-27]
|
||||
- Fix typo. [MN00066059]
|
||||
|
||||
* Wed Feb 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-26]
|
||||
- Use /sbin/e-smith/whiptail if it is available. [MN00066059]
|
||||
|
||||
* Mon Feb 7 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-25]
|
||||
- Update perms and ownership when expanding templates, regardless of
|
||||
whether file content has changed or not. [MN00068043]
|
||||
|
||||
* Wed Feb 2 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-24]
|
||||
- Fix the insertion of implicit actions into sorted action list in
|
||||
event.pm. Problem was perl syntax ambiguity. [MN00066406]
|
||||
|
||||
* Fri Jan 28 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-23]
|
||||
- Really move /home/e-smith/* to e-smith-base. [MN00066635]
|
||||
|
||||
* Fri Jan 28 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-22]
|
||||
- Move /home/e-smith/* to e-smith-base. [MN00066635]
|
||||
- Move generic-template expand to S05 position in sort, and
|
||||
adjust-service to S90. Fix run-time error. [MN00066406]
|
||||
- Don't attempt to execute non-executable action scripts.
|
||||
|
||||
* Thu Jan 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-21]
|
||||
- Implicitly include template expand and services adjust actions
|
||||
in each event if the respective metadata directory exists.
|
||||
[MN00066406]
|
||||
|
||||
* Tue Jan 25 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-20]
|
||||
- Add "adjust" to list of verbs which serviceControl groks,
|
||||
to allow for "masq adjust". [MN00065576]
|
||||
|
||||
* Tue Jan 25 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-19]
|
||||
- Add adjust-services generic action script [MN00065576]
|
||||
|
||||
* Tue Jan 18 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-18]
|
||||
- Fix typo. [MN00064412]
|
||||
- Improve die() message in esmith::config::STORE. [MN00064394]
|
||||
|
||||
* Mon Jan 17 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-17]
|
||||
- Fix broken logging (and reduce logging) in initialize_default_databases.
|
||||
[MN00064412]
|
||||
- Fix inappropriate use of global $_ in initialize_default_databases.
|
||||
[MN00064415]
|
||||
|
||||
* Thu Dec 23 2004 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-16]
|
||||
- Read templated file metadata (if any) from file tree under
|
||||
/etc/e-smith/templates.metadata. Update expand-template to
|
||||
use current API. [MN00061830]
|
||||
|
||||
* Tue Dec 14 2004 Mark Knox <markk@e-smith.com>
|
||||
- [1.15.1-15]
|
||||
- Change copyright date to 2004 [markk MN00060958]
|
||||
|
||||
* Fri Nov 5 2004 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-14]
|
||||
- Fix Authen::PAM dependency header [charlieb MN00040240]
|
||||
- Use kudzu's generated /etc/sysconfig/hwconf file for NIC detection
|
||||
[charlieb MN00056220]
|
||||
|
||||
* Thu Oct 14 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-13]
|
||||
- Updated esmith::ethernet's search code to remove File::Find, as it doesn't
|
||||
get along with taint checking. [msoulier MN00052510]
|
||||
|
||||
* Wed Oct 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-12]
|
||||
- Updated esmith::ethernet's search code such that is it more adaptable, and
|
||||
recurses the directories given. [msoulier MN00052510]
|
||||
|
||||
* Wed Oct 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-11]
|
||||
- Updated esmith::ethernet's search paths for network drivers.
|
||||
[msoulier MN00052510]
|
||||
|
||||
* Mon Oct 4 2004 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-10]
|
||||
- Remove dependency on perl(Filter::Handle) [charlieb MN00050075]
|
||||
|
||||
* Fri Sep 24 2004 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-09]
|
||||
- Updated requires with new perl dependencies. [msoulier MN00040240]
|
||||
- Remove "AutoReqProv: no" so that "Provides" headers are auto-generated.
|
||||
[charlieb MN00040240]
|
||||
- Remove anachronistic "require v5.6.0" directives. [charlieb MN00050370]
|
||||
- Avoid use of Filter::Handle in esmith::template. [charlieb MN00050075]
|
||||
|
||||
* Fri Aug 27 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-08]
|
||||
- Added esmith::util::network::isValidEmail function. [msoulier MN00023814]
|
||||
|
||||
* Thu Aug 26 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-07]
|
||||
- Added svdisable to permissible actions in serviceControl.
|
||||
[msoulier MN00043056]
|
||||
|
||||
* Tue Aug 10 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-06]
|
||||
- Fixed new methods. Bad else case. [msoulier MN00044891]
|
||||
|
||||
* Fri Aug 6 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-05]
|
||||
- Added a keys() method. [msoulier MN00041968]
|
||||
|
||||
* Fri Aug 6 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-04]
|
||||
- Added set_prop and set_value methods in esmith::DB. [msoulier MN00044891]
|
||||
|
||||
* Tue Jul 20 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-03]
|
||||
- Undeprecated esmith::util::serviceControl. [msoulier MN00043056]
|
||||
|
||||
* Fri Jun 25 2004 Tony Clayton <apc@e-smith.com>
|
||||
- [1.15.1-02]
|
||||
- Merge language_tag2locale() function from perl-I18N-LangTags [tonyc
|
||||
MN00040170]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-01]
|
||||
- Rolling to collect patches.
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-23]
|
||||
- Reordered the create code slightly to catch more errors.
|
||||
[msoulier MN00035059]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-22]
|
||||
- Added yet more error handling and reporting. [msoulier MN00035059]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-21]
|
||||
- Fixed one $Error reference that I missed in the last rev.
|
||||
[msoulier MN00035059]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-20]
|
||||
- Moved error handling from esmith::DB::db to esmith::DB, since it should not
|
||||
be database implementation specific. [msoulier MN00035059]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-19]
|
||||
- Propagated migration failures up to calling code for reporting to syslog.
|
||||
- Propagated creation failures up to calling code.
|
||||
- Moved lexicon $Error in esmith::DB::db to a class property so it can be used
|
||||
by subclasses. [msoulier MN00035059]
|
||||
|
||||
* Thu May 27 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-18]
|
||||
- Changed print statements to calls to the logger. [msoulier MN00035059]
|
||||
|
||||
* Thu May 27 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-17]
|
||||
- Added print statements to initialize-default-databases for post-install
|
||||
debugging. [msoulier MN00035059]
|
||||
|
||||
* Fri May 7 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-16]
|
||||
- Fixed migrate to report the caught error message. [msoulier MN00032503]
|
||||
|
||||
* Thu May 6 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-15]
|
||||
- Added isValidHostname function to esmith::util::network.
|
||||
[msoulier MN00024212]
|
||||
|
||||
* Fri Feb 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-14]
|
||||
- Greatly simplified the _mysystem function by ripping out open3.
|
||||
[msoulier dpar-20385]
|
||||
|
||||
* Fri Feb 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-13]
|
||||
- Backed-out change in esmith::util, as it's non-trivial there with the exec.
|
||||
Completed update of esmith::event, and separated the esmith::Logger class.
|
||||
[msoulier dpar-20385]
|
||||
|
||||
* Fri Feb 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-12]
|
||||
- Removed use of the logger entirely, replacing it with an abstracted
|
||||
interface to the Sys::Syslog module. [msoulier dpar-20385]
|
||||
|
||||
* Thu Jan 8 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-11]
|
||||
- Fixed esmith::util::network::isValidIP() so valid IP substrings no longer
|
||||
return true values. [msoulier 9308]
|
||||
|
||||
* Thu Jan 8 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-10]
|
||||
- Added a check in STORE in esmith::config for invalid attempts to set a value
|
||||
without a type. Also escalated previous warnings for undef key and value to
|
||||
fatal exceptions. [msoulier 7386]
|
||||
|
||||
* Thu Jan 8 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-09]
|
||||
- Now trimming whitespace around keys and values during esmith::config STORE
|
||||
events, to prevent invalid keys and values from being saved. [msoulier 7021]
|
||||
|
||||
* Mon Jan 5 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-08]
|
||||
- Fixed POD around merge_props. [msoulier 9482]
|
||||
|
||||
* Fri Nov 7 2003 Tony Clayton <apc@e-smith.com>
|
||||
- [1.15.0-07]
|
||||
- And again [tonyc 10569]
|
||||
|
||||
* Fri Nov 7 2003 Tony Clayton <apc@e-smith.com>
|
||||
- [1.15.0-06]
|
||||
- Change Merge API a bit, fix pod [tonyc 10569]
|
||||
|
||||
* Fri Nov 7 2003 Tony Clayton <apc@e-smith.com>
|
||||
- [1.15.0-05]
|
||||
- Add esmith::DB::Merge library [tonyc 10569]
|
||||
|
||||
* Fri Oct 10 2003 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-04]
|
||||
- Fixed AccountsDB.pm to handle group names with hyphens and periods, to match
|
||||
the error message in the groups panel, and the rest of the group/user
|
||||
behaviour. [msoulier 10236]
|
||||
|
||||
* Sun Sep 21 2003 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.0-03]
|
||||
- Skip any directries when iterating over action scripts in esmith::event.
|
||||
Add logfile timestamp symlinking to generic_template_expand action.
|
||||
Use templates2expand and logfiles2timestamp subdirectories of the event
|
||||
directory. Fix shebang line. [charlieb 10035]
|
||||
|
||||
* Thu Sep 18 2003 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.0-02]
|
||||
- Add generic_template_expand action. [charlieb 10035]
|
||||
|
||||
* Thu Sep 18 2003 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.0-01]
|
||||
- Changing version to development stream number - 1.15.0
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%pre
|
||||
#--------------------------------------------------
|
||||
# add admin, public and www user accounts
|
||||
#--------------------------------------------------
|
||||
/usr/sbin/groupadd \
|
||||
-g 500 shared 2>/dev/null || :
|
||||
/usr/sbin/useradd \
|
||||
-u 102 -c 'e-smith web server' -d /home/e-smith \
|
||||
-G shared -M -s /bin/false www 2>/dev/null || :
|
||||
/usr/sbin/useradd \
|
||||
-u 101 -c 'e-smith administrator' -d /home/e-smith \
|
||||
-G shared,root,www -M -s /sbin/e-smith/console admin 2>/dev/null || :
|
||||
/usr/sbin/useradd \
|
||||
-u 103 -c 'e-smith guest' -d /home/e-smith \
|
||||
-G shared -M -s /bin/false public 2>/dev/null || :
|
||||
/usr/sbin/useradd \
|
||||
-u 1002 -c 'sme log user' -d /var/log/smelog \
|
||||
-M -s /bin/false smelog 2>/dev/null || :
|
||||
|
||||
exit 0
|
||||
|
||||
%post
|
||||
|
||||
%build
|
||||
for event in post-install post-upgrade bootstrap-console-save console-save
|
||||
do
|
||||
mkdir -p root/etc/e-smith/events/$event
|
||||
done
|
||||
perl createlinks
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
(cd root ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT)
|
||||
rm -f %{name}-%{version}-%{release}-filelist
|
||||
/sbin/e-smith/genfilelist $RPM_BUILD_ROOT \
|
||||
>%{name}-%{version}-%{release}-filelist
|
||||
echo "%doc Copying" >> %{name}-%{version}-%{release}-filelist
|
||||
echo "%doc Artistic" >> %{name}-%{version}-%{release}-filelist
|
||||
echo "%doc LICENSE" >> %{name}-%{version}-%{release}-filelist
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files -f %{name}-%{version}-%{release}-filelist
|
||||
%defattr(-,root,root)
|
1
contriborbase
Normal file
1
contriborbase
Normal file
@ -0,0 +1 @@
|
||||
sme10
|
38
createlinks
Normal file
38
createlinks
Normal file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/perl -w
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright (c) 2001 Mitel Networks Corporation
|
||||
#
|
||||
# Technical support for this program is available from Mitel Networks
|
||||
# Corporation. Please visit our web site www.e-smith.com for details.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub panel_link
|
||||
{
|
||||
my ($function, $panel) = @_;
|
||||
|
||||
unlink "root/etc/e-smith/web/panels/$panel/cgi-bin/$function";
|
||||
symlink("../../../functions/$function",
|
||||
"root/etc/e-smith/web/panels/$panel/cgi-bin/$function")
|
||||
or die "Can't symlink to root/etc/e-smith/web/panels/$panel".
|
||||
"/cgi-bin/$function: $!";
|
||||
}
|
||||
|
||||
sub event_link
|
||||
{
|
||||
my ($action, $event, $level) = @_;
|
||||
|
||||
unlink "root/etc/e-smith/events/${event}/S${level}${action}";
|
||||
symlink("../actions/${action}",
|
||||
"root/etc/e-smith/events/${event}/S${level}${action}")
|
||||
or die "Can't symlink to " .
|
||||
"root/etc/e-smith/events/${event}/S${level}${action}: $!";
|
||||
}
|
||||
|
||||
#--------------------------------------------------
|
||||
# actions for events
|
||||
#--------------------------------------------------
|
||||
|
||||
foreach my $event (qw(post-install post-upgrade bootstrap-console-save console-save))
|
||||
{
|
||||
event_link("initialize-default-databases", $event, "00");
|
||||
}
|
902
e-smith-lib.spec
Normal file
902
e-smith-lib.spec
Normal file
@ -0,0 +1,902 @@
|
||||
# $Id: e-smith-lib.spec,v 1.20 2023/07/11 02:49:10 trevorb Exp $
|
||||
|
||||
%define copykooz 2013-2021
|
||||
|
||||
Summary: e-smith server and gateway - library module
|
||||
%define name e-smith-lib
|
||||
Name: %{name}
|
||||
%define version 2.6.0
|
||||
%define release 17
|
||||
Version: %{version}
|
||||
Release: %{release}%{?dist}
|
||||
License: Artistic
|
||||
Group: Networking/Daemons
|
||||
Source: %{name}-%{version}.tar.xz
|
||||
|
||||
BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot
|
||||
BuildArchitectures: noarch
|
||||
BuildRequires: e-smith-devtools >= 1.6.3-01
|
||||
Obsoletes: %{name}-Tai64n
|
||||
Obsoletes: whiptail
|
||||
Requires(pre): e-smith
|
||||
Requires: dialog
|
||||
Requires: perl, perl(Text::Template)
|
||||
Requires: perl(Time::HiRes), perl(MIME::Base64)
|
||||
Requires: perl(Authen::PAM), perl(I18N::AcceptLanguage)
|
||||
Requires: perl(I18N::LangTags) >= 0.27
|
||||
Requires: perl(Net::IPv4Addr) >= 0.10
|
||||
Requires: perl(Taint::Util)
|
||||
Requires: pciutils
|
||||
|
||||
%description
|
||||
e-smith server and gateway software - library module.
|
||||
|
||||
%changelog
|
||||
* Wed Jul 12 2023 cvs2git.sh aka Brian Read <brianr@koozali.org> 2.6.0-17.sme
|
||||
- Roll up patches and move to git repo [SME: 12338]
|
||||
- Remove create e-smith-lib-update event [SME: 12338]
|
||||
|
||||
* Wed Jul 12 2023 BogusDateBot
|
||||
- Eliminated rpmbuild "bogus date" warnings due to inconsistent weekday,
|
||||
by assuming the date is correct and changing the weekday.
|
||||
|
||||
* Wed Nov 23 2022 Jean-Philippe Pialasse <tests@pialasse.com> 2.6.0-16.sme
|
||||
- allow call to systemctl aliases in etc [SME: 12194]
|
||||
fix network=>networking service is not restarted.
|
||||
|
||||
* Thu Oct 28 2021 Jean-Philippe Pialasse <tests@pialasse.com> 2.6.0-15.sme
|
||||
- add support for service with instances [SME: 11723]
|
||||
|
||||
* Mon Apr 19 2021 Jean-Philippe Pialasse <tests@pialasse.com> 2.6.0-14.sme
|
||||
- update copyright dates, and make it easier to change from spec file [SME: 11570]
|
||||
|
||||
* Sat Jan 02 2021 Jean-Philipe Pialasse <tests@pialasse.com> 2.6.0-13.sme
|
||||
- partial revert of signals [SME: 11177]
|
||||
signal s not passed to runit services (dnscache*, qmail, qpsmtpd...)
|
||||
services handled by systemd crash if they do not have Restart=always defined
|
||||
|
||||
* Fri Jan 01 2021 Jean-Philipe Pialasse <tests@pialasse.com> 2.6.0-12.sme
|
||||
- add support for signals SIG* with systemd [SME: 11177]
|
||||
fix typo for reload-or-try-restart
|
||||
unsupervised services: really stop when disabled and start stopped enabled ones
|
||||
|
||||
* Thu Nov 26 2020 Jean-Philipe Pialasse <tests@pialasse.com> 2.6.0-11.sme
|
||||
- remove error when sending sighup event [SME: 11177]
|
||||
|
||||
* Tue Nov 17 2020 Jean-Philipe Pialasse <tests@pialasse.com> 2.6.0-10.sme
|
||||
- allow more systemctl controls [SME: 11177]
|
||||
convert unrecognized signals from service2adjust in events for systemd
|
||||
handle unsupervised services the same way supervised were in adjust-services
|
||||
- create e-smith-lib-event [SME: 11141]
|
||||
|
||||
* Thu Dec 12 2019 Jean-Philipe Pialasse <tests@pialasse.com> 2.6.0-9.sme
|
||||
- add support for systemctl reload-or-restart, try-restart, enable -now [SME: 10848]
|
||||
|
||||
* Wed Oct 25 2017 Daniel Berteaud <daniel@firewall-services.com> 2.6.0-8.sme
|
||||
- Revert prev change regarding tap_soft, as it's not needed [SME: 10445]
|
||||
|
||||
* Mon Oct 23 2017 Daniel Berteaud <daniel@firewall-services.com> 2.6.0-7.sme
|
||||
- Skip tap_soft interfaces (eg SoftEther, code from Hsing-Foo Wang)
|
||||
[SME: 10445]
|
||||
|
||||
* Wed Apr 12 2017 Jean-Philipe Pialasse <tests@pialasse.com> 2.6.0-6.sme
|
||||
- remove reference to smtpd in configuration.conf [SME: 9478]
|
||||
|
||||
* Thu Aug 04 2016 Jean-Philipe Pialasse <tests@pialasse.com> 2.6.0-5.sme
|
||||
- fix console startup display [SME: 9352]
|
||||
|
||||
* Sat Jul 23 2016 Jean-Philipe Pialasse <tests@pialasse.com> 2.6.0-4.sme
|
||||
- fix service name syslog to rsyslog [SME: 9691]
|
||||
|
||||
* Mon Jul 18 2016 Jean-Philipe Pialasse <tests@pialasse.com> 2.6.0-3.sme
|
||||
- fix mysqld to mariadb [SME: 9438]
|
||||
- Eliminated rpmbuild "bogus date" warnings due to inconsistent weekday,
|
||||
by assuming the date is correct and changing the weekday.
|
||||
Sat Dec 25 2005 --> Sat Dec 24 2005 or Sun Dec 25 2005 or Sat Dec 31 2005 or ....
|
||||
Tue Dec 15 2006 --> Tue Dec 12 2006 or Fri Dec 15 2006 or Tue Dec 19 2006 or ....
|
||||
|
||||
* Thu Jul 14 2016 stephane de Labrusse <stephdl@de-labrusse.fr> 2.6.0-2.sme
|
||||
- fix esmith::util::serviceControl to manage systemd service [SME: 9660]
|
||||
- Added e-smith-lib-2.6.0.bz9660.serviceControlSystemd.patch
|
||||
|
||||
* Fri Feb 05 2016 stephane de Labrusse <stephdl@de-labrusse.fr> 2.6.0-1.sme
|
||||
- Initial release to sme10
|
||||
|
||||
* Tue Jan 12 2016 Daniel Berteaud <daniel@firewall-services.com> 2.4.0-16.sme
|
||||
- Adjust regex so adjust-service accepts sigusr1 and sigusr2 from files
|
||||
[SME: 9184]
|
||||
|
||||
* Thu Jun 18 2015 stephane de Labrusse <stephdl@de-labrusse.fr> 2.4.0-15.sme
|
||||
- Added a password creation (set_secret) [SME: 8943]
|
||||
- code from Charlie Brady <charlieb-contribs-bugzilla@budge.apana.org.au>
|
||||
|
||||
* Sat Apr 5 2014 Ian Wells <esmith@wellsi.com> 2.4.0-14.sme
|
||||
- Untaint the license filename [SME: 8305]
|
||||
- Non-functional perl::Critic changes.
|
||||
|
||||
* Sun Mar 16 2014 Ian Wells <esmith@wellsi.com> 2.4.0-13.sme
|
||||
- Add textbox() to console.pm, getLicenseFile to util.pm [SME: 8264]
|
||||
|
||||
* Sun Feb 2 2014 Ian Wells <esmith@wellsi.com> 2.4.0-12.sme
|
||||
- Update frame header and footer [SME: 8183]
|
||||
|
||||
* Sat Nov 30 2013 Daniel Berteaud <daniel@firewall-services.com> 2.4.0-11.sme
|
||||
- Remove the "swap interface" feature [SME: 7993]
|
||||
|
||||
* Sat Nov 30 2013 Daniel Berteaud <daniel@firewall-services.com> 2.4.0-10.sme
|
||||
- Return nic names in probeAdapters so we can drop HWAddress [SME: 7991]
|
||||
|
||||
* Sat May 25 2013 Ian Wells <esmith@wellsi.com> 2.4.0-9.sme
|
||||
- Correctly display accented letters in the console [SME: 7591]
|
||||
by Filippo Carletti
|
||||
|
||||
* Sun May 05 2013 Ian Wells <esmith@wellsi.com> 2.4.0-8.sme
|
||||
- Add e-smith as a Requires(pre) and remove adding users in %pre
|
||||
- Fix uid and gid to be the same in create-system-user [SME: 7547]
|
||||
|
||||
* Sat Mar 9 2013 Shad L. Lords <slords@mail.com> 2.4.0-7.sme
|
||||
- Ensure group www exists before user [SME: 7319]
|
||||
|
||||
* Wed Mar 6 2013 Shad L. Lords <slords@mail.com> 2.4.0-6.sme
|
||||
- Fix pre script to make www and apache the same [SME: 7319]
|
||||
|
||||
* Tue Mar 5 2013 Daniel Berteaud <daniel@firewall-services.com> 2.4.0-5.sme
|
||||
- Untaint variable in probeAdapters() [SME: 7416]
|
||||
|
||||
* Thu Feb 28 2013 Ian Wells <esmith@wellsi.com> 2.4.0-4.sme
|
||||
- Improve error checking in isValidIP [SME: 7410]
|
||||
|
||||
* Sun Feb 24 2013 Daniel Berteaud <daniel@firewall-services.com> 2.4.0-3.sme
|
||||
- Fix MAC detection for bond slaves [SME: 3596]
|
||||
|
||||
* Thu Jan 31 2013 Daniel Berteaud <daniel@firewall-services.com> 2.4.0-2.sme
|
||||
- Stop using kudzu for NIC detection [SME: 3596]
|
||||
|
||||
* Fri Jan 25 2013 Shad L. Lords <slords@mail.com> 2.4.0-1.sme
|
||||
- Bump version in prep for SME9
|
||||
- Perl module rpms moved to /usr/share/perl5/vendor_perl [SME: 7223]
|
||||
|
||||
* Mon Oct 11 2010 Shad L. Lords <slords@mail.com> 2.2.0-7.sme
|
||||
- Serialize configure_peers to prevent errors [SME: 5831]
|
||||
|
||||
* Fri Feb 5 2010 Stephen Noble <support@dungog.net> 2.2.0-6.sme
|
||||
- adds the hwaddr parameter to probeAdapters() [SME: 4528]
|
||||
|
||||
* Thu Feb 4 2010 Shad L. Lords <slords@mail.com> 2.2.0-5.sme
|
||||
- Update path for 64-bit compatibility [SME: 5756]
|
||||
|
||||
* Tue Dec 22 2009 Filippo Carletti <filippo.carletti@gmail.com> 2.2.0-4.sme
|
||||
- Really apply previous patch in the spec file. [SME: 5659]
|
||||
|
||||
* Wed Dec 9 2009 Charlie Brady <charlieb@budge.apana.org.au> 2.2.0-3.sme
|
||||
- Add patch (Federico Simoncelli) to prevent re-use of uids. [SME: 5659]
|
||||
|
||||
* Mon Oct 13 2008 Shad L. Lords <slords@mail.com> 2.2.0-2.sme
|
||||
- Add patch to support multiple samba roles [SME: 4172]
|
||||
|
||||
* Tue Oct 7 2008 Shad L. Lords <slords@mail.com> 2.2.0-1.sme
|
||||
- Roll new stream to separate sme7/sme8 trees [SME: 4633]
|
||||
|
||||
* Wed Aug 20 2008 Shad L. Lords <slords@mail.com> 1.19.0-1
|
||||
- Roll new dev stream.
|
||||
|
||||
* Sat Aug 9 2008 Shad L. Lords <slords@mail.com> 1.18.0-28
|
||||
- Read /dev/urandmon instead of /dev/random [SME: 4492]
|
||||
|
||||
* Sat Aug 9 2008 Shad L. Lords <slords@mail.com> 1.18.0-27
|
||||
- Make dialog not use STDERR for return values [SME: 3663]
|
||||
- Remove requires for whiptail. No longer needed [SME: 4491]
|
||||
|
||||
* Thu Jul 31 2008 Shad L. Lords <slords@mail.com> 1.18.0-26
|
||||
- Make binmode properties of db class [SME: 4317]
|
||||
- Add new navigation db & utf8 classes [SME: 4317]
|
||||
|
||||
* Wed Apr 2 2008 Shad L. Lords <slords@mail.com> 1.18.0-25
|
||||
- Add .utf8 to locale unless server-console [SME: 4162]
|
||||
- Add new languages to langtag2locale [SME: 4163]
|
||||
|
||||
* Sun Mar 30 2008 Shad L. Lords <slords@mail.com> 1.18.0-24
|
||||
- Gracefully handle encoding errors in navigation dbs [SME: 4147]
|
||||
|
||||
* Wed Mar 26 2008 Shad L. Lords <slords@mail.com> 1.18.0-23
|
||||
- Make PAM conv routine not look for english strings [SME: 4117]
|
||||
|
||||
* Tue Mar 25 2008 Shad L. Lords <slords@mail.com> 1.18.0-22
|
||||
- Fix wide output to syslog and allow navigations db to be utf8 [SME: 4101]
|
||||
|
||||
* Mon Mar 10 2008 Shad L. Lords <slords@mail.com> 1.18.0-21
|
||||
- Output navigation in UTF-8 [SME: 3858]
|
||||
|
||||
* Sun Jan 20 2008 Gavin Weight <gweight@gmail.com> 1.18.0-20
|
||||
- Call smbpasswd -e - to reset user correctly. [SME: 3755]
|
||||
|
||||
* Tue Jan 08 2008 Stephen Noble <support@dungog.net> 1.18.0-19
|
||||
- modify validate password strong match for console [SME: 2173]
|
||||
|
||||
* Thu Nov 01 2007 Gavin Weight <gweight@gmail.com> 1.18.0-18
|
||||
- Fix I18N.pm file descriptor leak. [SME: 3509]
|
||||
|
||||
* Wed Oct 31 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-17
|
||||
- Remove undocumented and unused template metadata handling from
|
||||
generic_template_expand action (Take II). [SME: 2798]
|
||||
|
||||
* Fri Jun 1 2007 Shad L. Lords <slords@mail.com> 1.18.0-16
|
||||
- pam_unix requires passwords >= 6 [SME: 3039]
|
||||
|
||||
* Mon May 21 2007 Shad L. Lords <slords@mail.com> 1.18.0-15
|
||||
- Fix ip addr shift to work on 64-bit
|
||||
|
||||
* Sun Apr 29 2007 Shad L. Lords <slords@mail.com>
|
||||
- Clean up spec so package can be built by koji/plague
|
||||
|
||||
* Thu Apr 05 2007 Shad L. Lords <slords@mail.com> 1.18.0-14
|
||||
- Reverse changes for 1.18.0-12 as it is being used. [SME: 2838]
|
||||
|
||||
* Wed Apr 04 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-13
|
||||
- Allow gauge console widget to be used without following message_page.
|
||||
[SME: 2832].
|
||||
|
||||
* Mon Mar 26 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-12
|
||||
- Remove undocumented and unused template metadata handling from
|
||||
generic_template_expand action. [SME: 2798]
|
||||
|
||||
* Mon Mar 26 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-11
|
||||
- Split logfile rotation code out of generic_template_expand.
|
||||
Code moved to a new action in e-smith-base. [SME: 2795]
|
||||
|
||||
* Mon Mar 19 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-10
|
||||
Don't try to read template.metadata from subdirectories (affects
|
||||
initialize_database_defaults). [SME: 2690]
|
||||
|
||||
* Fri Mar 16 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-9
|
||||
- Allow template.metadata to be provided via a directory of
|
||||
small files. [SME: 2690]
|
||||
- Add support for a DELETE boolean template.metadata item. [SME: 2691]
|
||||
|
||||
* Wed Feb 28 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-8
|
||||
- Add gauge widget to esmith::console. [SME: 2579]
|
||||
|
||||
* Sun Feb 25 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-7
|
||||
- Default infobox height to 8 rows, and allow override via params.
|
||||
[SME: 2560]
|
||||
|
||||
* Fri Feb 23 2007 Shad L. Lords <slords@mail.com> 1.18.0-6
|
||||
- Really fix clear parameter for inputbox dialog screen [SME: 2533]
|
||||
|
||||
* Fri Feb 23 2007 Shad L. Lords <slords@mail.com> 1.18.0-5
|
||||
- Fix clear parameter for dialog screens [SME: 2533]
|
||||
|
||||
* Thu Feb 22 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-4
|
||||
- switch esmith::console::password_page() to use dialog rather than
|
||||
whiptail. [SME: 2534]
|
||||
|
||||
* Thu Feb 22 2007 Charlie Brady <charlie_brady@mitel.com> 1.18.0-3
|
||||
- Add infobox widget. [SME: 2533]
|
||||
|
||||
* Sun Jan 28 2007 Shad L. Lords <slords@mail.com> 1.18.0-2
|
||||
- Fix backtitle spacing for new dialog menus [SME: 2328]
|
||||
|
||||
* Fri Jan 26 2007 Shad L. Lords <slords@mail.com> 1.18.0-1
|
||||
- Roll stable stream. [SME: 2328]
|
||||
|
||||
* Fri Dec 15 2006 Federico Simoncelli <federico.simoncelli@gmail.com> 1.17.0-8
|
||||
Tue Dec 15 2006 --> Tue Dec 12 2006 or Fri Dec 15 2006 or Tue Dec 19 2006 or ....
|
||||
- Added the validatePassword function to esmith::util. [SME: 2100]
|
||||
|
||||
* Thu Dec 07 2006 Shad L. Lords <slords@mail.com>
|
||||
- Update to new release naming. No functional changes.
|
||||
- Make Packager generic
|
||||
|
||||
* Fri Nov 24 2006 Gordon Rowell <gordonr@gormand.com.au> 1.17.0-06
|
||||
- Allow optional path to peeers directory in
|
||||
esmith::tcpsvd::configure_peers() [SME: 2086]
|
||||
|
||||
* Tue Nov 14 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-05
|
||||
- Allow defaulno option to esmith::console::yesno.
|
||||
- Fix I/O redirection in esmith::console::new.
|
||||
|
||||
* Tue Nov 07 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-04
|
||||
- Allow display of "0" in iesmith::cgi::genSmallCell. [SME: 2038]
|
||||
|
||||
* Mon Oct 23 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-03
|
||||
- Make dialog the default console app, with whiptail used only when
|
||||
required.
|
||||
|
||||
* Wed Oct 11 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-02
|
||||
- Allow 'dialog' to be called from esmith::console. [SME: 1958]
|
||||
|
||||
* Wed Oct 11 2006 Charlie Brady <charlie_brady@mitel.com> 1.17.0-01
|
||||
- Roll development branch.
|
||||
|
||||
* Mon Sep 25 2006 Charlie Brady <charlie_brady@mitel.com> 1.16.0-06
|
||||
- Fix problem with greedy RE in template.metadata parsing. [SME: 1906]
|
||||
|
||||
* Fri Sep 08 2006 Charlie Brady <charlie_brady@mitel.com> 1.16.0-05
|
||||
- Fix taint problem in template.metadata handling. [SME: 1906]
|
||||
|
||||
* Thu Apr 13 2006 Charlie Brady <charlie_brady@mitel.com> 1.16.0-04
|
||||
- Use "kudzu --probe --class network" for NIC detection. [SME: 727]
|
||||
|
||||
* Fri Apr 7 2006 Gordon Rowell <gordonr@gormand.com.au> 1.16.0-03
|
||||
- Don't call smbpasswd -e - setting the password is sufficient [SME: 1193]
|
||||
|
||||
* Tue Mar 28 2006 Gordon Rowell <gordonr@gormand.com.au> 1.16.0-02
|
||||
- Log previous contents of db entry in DELETE log [SME: 1066]
|
||||
|
||||
* Tue Mar 14 2006 Charlie Brady <charlie_brady@mitel.com> 1.16.0-01
|
||||
- Roll to stable stream version number. [SME: 1016]
|
||||
|
||||
* Fri Mar 10 2006 Charlie Brady <charlie_brady@mitel.com> 1.15.4-02
|
||||
- Suppress warning from genSmallCell if text is undefined. [SME: 986]
|
||||
|
||||
* Fri Feb 17 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.4-01
|
||||
- Roll patches up to 1.15.3-42
|
||||
- Trim changelog prior to 1.15.0-01 [SME: 828]
|
||||
|
||||
* Thu Feb 16 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-42
|
||||
- Adjust console title bar to 'SME Server' [SME: 726]
|
||||
|
||||
* Tue Feb 14 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-41
|
||||
- Reworded text for template-begin and change URL to /development/
|
||||
rather than /custom/ [SME: 773]
|
||||
|
||||
* Mon Feb 13 2006 Charlie Brady <charlie_brady@mitel.com> 1.15.3-40
|
||||
- Update URL in default template-begin fragment. [SME: 773]
|
||||
|
||||
* Sat Feb 11 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-39
|
||||
- Remove obsolete e-smith-lib-Tai64n package. [SME: 689]
|
||||
|
||||
* Sat Feb 11 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-38
|
||||
- [Null changelog for missing version - we accidentally skipped
|
||||
this version.]
|
||||
|
||||
* Sat Feb 11 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-37
|
||||
- Fix get_all_by_prop in scalar context. [SME: 669,721]
|
||||
|
||||
* Mon Feb 6 2006 Shad L. Lords <slords@mail.com> 1.15.3-37
|
||||
- Add ability to pass many props to get_all_by_prop [SME: 669]
|
||||
|
||||
* Mon Jan 23 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-36
|
||||
- Fix warning during pseudonym deletion. [SME: 491]
|
||||
|
||||
* Fri Jan 20 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-35
|
||||
- Fix up use of Sys::Syslog::syslog. [SME: 526]
|
||||
|
||||
* Thu Jan 19 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-34
|
||||
- Remove running of kudzu during NIC probing. TODO: Find a solution
|
||||
to system reconfiguration when new hardware is added. [SME: 192]
|
||||
|
||||
* Tue Jan 10 2006 Charlie Brady <charlieb@e-smith.com> 1.15.3-33
|
||||
- Fold a.b.c.d/255.255.255.255 to a.b.c.d in local_access_spec() to
|
||||
work around bugs in applications which don't accept such specs.
|
||||
[SME: 430]
|
||||
|
||||
* Mon Jan 9 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-32
|
||||
- Check whether an accounts db record exists before trying to create
|
||||
the dot and underscore pseudonyms (new_record will fail silently)
|
||||
and check that the records are pseudonyms before deleting them [SME: 24]
|
||||
|
||||
* Mon Jan 9 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-31
|
||||
- And update POD for last change [SME: 24]
|
||||
|
||||
* Mon Jan 9 2006 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-30
|
||||
- Allow dot and underscore in account names [SME: 24]
|
||||
|
||||
* Tue Dec 27 2005 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-29
|
||||
- Remove newlines from cluck() string and just note that the old
|
||||
path was used [SME: 365]
|
||||
|
||||
* Sun Dec 25 2005 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-28
|
||||
Sat Dec 25 2005 --> Sat Dec 24 2005 or Sun Dec 25 2005 or Sat Dec 31 2005 or ....
|
||||
- If db exists in both the old and new locations in
|
||||
initialize_default_databases, rename the one in the new
|
||||
location to db.time(), avoiding the conflict and saving the
|
||||
evidence in case it is needed later [SME: 229]
|
||||
|
||||
* Mon Dec 05 2005 Mark Knox <mark_knox@mitel.com>
|
||||
- [1.15.3-27]
|
||||
- Moved queueing logic to separate daemon, replaced with FIFO IPC [BZ252
|
||||
|
||||
* Thu Dec 01 2005 Mark Knox <mark_knox@mitel.com>
|
||||
- [1.15.3-26]
|
||||
- Added event queueing (open source portion) for clustered systems [BZ250]
|
||||
|
||||
* Wed Nov 30 2005 Gordon Rowell <gordonr@gormand.com.au> 1.15.3-25
|
||||
- Bump release number only
|
||||
|
||||
* Thu Nov 24 2005 Gordon Rowell <gordonr@e-smith.com>
|
||||
- [1.15.3-24]
|
||||
- Add missing 'use Locale::gettext' to esmith::console.pm [MN00108804]
|
||||
|
||||
* Sun Nov 20 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-23]
|
||||
- Clarify logic for stopped services in adjust-services. [SF: 1357629]
|
||||
|
||||
* Sun Nov 20 2005 Gordon Rowell <gordonr@e-smith.com>
|
||||
- [1.15.3-22]
|
||||
- Correct adjust-services logic for stopped services [SF: 1357629]
|
||||
|
||||
* Wed Nov 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-21]
|
||||
- Allow services2adjust directories to contain files rather than just dangling
|
||||
symlinks. Files can contain more than one actions to perform. [SF: 1270644]
|
||||
|
||||
* Wed Nov 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-20]
|
||||
- Also don't start services if we just want to "once" them. [SF: 1357629]
|
||||
|
||||
* Wed Nov 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-19]
|
||||
- Fix restart of enabled supervised services which we are attempting to stop.
|
||||
[SF: 1357629]
|
||||
|
||||
* Tue Nov 15 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-18]
|
||||
- Set default for $type in esmith::cgi::genSmallCell, to prevent some log
|
||||
noise. [SF: 1357830]
|
||||
|
||||
* Tue Nov 15 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-17]
|
||||
- Pass $EVENT to template expansions in generic_template_expand.
|
||||
[SF: MN00106104]
|
||||
|
||||
* Tue Nov 15 2005 Gordon Rowell <gordonr@e-smith.com>
|
||||
- [1.15.3-16]
|
||||
- Redirect esmith::config calls on old db paths to the new
|
||||
location [SF: 1335865]
|
||||
|
||||
* Thu Oct 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-15]
|
||||
- Fix a few minor spec file portability issues. [SF: 1339729]
|
||||
|
||||
* Wed Oct 26 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-14]
|
||||
- Add it and de to the langtag2locale fixups. [SF: 1338236]
|
||||
|
||||
* Tue Oct 11 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-13]
|
||||
- Build driver list from .ko files as well as .o files. Untaint driver
|
||||
names while building list. [SF: 1323270]
|
||||
|
||||
* Mon Sep 26 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-12]
|
||||
- Fix "defaults" handling so that values which evaluate to false are
|
||||
not overridden by default. [SF: 1303885]
|
||||
|
||||
* Fri Sep 23 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-11]
|
||||
- Untaint db names before attempting to move them. [MN00098405]
|
||||
|
||||
* Thu Sep 22 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-10]
|
||||
- Provide networks method in esmith::NetworksDB. [SF: 1296099]
|
||||
- Support a "localhost" configuration in esmith::tcpsvd:configure_peers
|
||||
[SF: 1294719]
|
||||
|
||||
* Tue Sep 20 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-09]
|
||||
- Remove deprecated functions from esmith::utils. [SF: 1295851]
|
||||
- Include only "network" records in local_access_spec. [SF: 1296099]
|
||||
|
||||
* Mon Sep 12 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-08]
|
||||
- Remove warning about explicit path in esmith::db::_db_path.
|
||||
[SF: 1286294]
|
||||
|
||||
* Fri Sep 9 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-07]
|
||||
- Tolerate, but warn about, symlinks in /home/e-smith. [SF: 1216546]
|
||||
|
||||
* Fri Sep 9 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-06]
|
||||
- Reduce the noise from _file_path() in esmith::DB::db. [SF: 1286294]
|
||||
|
||||
* Wed Sep 7 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-05]
|
||||
- Fix operation of expandTemplate when taint check is enabled.
|
||||
[SF: 1284301]
|
||||
|
||||
* Wed Aug 17 2005 Mark Knox <markk@e-smith.com>
|
||||
- [1.15.3-04]
|
||||
- Added open_local and open_ro_local methods for clustering [markk MN00094831]
|
||||
|
||||
* Tue Aug 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-03]
|
||||
- Fix POD error in util.pm.
|
||||
|
||||
* Wed Jul 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-02]
|
||||
- Move databases default location from /home/e-smith to /home/e-smith/db.
|
||||
During esmith::utils::initialize_default_databases, move from old to new
|
||||
location before doing db migrate actions. [SF: 1216546]
|
||||
|
||||
* Wed Jul 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.3-01]
|
||||
- Roll a new development stream - 1.15.3
|
||||
|
||||
* Wed Jul 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.2-04]
|
||||
- Remove broken MergeDB stuff. [SF: 1246315]
|
||||
|
||||
* Wed Jul 27 2005 Mark Knox <markk@e-smith.com>
|
||||
- [1.15.2-03]
|
||||
- Fixed misleading comment in util.pm
|
||||
- Added 'use' statements in Record classes for SOAP compatibility
|
||||
- Fixed undefined max_len warning
|
||||
- Added explicit writeconf calls in db::Record.pm, needed for setting props
|
||||
via SOAP
|
||||
|
||||
* Tue Jul 19 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.2-02]
|
||||
- Allow db open API to use default path if a simple filename
|
||||
is provided as arg. This is preparation for move of dbs to
|
||||
/home/e-smith/db. Patch by Shad Lords.
|
||||
|
||||
* Mon Jul 18 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.2-01]
|
||||
- Roll new development stream - 1.15.2
|
||||
|
||||
* Fri Jul 15 2005 Mark Knox <markk@e-smith.com>
|
||||
- [1.15.1-44]
|
||||
- Tweak to allow calling _writeconf from SOAP [markk MN00090738]
|
||||
|
||||
* Tue Jun 21 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-43]
|
||||
- Ensure that esmith::util::LdapPassword returns bare string without
|
||||
newline terminator.
|
||||
|
||||
* Sun Jun 12 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-42]
|
||||
- Remove .rpmsave and .rpmnew symlinks (as well as files). [SF: 1217969]
|
||||
- Handle missing description in pcitables entries.
|
||||
|
||||
* Sun Jun 12 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-41]
|
||||
- Provide feedback (via log messages) from services2adjust. [SF: 1218920]
|
||||
|
||||
* Mon May 30 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-40]
|
||||
- Add preinstall scripting to create required accounts/groups if they
|
||||
don't already exist. [SF: 1210723]
|
||||
|
||||
* Thu May 5 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-39]
|
||||
- Show Text::Template error text rather than inappropriate $! if template
|
||||
expansion fails.
|
||||
- Change error to warning if a config item is set with an empty "type"
|
||||
property.
|
||||
|
||||
* Thu May 5 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-38]
|
||||
- Fix esmith::DB::get_prop_and_delete fail if prop is "false" [From Gordon].
|
||||
|
||||
* Tue May 3 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-37]
|
||||
- Update directory list so that ethernet drivers from kernel-unsupported are
|
||||
added to "choose by driver" list.
|
||||
|
||||
* Sat Mar 19 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-36]
|
||||
- Rework esmith::tcpsvd::configure_peers so that it doesn't chdir.
|
||||
- Fix generic_template_expand so that templates.metadata doesn't
|
||||
need to set OUTPUT_FILENAME is TEMPLATE_PATH is changed. This
|
||||
matches what expand-template already does.
|
||||
|
||||
* Fri Mar 18 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-35]
|
||||
- Change numerous calls to "croak" in esmith::template
|
||||
to "carp ...; return", so that problem with any single
|
||||
template expansion doesn't terminate calling program.
|
||||
[MN00075009]
|
||||
|
||||
* Wed Mar 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-34]
|
||||
- Add missing "use esmith::util" in esmith::tcpsvd.
|
||||
|
||||
* Wed Mar 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-33]
|
||||
- Add esmith::tcpsvd library for managing tcpsvd "peers"
|
||||
directories.
|
||||
|
||||
* Mon Mar 14 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-32]
|
||||
- Make template expansion message more succinct.
|
||||
|
||||
* Thu Mar 10 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-31]
|
||||
- Remove pseudonyms of pseudonyms when removing user
|
||||
accounts. Adapted from patch submitted by Shad. [MN00039941]
|
||||
|
||||
* Wed Feb 23 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-30]
|
||||
- Fix incompatibility with CentOS's CGI.pm.
|
||||
|
||||
* Tue Feb 22 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-29]
|
||||
- Fix bug in output to empty file when FILTER is used
|
||||
during template expansion. [charlieb MN00050075]
|
||||
|
||||
* Tue Feb 22 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-28]
|
||||
- Refresh contents of /etc/sysconfig/hwconf before listing
|
||||
network adaptors [MN00069993]
|
||||
- Fix typo in documentation of esmith::DB::db - reported from Tanna -
|
||||
http://www.livejournal.com/users/gcrumb/61169.html (thanks Dan!)
|
||||
|
||||
* Wed Feb 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-27]
|
||||
- Fix typo. [MN00066059]
|
||||
|
||||
* Wed Feb 16 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-26]
|
||||
- Use /sbin/e-smith/whiptail if it is available. [MN00066059]
|
||||
|
||||
* Mon Feb 7 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-25]
|
||||
- Update perms and ownership when expanding templates, regardless of
|
||||
whether file content has changed or not. [MN00068043]
|
||||
|
||||
* Wed Feb 2 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-24]
|
||||
- Fix the insertion of implicit actions into sorted action list in
|
||||
event.pm. Problem was perl syntax ambiguity. [MN00066406]
|
||||
|
||||
* Fri Jan 28 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-23]
|
||||
- Really move /home/e-smith/* to e-smith-base. [MN00066635]
|
||||
|
||||
* Fri Jan 28 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-22]
|
||||
- Move /home/e-smith/* to e-smith-base. [MN00066635]
|
||||
- Move generic-template expand to S05 position in sort, and
|
||||
adjust-service to S90. Fix run-time error. [MN00066406]
|
||||
- Don't attempt to execute non-executable action scripts.
|
||||
|
||||
* Thu Jan 27 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-21]
|
||||
- Implicitly include template expand and services adjust actions
|
||||
in each event if the respective metadata directory exists.
|
||||
[MN00066406]
|
||||
|
||||
* Tue Jan 25 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-20]
|
||||
- Add "adjust" to list of verbs which serviceControl groks,
|
||||
to allow for "masq adjust". [MN00065576]
|
||||
|
||||
* Tue Jan 25 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-19]
|
||||
- Add adjust-services generic action script [MN00065576]
|
||||
|
||||
* Tue Jan 18 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-18]
|
||||
- Fix typo. [MN00064412]
|
||||
- Improve die() message in esmith::config::STORE. [MN00064394]
|
||||
|
||||
* Mon Jan 17 2005 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-17]
|
||||
- Fix broken logging (and reduce logging) in initialize_default_databases.
|
||||
[MN00064412]
|
||||
- Fix inappropriate use of global $_ in initialize_default_databases.
|
||||
[MN00064415]
|
||||
|
||||
* Thu Dec 23 2004 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-16]
|
||||
- Read templated file metadata (if any) from file tree under
|
||||
/etc/e-smith/templates.metadata. Update expand-template to
|
||||
use current API. [MN00061830]
|
||||
|
||||
* Tue Dec 14 2004 Mark Knox <markk@e-smith.com>
|
||||
- [1.15.1-15]
|
||||
- Change copyright date to 2004 [markk MN00060958]
|
||||
|
||||
* Fri Nov 5 2004 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-14]
|
||||
- Fix Authen::PAM dependency header [charlieb MN00040240]
|
||||
- Use kudzu's generated /etc/sysconfig/hwconf file for NIC detection
|
||||
[charlieb MN00056220]
|
||||
|
||||
* Thu Oct 14 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-13]
|
||||
- Updated esmith::ethernet's search code to remove File::Find, as it doesn't
|
||||
get along with taint checking. [msoulier MN00052510]
|
||||
|
||||
* Wed Oct 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-12]
|
||||
- Updated esmith::ethernet's search code such that is it more adaptable, and
|
||||
recurses the directories given. [msoulier MN00052510]
|
||||
|
||||
* Wed Oct 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-11]
|
||||
- Updated esmith::ethernet's search paths for network drivers.
|
||||
[msoulier MN00052510]
|
||||
|
||||
* Mon Oct 4 2004 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-10]
|
||||
- Remove dependency on perl(Filter::Handle) [charlieb MN00050075]
|
||||
|
||||
* Fri Sep 24 2004 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.1-09]
|
||||
- Updated requires with new perl dependencies. [msoulier MN00040240]
|
||||
- Remove "AutoReqProv: no" so that "Provides" headers are auto-generated.
|
||||
[charlieb MN00040240]
|
||||
- Remove anachronistic "require v5.6.0" directives. [charlieb MN00050370]
|
||||
- Avoid use of Filter::Handle in esmith::template. [charlieb MN00050075]
|
||||
|
||||
* Fri Aug 27 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-08]
|
||||
- Added esmith::util::network::isValidEmail function. [msoulier MN00023814]
|
||||
|
||||
* Thu Aug 26 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-07]
|
||||
- Added svdisable to permissible actions in serviceControl.
|
||||
[msoulier MN00043056]
|
||||
|
||||
* Tue Aug 10 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-06]
|
||||
- Fixed new methods. Bad else case. [msoulier MN00044891]
|
||||
|
||||
* Fri Aug 6 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-05]
|
||||
- Added a keys() method. [msoulier MN00041968]
|
||||
|
||||
* Fri Aug 6 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-04]
|
||||
- Added set_prop and set_value methods in esmith::DB. [msoulier MN00044891]
|
||||
|
||||
* Tue Jul 20 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-03]
|
||||
- Undeprecated esmith::util::serviceControl. [msoulier MN00043056]
|
||||
|
||||
* Fri Jun 25 2004 Tony Clayton <apc@e-smith.com>
|
||||
- [1.15.1-02]
|
||||
- Merge language_tag2locale() function from perl-I18N-LangTags [tonyc
|
||||
MN00040170]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.1-01]
|
||||
- Rolling to collect patches.
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-23]
|
||||
- Reordered the create code slightly to catch more errors.
|
||||
[msoulier MN00035059]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-22]
|
||||
- Added yet more error handling and reporting. [msoulier MN00035059]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-21]
|
||||
- Fixed one $Error reference that I missed in the last rev.
|
||||
[msoulier MN00035059]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-20]
|
||||
- Moved error handling from esmith::DB::db to esmith::DB, since it should not
|
||||
be database implementation specific. [msoulier MN00035059]
|
||||
|
||||
* Fri May 28 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-19]
|
||||
- Propagated migration failures up to calling code for reporting to syslog.
|
||||
- Propagated creation failures up to calling code.
|
||||
- Moved lexicon $Error in esmith::DB::db to a class property so it can be used
|
||||
by subclasses. [msoulier MN00035059]
|
||||
|
||||
* Thu May 27 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-18]
|
||||
- Changed print statements to calls to the logger. [msoulier MN00035059]
|
||||
|
||||
* Thu May 27 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-17]
|
||||
- Added print statements to initialize-default-databases for post-install
|
||||
debugging. [msoulier MN00035059]
|
||||
|
||||
* Fri May 7 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-16]
|
||||
- Fixed migrate to report the caught error message. [msoulier MN00032503]
|
||||
|
||||
* Thu May 6 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-15]
|
||||
- Added isValidHostname function to esmith::util::network.
|
||||
[msoulier MN00024212]
|
||||
|
||||
* Fri Feb 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-14]
|
||||
- Greatly simplified the _mysystem function by ripping out open3.
|
||||
[msoulier dpar-20385]
|
||||
|
||||
* Fri Feb 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-13]
|
||||
- Backed-out change in esmith::util, as it's non-trivial there with the exec.
|
||||
Completed update of esmith::event, and separated the esmith::Logger class.
|
||||
[msoulier dpar-20385]
|
||||
|
||||
* Fri Feb 13 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-12]
|
||||
- Removed use of the logger entirely, replacing it with an abstracted
|
||||
interface to the Sys::Syslog module. [msoulier dpar-20385]
|
||||
|
||||
* Thu Jan 8 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-11]
|
||||
- Fixed esmith::util::network::isValidIP() so valid IP substrings no longer
|
||||
return true values. [msoulier 9308]
|
||||
|
||||
* Thu Jan 8 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-10]
|
||||
- Added a check in STORE in esmith::config for invalid attempts to set a value
|
||||
without a type. Also escalated previous warnings for undef key and value to
|
||||
fatal exceptions. [msoulier 7386]
|
||||
|
||||
* Thu Jan 8 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-09]
|
||||
- Now trimming whitespace around keys and values during esmith::config STORE
|
||||
events, to prevent invalid keys and values from being saved. [msoulier 7021]
|
||||
|
||||
* Mon Jan 5 2004 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-08]
|
||||
- Fixed POD around merge_props. [msoulier 9482]
|
||||
|
||||
* Fri Nov 7 2003 Tony Clayton <apc@e-smith.com>
|
||||
- [1.15.0-07]
|
||||
- And again [tonyc 10569]
|
||||
|
||||
* Fri Nov 7 2003 Tony Clayton <apc@e-smith.com>
|
||||
- [1.15.0-06]
|
||||
- Change Merge API a bit, fix pod [tonyc 10569]
|
||||
|
||||
* Fri Nov 7 2003 Tony Clayton <apc@e-smith.com>
|
||||
- [1.15.0-05]
|
||||
- Add esmith::DB::Merge library [tonyc 10569]
|
||||
|
||||
* Fri Oct 10 2003 Michael Soulier <msoulier@e-smith.com>
|
||||
- [1.15.0-04]
|
||||
- Fixed AccountsDB.pm to handle group names with hyphens and periods, to match
|
||||
the error message in the groups panel, and the rest of the group/user
|
||||
behaviour. [msoulier 10236]
|
||||
|
||||
* Sun Sep 21 2003 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.0-03]
|
||||
- Skip any directries when iterating over action scripts in esmith::event.
|
||||
Add logfile timestamp symlinking to generic_template_expand action.
|
||||
Use templates2expand and logfiles2timestamp subdirectories of the event
|
||||
directory. Fix shebang line. [charlieb 10035]
|
||||
|
||||
* Thu Sep 18 2003 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.0-02]
|
||||
- Add generic_template_expand action. [charlieb 10035]
|
||||
|
||||
* Thu Sep 18 2003 Charlie Brady <charlieb@e-smith.com>
|
||||
- [1.15.0-01]
|
||||
- Changing version to development stream number - 1.15.0
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%pre
|
||||
|
||||
|
||||
%post
|
||||
|
||||
%build
|
||||
for event in post-install post-upgrade bootstrap-console-save console-save
|
||||
do
|
||||
mkdir -p root/etc/e-smith/events/$event
|
||||
done
|
||||
perl createlinks
|
||||
find root/ -type f | xargs grep -l ____COPYYEARS____ | xargs sed -i -e 's/____COPYYEARS____/%{copykooz}/g'
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
(cd root ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT)
|
||||
rm -f %{name}-%{version}-%{release}-filelist
|
||||
/sbin/e-smith/genfilelist $RPM_BUILD_ROOT \
|
||||
>%{name}-%{version}-%{release}-filelist
|
||||
echo "%doc Copying" >> %{name}-%{version}-%{release}-filelist
|
||||
echo "%doc Artistic" >> %{name}-%{version}-%{release}-filelist
|
||||
echo "%doc LICENSE" >> %{name}-%{version}-%{release}-filelist
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files -f %{name}-%{version}-%{release}-filelist
|
||||
%defattr(-,root,root)
|
3
root/etc/e-smith/db/configuration/migrate/00openRW
Normal file
3
root/etc/e-smith/db/configuration/migrate/00openRW
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
$DB = esmith::ConfigDB->open(${DB_FILENAME});
|
||||
}
|
146
root/etc/e-smith/events/actions/adjust-services
Executable file
146
root/etc/e-smith/events/actions/adjust-services
Executable file
@ -0,0 +1,146 @@
|
||||
#!/usr/bin/perl -w
|
||||
#----------------------------------------------------------------------
|
||||
# copyright (C) 2005 Mitel Networks Corporation
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#----------------------------------------------------------------------
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use Errno;
|
||||
use DirHandle;
|
||||
|
||||
my $event = shift || die "must give event name parameter";
|
||||
chdir "/etc/e-smith/events/$event" or die "Couldn't chdir to event directory /etc/e-smith/events/$event: $!";
|
||||
my $dh = DirHandle->new("services2adjust");
|
||||
|
||||
exit(0) unless $dh; # Nothing to do
|
||||
|
||||
use esmith::ConfigDB;
|
||||
use esmith::util;
|
||||
|
||||
my %param2char = (
|
||||
down => 'd',
|
||||
stop => 'd',
|
||||
up => 'u',
|
||||
start => 'u',
|
||||
restart => 't',
|
||||
sigterm => 't',
|
||||
adjust => 'h',
|
||||
reload => 'h',
|
||||
sighup => 'h',
|
||||
sigusr1 => '1',
|
||||
sigusr2 => '2',
|
||||
once => 'o',
|
||||
pause => 'p',
|
||||
alarm => 'a',
|
||||
interrupt => 'i',
|
||||
quit => 'q',
|
||||
kill => 'k',
|
||||
exit => 'x',
|
||||
);
|
||||
|
||||
sub adjust_supervised_service
|
||||
{
|
||||
my ($s, @actions) = @_;
|
||||
my $m = "control fifo for service $s: ";
|
||||
unless (open(C, ">/service/$s/supervise/control"))
|
||||
{
|
||||
warn "Couldn't open $m$!";
|
||||
return;
|
||||
}
|
||||
foreach my $p (@actions)
|
||||
{
|
||||
my $c = $param2char{$p};
|
||||
unless ($c)
|
||||
{
|
||||
warn "Unrecognised param $p for service $s\n";
|
||||
next;
|
||||
}
|
||||
warn "adjusting supervised $s ($p)\n";
|
||||
unless (print C $c)
|
||||
{
|
||||
warn "Couldn't write to $m$!";
|
||||
return;
|
||||
}
|
||||
}
|
||||
warn "Couldn't close $m$!" unless close(C);
|
||||
}
|
||||
|
||||
my $conf = esmith::ConfigDB->open_ro || die "Couldn't open config db";
|
||||
|
||||
foreach my $service (grep { !/^\./ } $dh->read())
|
||||
{
|
||||
my $s = $conf->get($service);
|
||||
unless ($s)
|
||||
{
|
||||
warn "No conf db entry for service $service\n";
|
||||
next;
|
||||
}
|
||||
my $f = "services2adjust/$service";
|
||||
|
||||
my @actions;
|
||||
if (-l "$f")
|
||||
{
|
||||
@actions = ( readlink "$f" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (open(F, $f))
|
||||
{
|
||||
# Read list of actions from the file, and untaint
|
||||
@actions = map { chomp; /([a-z]+[12]?)/ ; $1 } <F>;
|
||||
close(F);
|
||||
}
|
||||
else
|
||||
{
|
||||
warn "Could not open $f: $!";
|
||||
}
|
||||
}
|
||||
|
||||
# if service is supervised and not handled by systemd
|
||||
if (-d "/service/$service" && glob("/etc/rc7.d/S??$service"))
|
||||
{
|
||||
my $enabled = ($s->prop('status') || 'disabled') eq 'enabled';
|
||||
adjust_supervised_service($service,
|
||||
# stop the service if it is now disabled
|
||||
$enabled ? () : 'down',
|
||||
# Send the specified signal(s) to the running daemon
|
||||
@actions,
|
||||
# bring the service up if it is enabled (and we're not
|
||||
# stopping it or running it once)
|
||||
($enabled && !grep { /^(down|stop|d|once|o)$/ } @actions) ? 'up' : (),
|
||||
);
|
||||
}
|
||||
# for service handled by former sysvinit or directly with systemd
|
||||
else
|
||||
{
|
||||
my $enabled = ($s->prop('status') || 'disabled') eq 'enabled';
|
||||
# bring the service up if it is enabled (and we're not stopping it or running it once, or using signal able to start it)
|
||||
unshift(@actions,'start') if ($enabled && !grep { /^(down|stop|d|once|o|start|restart|reload-or-restart)$/ } @actions) ;
|
||||
# stop the service if it is disabled
|
||||
@actions = ('stop') unless $enabled;
|
||||
foreach (@actions)
|
||||
{
|
||||
warn "adjusting non-supervised $service ($_)\n";
|
||||
esmith::util::serviceControl(
|
||||
NAME => $service,
|
||||
ACTION => $_,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
61
root/etc/e-smith/events/actions/generic_template_expand
Normal file
61
root/etc/e-smith/events/actions/generic_template_expand
Normal file
@ -0,0 +1,61 @@
|
||||
#! /usr/bin/perl -w
|
||||
#----------------------------------------------------------------------
|
||||
# copyright (C) 2003-2007 Mitel Networks Corporation
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
use File::Find;
|
||||
use File::Copy;
|
||||
use esmith::templates;
|
||||
|
||||
sub expand;
|
||||
|
||||
my $event = shift or die "Event name is required\n";
|
||||
|
||||
my $filename;
|
||||
my %args;
|
||||
my ($param, $value);
|
||||
my $templates_dir = "/etc/e-smith/events/$event/templates2expand";
|
||||
exit 0 unless -d $templates_dir;
|
||||
|
||||
chdir $templates_dir or die "Could not chdir to $templates_dir: $!\n";;
|
||||
# Walk the tree and expand all templates referenced thereunder.
|
||||
find({
|
||||
no_chdir => 1,
|
||||
follow => 0,
|
||||
wanted => \&expand,
|
||||
},
|
||||
'.'
|
||||
);
|
||||
|
||||
exit 0;
|
||||
|
||||
sub expand
|
||||
{
|
||||
return unless -f $_;
|
||||
# For each file found, read the file to find
|
||||
# processTemplate args, then expand the template
|
||||
s/^\.//;
|
||||
$filename = $_;
|
||||
warn "expanding $filename\n";
|
||||
esmith::templates::processTemplate({
|
||||
MORE_DATA => { EVENT => $event },
|
||||
TEMPLATE_PATH => $filename,
|
||||
OUTPUT_FILENAME => $filename,
|
||||
});
|
||||
}
|
35
root/etc/e-smith/events/actions/initialize-default-databases
Normal file
35
root/etc/e-smith/events/actions/initialize-default-databases
Normal file
@ -0,0 +1,35 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# copyright (C) 1999-2003 Mitel Networks Corporation
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# Technical support for this program is available from Mitel Networks
|
||||
# Please visit our web site www.mitel.com/sme/ for details.
|
||||
#----------------------------------------------------------------------
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use esmith::util;
|
||||
|
||||
if (esmith::util::initialize_default_databases())
|
||||
{
|
||||
exit 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
exit 1;
|
||||
}
|
0
root/etc/e-smith/events/e-smith-lib-update/.gitignore
vendored
Normal file
0
root/etc/e-smith/events/e-smith-lib-update/.gitignore
vendored
Normal file
10
root/etc/e-smith/templates-default/template-begin
Normal file
10
root/etc/e-smith/templates-default/template-begin
Normal file
@ -0,0 +1,10 @@
|
||||
#------------------------------------------------------------
|
||||
# !!DO NOT MODIFY THIS FILE!!
|
||||
#
|
||||
# Manual changes will be lost when this file is regenerated.
|
||||
#
|
||||
# Please read the developer's guide, which is available
|
||||
# at http://www.contribs.org/development/
|
||||
#
|
||||
# Copyright (C) 1999-2006 Mitel Networks Corporation
|
||||
#------------------------------------------------------------
|
13
root/etc/e-smith/templates-default/template-begin-html
Normal file
13
root/etc/e-smith/templates-default/template-begin-html
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
$OUT = <<HERE;
|
||||
<!--
|
||||
HERE
|
||||
|
||||
$OUT .=
|
||||
Text::Template::_load_text("/etc/e-smith/templates-default/template-begin");
|
||||
|
||||
$OUT .= <<HERE;
|
||||
-->
|
||||
HERE
|
||||
|
||||
}
|
8
root/etc/e-smith/templates-default/template-begin-pam
Normal file
8
root/etc/e-smith/templates-default/template-begin-pam
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
$OUT = <<HERE;
|
||||
#%PAM-1.0
|
||||
HERE
|
||||
|
||||
$OUT .=
|
||||
Text::Template::_load_text("/etc/e-smith/templates-default/template-begin");
|
||||
}
|
8
root/etc/e-smith/templates-default/template-begin-perl
Normal file
8
root/etc/e-smith/templates-default/template-begin-perl
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
$OUT = <<HERE;
|
||||
#!/usr/bin/perl -w
|
||||
HERE
|
||||
|
||||
$OUT .=
|
||||
Text::Template::_load_text("/etc/e-smith/templates-default/template-begin");
|
||||
}
|
14
root/etc/e-smith/templates-default/template-begin-php
Normal file
14
root/etc/e-smith/templates-default/template-begin-php
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
$OUT = <<HERE;
|
||||
<?php
|
||||
/*
|
||||
HERE
|
||||
|
||||
$OUT .=
|
||||
Text::Template::_load_text("/etc/e-smith/templates-default/template-begin");
|
||||
|
||||
$OUT .= <<HERE;
|
||||
*/
|
||||
HERE
|
||||
|
||||
}
|
8
root/etc/e-smith/templates-default/template-begin-shell
Normal file
8
root/etc/e-smith/templates-default/template-begin-shell
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
$OUT = <<HERE;
|
||||
#!/bin/sh
|
||||
HERE
|
||||
|
||||
$OUT .=
|
||||
Text::Template::_load_text("/etc/e-smith/templates-default/template-begin");
|
||||
}
|
1
root/etc/e-smith/templates-default/template-end-php
Normal file
1
root/etc/e-smith/templates-default/template-end-php
Normal file
@ -0,0 +1 @@
|
||||
?>
|
81
root/etc/e-smith/tests/10e-smith-lib/accounts.conf
Normal file
81
root/etc/e-smith/tests/10e-smith-lib/accounts.conf
Normal file
@ -0,0 +1,81 @@
|
||||
# DO NOT MODIFY THIS FILE.
|
||||
# This file is automatically maintained by the Mitel Networks SME Server
|
||||
# configuration software. Manually editing this file may put your
|
||||
# system in an unknown state.
|
||||
#
|
||||
# updated: Thu Mar 28 15:29:31 2002
|
||||
Bart.Simpson=pseudonym|Account|bart
|
||||
Bart_Simpson=pseudonym|Account|bart
|
||||
Global=system
|
||||
Primary=system
|
||||
adm=system|Gid|4|Uid|3
|
||||
admin=system|Gid|101|Uid|101
|
||||
alias=system|Gid|400|Uid|400
|
||||
apache=existing|Gid|48|Uid|48
|
||||
bart=user|FirstName|Bart|LastName|Simpson
|
||||
bin=system|Gid|1|Uid|1
|
||||
cdrom=system
|
||||
cgi-bin=url
|
||||
console=system
|
||||
daemon=system|Gid|2|Uid|2
|
||||
dip=system|Gid|40
|
||||
disk=system|Gid|6
|
||||
dns=existing|Gid|53|Uid|53
|
||||
e-smith-manager=url
|
||||
e-smith-password=url
|
||||
everyone=pseudonym|Account|shared|Visible|internal
|
||||
floppy=system|Gid|19
|
||||
ftp=system|Gid|50|Uid|14
|
||||
games=system|Gid|20|Uid|12
|
||||
global=system
|
||||
gopher=system|Gid|30|Uid|13
|
||||
halt=system
|
||||
homes=system
|
||||
kmem=system|Gid|9
|
||||
ldap=existing|Gid|55|Uid|55
|
||||
lp=system|Gid|7|Uid|4
|
||||
mail=system|Gid|12|Uid|8
|
||||
mailer-daemon=pseudonym|Account|admin
|
||||
man=system|Gid|15
|
||||
mem=system|Gid|8
|
||||
mysql=existing|Gid|27|Uid|27
|
||||
named=existing|Gid|25|Uid|25
|
||||
netlogon=netlogon|Comment|placeholder for netlogon share
|
||||
news=system|Gid|13|Uid|9
|
||||
nofiles=system|Gid|400
|
||||
operator=system|Gid|0|Uid|11
|
||||
postgres=system
|
||||
postmaster=pseudonym|Account|admin
|
||||
primary=system
|
||||
printers=system
|
||||
public=system|Gid|103|Uid|102
|
||||
qmail=system|Gid|401
|
||||
qmaild=system|Gid|400|Uid|401
|
||||
qmaill=system|Gid|400|Uid|402
|
||||
qmailp=system|Gid|400|Uid|403
|
||||
qmailq=system|Gid|401|Uid|404
|
||||
qmailr=system|Gid|401|Uid|405
|
||||
qmails=system|Gid|401|Uid|406
|
||||
qmailscan=existing|Gid|407|Uid|407
|
||||
root=system|Gid|0|Uid|0
|
||||
schwern=user|Uid|500|Gid|501|FirstName|Michael|LastName|Schwern
|
||||
server-manager=url
|
||||
server-manual=url
|
||||
shared=system|Gid|500|Visible|internal
|
||||
shutdown=system
|
||||
simpsons=group|Description|bar|Gid|5005|Members|bart,lisa,homer,maggie|Uid|5005
|
||||
slocate=system
|
||||
somegroup=group|Gid|42|Members|admin
|
||||
squid=system|Gid|23|Uid|23
|
||||
sync=system
|
||||
sys=system|Gid|3
|
||||
trend=existing|Gid|408|Uid|408
|
||||
tty=system|Gid|5
|
||||
user-password=url
|
||||
users=system|Gid|100
|
||||
utmp=system|Gid|22
|
||||
uucp=system|Gid|14|Uid|10
|
||||
webmail=url
|
||||
wheel=system|Gid|10
|
||||
www=system|Gid|102|Uid|100
|
||||
wwwpublic=system
|
95
root/etc/e-smith/tests/10e-smith-lib/config.t
Normal file
95
root/etc/e-smith/tests/10e-smith-lib/config.t
Normal file
@ -0,0 +1,95 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# Overall tests for esmith::config
|
||||
|
||||
use strict;
|
||||
use File::Copy;
|
||||
|
||||
use Test::More 'no_plan';
|
||||
use_ok('esmith::config');
|
||||
|
||||
my %Expect = ( foo => 'bar',
|
||||
'this key' => 'has whitespace',
|
||||
'that key ' => 'has trailing whitespace',
|
||||
' another key' => 'has leading whitespace',
|
||||
'this value' => ' has leading whitespace',
|
||||
'that value' => 'has trailing whitespace ',
|
||||
'tricky value' => 'with=equals.',
|
||||
);
|
||||
|
||||
|
||||
# so we don't bork the original.
|
||||
my $Scratch = '10e-smith-lib/mydummy.conf';
|
||||
copy('10e-smith-lib/dummy.conf', $Scratch);
|
||||
END { unlink $Scratch }
|
||||
|
||||
my %config;
|
||||
tie %config, 'esmith::config', $Scratch;
|
||||
ok( tied %config, 'tie worked' );
|
||||
is_deeply( \%config, \%Expect, 'read in the config properly' );
|
||||
|
||||
# Test the tied interface.
|
||||
is_deeply( [sort keys %config], [sort keys %Expect], 'keys' );
|
||||
is_deeply( [sort values %config], [sort values %Expect], 'values' );
|
||||
|
||||
is_deeply( [@config{'foo', 'this key'}], [@Expect{'foo', 'this key'}],
|
||||
'hash slice');
|
||||
|
||||
$config{foo} = 'baz';
|
||||
is( $config{foo}, 'baz', 'STORE' );
|
||||
|
||||
my %config_copy;
|
||||
tie %config_copy, 'esmith::config', $Scratch;
|
||||
is( $config_copy{foo}, 'baz', ' STORE saved' );
|
||||
|
||||
SKIP: {
|
||||
skip "Locking is broken in perl 5.6.0", 2 if $] eq 5.006;
|
||||
|
||||
tied(%config_copy)->_lock_write;
|
||||
my $start_time = time;
|
||||
{
|
||||
local $ENV{PERL5LIB} = join ':', @INC;
|
||||
system(qq{$^X -Mesmith::config -e 'alarm 4; tie %config, "esmith::config", q{$Scratch}'});
|
||||
}
|
||||
|
||||
cmp_ok( time - 2, '<=', $start_time, 'write locks dont prevent read' );
|
||||
|
||||
|
||||
tied(%config_copy)->_lock_write;
|
||||
$start_time = time;
|
||||
{
|
||||
local $ENV{PERL5LIB} = join ':', @INC;
|
||||
system(qq{$^X -Mesmith::config -e 'alarm 4; tie %config, "esmith::config", q{$Scratch}; \$config{foo} = 42'});
|
||||
}
|
||||
|
||||
cmp_ok( time - 1, '>=', $start_time, 'write locks prevent writes' );
|
||||
};
|
||||
|
||||
my $new_conf = 'I_dont_exist';
|
||||
unlink $new_conf;
|
||||
ok( !-e $new_conf, 'config file doesnt exist' );
|
||||
END { unlink $new_conf }
|
||||
|
||||
tie %config, 'esmith::config', $new_conf;
|
||||
is( keys %config, 0, 'new() from nonexistent config' );
|
||||
$config{wibble} = 'wobble';
|
||||
|
||||
tie %config_copy, 'esmith::config', $new_conf;
|
||||
is( $config_copy{wibble}, 'wobble', ' new config file written' );
|
||||
|
||||
|
||||
SKIP: {
|
||||
skip "Locking is broken in perl 5.6.0", 1 if $] eq 5.006;
|
||||
|
||||
# There was a bug where if you set something to its existing value
|
||||
# it wouldn't unlock properly.
|
||||
my $Alarm;
|
||||
eval {
|
||||
local $SIG{ALRM} = sub { $Alarm = 1; die "ALARM!\n"; };
|
||||
alarm 1;
|
||||
$config_copy{wibble} = $config_copy{wibble};
|
||||
$config{wibble} = 42;
|
||||
alarm 0;
|
||||
};
|
||||
ok( !$Alarm, 'Unlocking works for setting the same value' );
|
||||
};
|
13
root/etc/e-smith/tests/10e-smith-lib/config_taint.t
Normal file
13
root/etc/e-smith/tests/10e-smith-lib/config_taint.t
Normal file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/perl -Tw
|
||||
|
||||
use strict;
|
||||
use esmith::config;
|
||||
use Test::More tests => 2;
|
||||
|
||||
my %config;
|
||||
tie %config, 'esmith::config', '10e-smith-lib/dummy.conf';
|
||||
my $value = $config{foo};
|
||||
|
||||
# Config values *should* be tained, but code depends on them not being.
|
||||
is( $value, 'bar', 'tied to the dummy database' );
|
||||
ok( eval { () = join('', $value), kill 0; 1; }, 'config values not tainted' );
|
103
root/etc/e-smith/tests/10e-smith-lib/configuration.conf
Normal file
103
root/etc/e-smith/tests/10e-smith-lib/configuration.conf
Normal file
@ -0,0 +1,103 @@
|
||||
# DO NOT MODIFY THIS FILE.
|
||||
# This file is automatically maintained by the Mitel Networks SME Server
|
||||
# configuration software. Manually editing this file may put your
|
||||
# system in an unknown state.
|
||||
#
|
||||
# updated: Fri Feb 28 16:41:34 2003
|
||||
AccessType=dedicated
|
||||
ActiveAccounts=0
|
||||
AdminEmail=
|
||||
ConsoleMode=login
|
||||
ContactEmail=
|
||||
ContactName=
|
||||
ContactOrg=
|
||||
DialupConnOffice=long
|
||||
DialupConnOutside=long
|
||||
DialupConnWeekend=long
|
||||
DialupFreqOffice=every15min
|
||||
DialupFreqOutside=everyhour
|
||||
DialupFreqWeekend=everyhour
|
||||
DialupModemDevice=/dev/ttyS1
|
||||
DialupPhoneNumber=
|
||||
DialupUserAccount=useraccount
|
||||
DialupUserPassword=userpassword
|
||||
DomainName=e-smith.com
|
||||
DynDnsAccount=dnsaccount
|
||||
DynDnsPassword=dnspassword
|
||||
DynDnsService=off
|
||||
EmailUnknownUser=return
|
||||
EthernetDriver1=pcnet32
|
||||
EthernetDriver2=unknown
|
||||
ExternalDHCP=off
|
||||
ExternalNetmask=255.255.255.0
|
||||
GatewayIP=192.168.16.1
|
||||
LocalIP=192.168.16.228
|
||||
LocalNetmask=255.255.255.0
|
||||
MinUid=5000
|
||||
PasswordSet=yes
|
||||
PreviousConfiguration=/home/e-smith/db/configuration.previous
|
||||
SMTPSmartHost=
|
||||
SambaDomainMaster=no
|
||||
SambaServerName=pretz
|
||||
SambaWorkgroup=mitel-networks
|
||||
ServiceAccountId=
|
||||
ServiceDomainName=
|
||||
ServiceTargetIP=
|
||||
SquidParent=
|
||||
SquidParentPort=
|
||||
StatusReports=off
|
||||
SystemMode=serveronly
|
||||
SystemName=pretz
|
||||
TimeZone=US/Eastern
|
||||
UnsavedChanges=yes
|
||||
atalk=service|InitscriptOrder|91|status|enabled
|
||||
auth=service|access|public|status|enabled
|
||||
bazbar=service|status|enabled
|
||||
blades=service|Host|service.e-smith.com|status|enabled
|
||||
bootstrap-console=service|InitscriptOrder|35|Run|no|status|enabled
|
||||
branding=service|modified|000000000000|status|enabled
|
||||
crond=service|InitscriptOrder|40|status|enabled
|
||||
ctrlaltdel=service|status|enabled
|
||||
dhcpd=service|InitscriptOrder|65|end|192.168.16.250|start|192.168.16.65|status|disabled
|
||||
diald=service|InitscriptOrder|57|status|disabled
|
||||
fetchmail=service|FreqOffice|every5min|FreqOutside|every30min|FreqWeekend|never|Method|standard|SecondaryMailAccount|popaccount|SecondaryMailPassword|poppassword|SecondaryMailServer|mail.myisp.xxx|status|disabled
|
||||
flexbackup=backupservice|erase_rewind_only|true
|
||||
ftp=service|access|private|accessLimits|off|status|enabled
|
||||
hdparm=service|InitscriptOrder|40|status|disabled
|
||||
horde=service|status|disabled
|
||||
httpd-admin=service|InitscriptOrder|86|status|enabled
|
||||
httpd-e-smith=service|InitscriptOrder|85|access|private|status|enabled
|
||||
imap=service|access|private|status|enabled
|
||||
imp=service|status|disabled
|
||||
ippp=service|InitscriptOrder|55|status|enabled
|
||||
ipsec=service|InitscriptOrder|90|PubKey|0sAQOoIKaOMuDqSdCZJXgv9QI86DAuAwbbvn8uoKn2lRQ9ZVPTn9Ow5znhuw/GopsYD2eujhtvkQo7fszAhWbEpn+lW2LzLCbZYaDov7j8Q9CpeJSVgeuzaBcw3OenSL3ltTwWWtG0pvyaYsfepNqVYvo64YVmrxo0O7dCECySMVBZkQ==|status|disabled
|
||||
isdn=service|Protocol|2|UseSyncPPP|yes|status|disabled
|
||||
keytable=service|InitscriptOrder|25|status|enabled
|
||||
ldap=service|InitscriptOrder|80|access|private|defaultCity|Ottawa|defaultCompany|XYZ Corporation|defaultDepartment|Main|defaultPhoneNumber|555-5555|defaultStreet|123 Main Street|status|enabled
|
||||
lilo=service|AddressMode|linear
|
||||
local=service|InitscriptOrder|99|status|enabled
|
||||
lpd=service|InitscriptOrder|60|status|enabled
|
||||
mariadb=service|InitscriptOrder|90|status|enabled
|
||||
masq=service|InitscriptOrder|06|Logging|none|Stealth|no|status|disabled
|
||||
modSSL=service|status|enabled
|
||||
mysql.init=service|InitscriptOrder|99|status|enabled
|
||||
named=service|chroot|yes|status|enabled|Forwarder1|1.2.3.4
|
||||
network=service|InitscriptOrder|10|status|enabled
|
||||
ntpd=service|InitscriptOrder|55|status|disabled
|
||||
php=service|status|enabled
|
||||
popd=service|access|private|status|enabled
|
||||
pppoe=service|DemandIdleTime|no|InitscriptOrder|57|SynchronousPPP|no|status|disabled
|
||||
pptpd=service|sessions|10|status|disabled
|
||||
qmail=service|InitscriptOrder|80|status|enabled
|
||||
random=service|InitscriptOrder|20|status|enabled
|
||||
rsyslog=service|InitscriptOrder|05|status|enabled
|
||||
scanner=service|ScannerFns|iscan|UpdateTime|1:14|scanMail|yes|status|enabled
|
||||
smb=service|InitscriptOrder|91|RoamingProfiles|no|status|enabled
|
||||
smtpd=service|access|public|status|enabled
|
||||
smtpfwdd=service|InitscriptOrder|81|status|enabled
|
||||
squid=service|InitscriptOrder|90|status|enabled
|
||||
sshd=service|InitscriptOrder|85|PasswordAuthentication|yes|PermitRootLogin|yes|access|private|status|enabled
|
||||
sync=service|Host|service.e-smith.com|LastId|0|SuccessId|0|SyncFrequency|1|SyncMinute|57|status|disabled
|
||||
telnet=service|access|private|status|disabled
|
||||
wibble=42
|
||||
xinetd=service|InitscriptOrder|50|status|enabled
|
215
root/etc/e-smith/tests/10e-smith-lib/db.t
Normal file
215
root/etc/e-smith/tests/10e-smith-lib/db.t
Normal file
@ -0,0 +1,215 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# Overall test for esmith::db
|
||||
|
||||
use File::Copy;
|
||||
use esmith::TestUtils;
|
||||
use Test::More 'no_plan';
|
||||
use_ok('esmith::db');
|
||||
|
||||
my %Expect = (
|
||||
Foo => ['Bar', {}],
|
||||
Night => ['Day', {}],
|
||||
Squid => ['cephalopod', {
|
||||
arms => 10,
|
||||
species => 'Loligo',
|
||||
}
|
||||
],
|
||||
|
||||
# Ensure that empty values are read in properly.
|
||||
Octopus => ['cephalopod', {
|
||||
arms => 8,
|
||||
species => '',
|
||||
}
|
||||
],
|
||||
|
||||
# Ensure that escaped pipes are read in properly.
|
||||
Pipe => ['art', { pipe => 'this is not a \| got that?'}],
|
||||
|
||||
# Ensure that escaped newlines are handled properly.
|
||||
Haiku => ['poem', { words =>
|
||||
"Damian Conway\n".
|
||||
"God damn! Damian Conway\n".
|
||||
"Damian Conway"
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
my $Scratch_Conf = '10e-smith-lib/db_scratch.conf';
|
||||
copy '10e-smith-lib/db_dummy.conf', $Scratch_Conf;
|
||||
END { unlink $Scratch_Conf }
|
||||
|
||||
my %config;
|
||||
tie %config, 'esmith::config', $Scratch_Conf;
|
||||
ok( tied %config, 'tied to the dummy config file' );
|
||||
isnt( keys %config, 0, ' and theres something in there' );
|
||||
|
||||
is( db_get_type(\%config, 'Foo'), 'Bar', 'simple db_get_type' );
|
||||
|
||||
my @keys = db_get(\%config);
|
||||
is_deeply( [sort @keys], [sort keys %Expect],
|
||||
'db_get() all keys' );
|
||||
|
||||
|
||||
foreach my $key (@keys) {
|
||||
my($type, %properties) = db_get(\%config, $key);
|
||||
my($exp_type, $exp_properties) = @{$Expect{$key}};
|
||||
|
||||
is( $type, $exp_type, "db_get - type - $key" );
|
||||
is( db_get_type(\%config, $key), $exp_type, "db_get_type" );
|
||||
is_deeply( \%properties, $exp_properties, "db_get - prop" );
|
||||
is_deeply( {db_get_prop(\%config, $key)}, $exp_properties,
|
||||
"db_get_prop - all properties");
|
||||
while( my($prop, $val) = each %properties ) {
|
||||
is( db_get_prop(\%config, $key, $prop), $val,
|
||||
"db_get_prop - single prop - $prop");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
is( db_get_type(\%config, 'I_dont_exist'), undef,
|
||||
'db_get_type on non-existent key' );
|
||||
is( db_get_prop(\%config, 'I_dont_exist'), undef,
|
||||
' db_get_prop' );
|
||||
is( db_get_prop(\%config, 'Squid', 'feet'), undef,
|
||||
'db_get_prop on non-existent prop' );
|
||||
is( db_delete_prop(\%config, 'I_dont_exist', 'feet'), undef,
|
||||
'db_delete_prop on non-existent key' );
|
||||
|
||||
is( db_get(\%config, 'Squid'), 'cephalopod|arms|10|species|Loligo',
|
||||
'db_get a raw value');
|
||||
|
||||
{
|
||||
package TieOut;
|
||||
|
||||
sub TIEHANDLE {
|
||||
bless( \(my $scalar), $_[0]);
|
||||
}
|
||||
|
||||
sub PRINT {
|
||||
my $self = shift;
|
||||
$$self .= join('', @_);
|
||||
}
|
||||
|
||||
sub read {
|
||||
my $self = shift;
|
||||
return substr($$self, 0, length($$self), '');
|
||||
}
|
||||
}
|
||||
|
||||
my $out = tie *STDOUT, 'TieOut';
|
||||
db_show(\%config);
|
||||
is( $out->read, <<SHOW, 'db_show() all' );
|
||||
Foo=Bar
|
||||
Haiku=poem
|
||||
words=Damian Conway\nGod damn! Damian Conway\nDamian Conway
|
||||
Night=Day
|
||||
Octopus=cephalopod
|
||||
arms=8
|
||||
species=
|
||||
Pipe=art
|
||||
pipe=this is not a \\| got that?
|
||||
Squid=cephalopod
|
||||
arms=10
|
||||
species=Loligo
|
||||
SHOW
|
||||
|
||||
db_show(\%config, 'Squid');
|
||||
is( $out->read, <<SHOW, 'db_show() one key' );
|
||||
Squid=cephalopod
|
||||
arms=10
|
||||
species=Loligo
|
||||
SHOW
|
||||
|
||||
|
||||
db_print(\%config);
|
||||
is( $out->read, <<PRINT, 'db_print all' );
|
||||
Foo=Bar
|
||||
Haiku=poem|words|Damian Conway\nGod damn! Damian Conway\nDamian Conway
|
||||
Night=Day
|
||||
Octopus=cephalopod|arms|8|species|
|
||||
Pipe=art|pipe|this is not a \\| got that?
|
||||
Squid=cephalopod|arms|10|species|Loligo
|
||||
PRINT
|
||||
|
||||
|
||||
db_print(\%config, 'Squid');
|
||||
is( $out->read, <<PRINT, 'db_print one key' );
|
||||
Squid=cephalopod|arms|10|species|Loligo
|
||||
PRINT
|
||||
|
||||
|
||||
db_print_type(\%config);
|
||||
is( $out->read, <<PRINT_TYPE, 'db_print_type all keys' );
|
||||
Foo=Bar
|
||||
Haiku=poem
|
||||
Night=Day
|
||||
Octopus=cephalopod
|
||||
Pipe=art
|
||||
Squid=cephalopod
|
||||
PRINT_TYPE
|
||||
|
||||
db_print_type(\%config, 'Squid');
|
||||
is( $out->read, <<PRINT_TYPE, 'db_print_type one key' );
|
||||
Squid=cephalopod
|
||||
PRINT_TYPE
|
||||
|
||||
db_print_prop(\%config, 'Squid');
|
||||
is( $out->read, <<PRINT_PROP, 'db_print_prop all props' );
|
||||
arms=10
|
||||
species=Loligo
|
||||
PRINT_PROP
|
||||
|
||||
db_print_prop(\%config, 'Squid', 'arms');
|
||||
is( $out->read, <<PRINT_PROP, 'db_print_prop one prop' );
|
||||
arms=10
|
||||
PRINT_PROP
|
||||
|
||||
undef $out;
|
||||
untie *STDOUT;
|
||||
|
||||
db_set(\%config, 'Wibble', 'dribble|hip|hop');
|
||||
my($type, %props) = db_get(\%config, 'Wibble');
|
||||
is( $type, 'dribble', 'db_set with raw value' );
|
||||
is_deeply( \%props, { hip => 'hop' }, ' again' );
|
||||
|
||||
db_set(\%config, 'Wibble', 'word', { thingy => 'yep' });
|
||||
($type, %props) = db_get(\%config, 'Wibble');
|
||||
is( $type, 'word', 'db_set');
|
||||
is_deeply( \%props, { thingy => 'yep' } );
|
||||
|
||||
db_set_type(\%config, 'Wibble', 'yibble');
|
||||
is( db_get_type(\%config, 'Wibble'), 'yibble', 'db_set_type' );
|
||||
|
||||
db_set_prop(\%config, 'Wibble', har => 'far');
|
||||
is( db_get_prop(\%config, 'Wibble', 'har'), 'far', 'db_set_prop' );
|
||||
|
||||
|
||||
### Test read-only open()
|
||||
my $scratch = scratch_copy('10e-smith-lib/configuration.conf');
|
||||
ok( chmod 0444, $scratch );
|
||||
my $ro_db = esmith::DB::db->open_ro($scratch);
|
||||
|
||||
eval { $ro_db->new_record('wibble', { type => 'something' }) };
|
||||
like( $@, qr/read-only/ );
|
||||
|
||||
my $sshd = $ro_db->get('sshd');
|
||||
eval { $sshd->set_prop('foo', 'bar') };
|
||||
like( $@, qr/read-only/ );
|
||||
is( $sshd->prop('foo'), undef );
|
||||
|
||||
eval { $sshd->delete_prop('status') };
|
||||
like( $@, qr/read-only/ );
|
||||
isnt( $sshd->prop('status'), undef );
|
||||
|
||||
eval { $sshd->merge_props(foo => 'bar') };
|
||||
like( $@, qr/read-only/ );
|
||||
is( $sshd->prop('foo'), undef );
|
||||
|
||||
eval { $sshd->reset_props(foo => 'bar') };
|
||||
like( $@, qr/read-only/ );
|
||||
is( $sshd->prop('foo'), undef );
|
||||
|
||||
eval { $sshd->delete };
|
||||
like( $@, qr/read-only/ );
|
||||
ok( $ro_db->get('sshd') );
|
@ -0,0 +1 @@
|
||||
invalid
|
@ -0,0 +1 @@
|
||||
enabled
|
@ -0,0 +1 @@
|
||||
service
|
@ -0,0 +1 @@
|
||||
enabled
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
$DB = esmith::ConfigDB->open("${DB_FILENAME}");
|
||||
}
|
||||
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
$DB->new_record("quux", {type=>'service', status=>'enabled'});
|
||||
}
|
7
root/etc/e-smith/tests/10e-smith-lib/db_dummy.conf
Normal file
7
root/etc/e-smith/tests/10e-smith-lib/db_dummy.conf
Normal file
@ -0,0 +1,7 @@
|
||||
# Dummy configuration file for testing esmith::db
|
||||
Foo=Bar
|
||||
Night=Day
|
||||
Squid=cephalopod|arms|10|species|Loligo
|
||||
Pipe=art|pipe|this is not a \| got that?
|
||||
Haiku=poem|words|Damian Conway\nGod damn! Damian Conway\nDamian Conway
|
||||
Octopus=cephalopod|arms|8|species|
|
141
root/etc/e-smith/tests/10e-smith-lib/default_migrate_force.t
Normal file
141
root/etc/e-smith/tests/10e-smith-lib/default_migrate_force.t
Normal file
@ -0,0 +1,141 @@
|
||||
#!/usr/bin/perl -w
|
||||
# vim: ft=perl:
|
||||
|
||||
use strict;
|
||||
use esmith::util;
|
||||
use esmith::ConfigDB;
|
||||
use Test::More 'no_plan';
|
||||
use File::Copy qw(copy);
|
||||
use POSIX qw(tmpnam);
|
||||
|
||||
# What we want to do is run initialize-default-databases on a scratch
|
||||
# db and check the results.
|
||||
my $dbhome = '/tmp/dbhome';
|
||||
my $dbroot = '/etc/e-smith/db';
|
||||
system('rm', '-rf', $dbhome);
|
||||
system('mkdir', '-p', $dbhome) == 0
|
||||
or die "Can't create $dbhome: $!\n";
|
||||
|
||||
ok( esmith::util::initialize_default_databases(dbhome => $dbhome),
|
||||
"initialize_default_databases created successfully" );
|
||||
|
||||
# Confirm the default settings.
|
||||
walk_dbtree($dbroot, 'defaults');
|
||||
# Test that forced options were forced.
|
||||
walk_dbtree($dbroot, 'force');
|
||||
|
||||
# We should now have default configuration files. We can go through each
|
||||
# setting specified by the defaults and confirm that it is correct.
|
||||
|
||||
# To test migration, we should take a typical 5.6 set of databases and migrate
|
||||
# those. The existing .conf databases in the 10e-smith-lib directory are
|
||||
# styled after 5.6, and suitable for this.
|
||||
foreach my $dummyconf (qw(accounts.conf domains.conf networks.conf
|
||||
configuration.conf hosts.conf))
|
||||
{
|
||||
# Copy them over the ones in our test directory, and then migrate them.
|
||||
my $dest;
|
||||
($dest = $dummyconf) =~ s/\.conf$//;
|
||||
$dest = "$dbhome/$dest";
|
||||
copy($dummyconf, $dest) or die "Can't copy $dummyconf to $dest: $!\n";
|
||||
}
|
||||
|
||||
# Migrate the directory.
|
||||
ok( esmith::util::initialize_default_databases(dbhome => $dbhome),
|
||||
"initialize_default_databases migrated successfully" );
|
||||
|
||||
#run_migrate_tests($dbhome, $dbroot);
|
||||
system('rm', '-rf', $dbhome);
|
||||
|
||||
exit 0;
|
||||
|
||||
sub walk_dbtree
|
||||
{
|
||||
my $dbroot = shift;
|
||||
my $mode = shift;
|
||||
die unless $mode =~ /^(defaults|force)$/;
|
||||
|
||||
opendir(DBROOT, $dbroot) or die "Can't open $dbroot: $!\n";
|
||||
my @dbfiles = grep { -d "$dbroot/$_" }
|
||||
grep { !/^\./ } readdir DBROOT;
|
||||
closedir(DBROOT);
|
||||
foreach my $dbfile (@dbfiles)
|
||||
{
|
||||
# Handle the defaults in this case.
|
||||
my $defaultdir = "$dbroot/$dbfile/defaults";
|
||||
next if not -e $defaultdir;
|
||||
opendir(DEFAULTDIR, $defaultdir) or die "Can't open $defaultdir: $!\n";
|
||||
my @keys = grep { -d "$defaultdir/$_" }
|
||||
grep { !/^\./ } readdir DEFAULTDIR;
|
||||
closedir(DEFAULTDIR);
|
||||
# There should now be a db file output at the dbhome.
|
||||
ok( -e "$dbhome/$dbfile", "$dbfile db exists" );
|
||||
|
||||
my $db = esmith::ConfigDB->open_ro("$dbhome/$dbfile");
|
||||
ok( defined $db, "$dbhome/$dbfile loads properly" );
|
||||
# Loop on all the keys.
|
||||
foreach my $keydir (@keys)
|
||||
{
|
||||
my $key_fullpath = "$defaultdir/$keydir";
|
||||
opendir(KEYDIR, $key_fullpath)
|
||||
or die "Can't open $key_fullpath: $!\n";
|
||||
my @propfiles = grep { -f "$key_fullpath/$_" }
|
||||
grep { !/^\./ } readdir KEYDIR;
|
||||
closedir(KEYDIR);
|
||||
|
||||
foreach my $propfile (@propfiles)
|
||||
{
|
||||
my $propfile_fullpath = "$key_fullpath/$propfile";
|
||||
# Open each and check what the default should be.
|
||||
open(PROPFILE, "<$propfile_fullpath")
|
||||
or die "Can't open $propfile_fullpath: $!\n";
|
||||
chomp( my $propval = <PROPFILE> );
|
||||
close(PROPFILE);
|
||||
if ($keydir eq 'ActiveAccounts')
|
||||
{
|
||||
print "get_prop on $keydir, $propfile returns ";
|
||||
print $db->get_prop($keydir, $propfile) . "\n";
|
||||
print "propval is $propval\n";
|
||||
}
|
||||
ok( $db->get_prop($keydir, $propfile) eq $propval,
|
||||
"property $propfile of record $keydir has correct $mode value of $propval" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# FIXME: This works, but the numbers of the tests are thrown off. We probably
|
||||
# want to eval the test block of code instead.
|
||||
sub run_migrate_tests
|
||||
{
|
||||
my $dbhome = shift;
|
||||
my $dbroot = shift;
|
||||
|
||||
opendir(DBROOT, $dbroot) or die "Can't open $dbroot: $!\n";
|
||||
my @dbfiles = grep { -d "$dbroot/$_" }
|
||||
grep { !/^\./ } readdir DBROOT;
|
||||
closedir(DBROOT);
|
||||
foreach my $dbfile (@dbfiles)
|
||||
{
|
||||
# Handle the defaults in this case.
|
||||
my $migratedir = "$dbroot/$dbfile/migrate";
|
||||
next if not -e $migratedir;
|
||||
|
||||
opendir(MIGRATEDIR, $migratedir) or die "Can't open $migratedir: $!\n";
|
||||
my @migrate_fragments = grep { !/^\./ } readdir MIGRATEDIR;
|
||||
closedir(MIGRATEDIR);
|
||||
|
||||
foreach my $migrate_fragment (sort @migrate_fragments)
|
||||
{
|
||||
my $tempname = tmpnam() or die "Can't obtain tempfile: $!\n";
|
||||
my $pod2test = '/usr/bin/pod2test';
|
||||
system($pod2test, "$migratedir/$migrate_fragment", $tempname);
|
||||
if (! -e $tempname)
|
||||
{
|
||||
warn "The fragment $migrate_fragment apparently has no embedded tests\n";
|
||||
next;
|
||||
}
|
||||
system('/usr/bin/perl', $tempname);
|
||||
}
|
||||
}
|
||||
}
|
3
root/etc/e-smith/tests/10e-smith-lib/domains.conf
Normal file
3
root/etc/e-smith/tests/10e-smith-lib/domains.conf
Normal file
@ -0,0 +1,3 @@
|
||||
test=domain|foo|bar
|
||||
foo=domain|baz|quux
|
||||
wombat=notadomain
|
11
root/etc/e-smith/tests/10e-smith-lib/dummy.conf
Normal file
11
root/etc/e-smith/tests/10e-smith-lib/dummy.conf
Normal file
@ -0,0 +1,11 @@
|
||||
foo=bar
|
||||
this key=has whitespace
|
||||
that key =has trailing whitespace
|
||||
another key=has leading whitespace
|
||||
this value= has leading whitespace
|
||||
that value=has trailing whitespace
|
||||
|
||||
# this is a comment. ignore it.
|
||||
# this is a comment = too
|
||||
|
||||
tricky value=with=equals.
|
13
root/etc/e-smith/tests/10e-smith-lib/hosts.conf
Normal file
13
root/etc/e-smith/tests/10e-smith-lib/hosts.conf
Normal file
@ -0,0 +1,13 @@
|
||||
# DO NOT MODIFY THIS FILE.
|
||||
# This file is automatically maintained by the Mitel Networks SME Server
|
||||
# configuration software. Manually editing this file may put your
|
||||
# system in an unknown state.
|
||||
#
|
||||
# updated: Fri Mar 11 18:21:42 2002
|
||||
ftp.mydomain.xxx=host|ExternalIP||HostType|Self|InternalIP||MACAddress||Visibility|Local
|
||||
mail.mydomain.xxx=host|ExternalIP||HostType|Self|InternalIP||MACAddress||Visibility|Local
|
||||
myserver.mydomain.xxx=host|ExternalIP||HostType|Local|InternalIP||MACAddress||Visibility|Local
|
||||
otherhost.mydomain.xxx=host|ExternalIP||HostType|Local|InternalIP|192.168.1.3|MACAddress||Visibility|Local
|
||||
www.mydomain.xxx=host|ExternalIP||HostType|Self|InternalIP||MACAddress||Visibility|Local
|
||||
www.otherdomain.xxx=host|ExternalIP||HostType|Self|InternalIP||MACAddress||Visibility|Local
|
||||
foo.otherdomain.xxx=host|ExternalIP||HostType|Self|InternalIP||MACAddress||Visibility|Local
|
@ -0,0 +1 @@
|
||||
I am an English license.
|
@ -0,0 +1 @@
|
||||
Je suis une license francais. Or something like that.
|
1
root/etc/e-smith/tests/10e-smith-lib/networks.conf
Normal file
1
root/etc/e-smith/tests/10e-smith-lib/networks.conf
Normal file
@ -0,0 +1 @@
|
||||
10.0.0.0=network|Mask|255.255.255.0|Router|default
|
@ -0,0 +1 @@
|
||||
sysconfig=configuration|KeyboardType|pc|Keytable|us|Language|en_US|ReleaseVersion|6.0alpha2
|
@ -0,0 +1 @@
|
||||
sysconfig=configuration|KeyboardType|pc|Keytable|us|Language|fr_CA|ReleaseVersion|6.0alpha2
|
111
root/etc/e-smith/tests/10e-smith-lib/templates.t
Normal file
111
root/etc/e-smith/tests/10e-smith-lib/templates.t
Normal file
@ -0,0 +1,111 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use esmith::TestUtils qw(scratch_copy);
|
||||
use File::Path;
|
||||
|
||||
use Test::More 'no_plan';
|
||||
|
||||
use_ok('esmith::templates', qw(:DEFAULT removeBlankLines));
|
||||
|
||||
use esmith::config;
|
||||
my %config;
|
||||
tie %config, 'esmith::config', '10e-smith-lib/scratch.conf';
|
||||
$ENV{ESMITH_CONFIG_DB} = '10e-smith-lib/scratch.conf';
|
||||
END { unlink '10e-smith-lib/scratch.conf' }
|
||||
|
||||
my $Scratch_Temp_Dir = 'template_scratch_dir';
|
||||
my $Scratch_Temp = "$Scratch_Temp_Dir/dummy";
|
||||
mkpath "$Scratch_Temp_Dir/10e-smith-lib";
|
||||
END { rmtree $Scratch_Temp_Dir }
|
||||
|
||||
# processTemplate() is going to be Loud and Helpful about skipping
|
||||
# things like CVS directories.
|
||||
$SIG{__WARN__} = sub { return if $_[0] =~ /^Skipping directory/ };
|
||||
|
||||
$config{Koala_Say} = "This is not the bear you're looking for.";
|
||||
processTemplate({ CONFREF => \%config,
|
||||
OUTPUT_PREFIX => $Scratch_Temp_Dir,
|
||||
OUTPUT_FILENAME => 'dummy',
|
||||
TEMPLATE_PATH => 'templates',
|
||||
TEMPLATE_EXPAND_QUEUE => [
|
||||
'10e-smith-lib'
|
||||
],
|
||||
FILTER => \&removeBlankLines,
|
||||
UID => $<,
|
||||
GID => (split / /, $()[0]
|
||||
});
|
||||
|
||||
ok( -f $Scratch_Temp, 'file generated' );
|
||||
ok( -s $Scratch_Temp, ' its not empty' );
|
||||
|
||||
open(SCRATCH, $Scratch_Temp) || die $!;
|
||||
my $out;
|
||||
{ local $/; $out = <SCRATCH>; }
|
||||
close SCRATCH;
|
||||
|
||||
my $koala_output = <<'THIS';
|
||||
# This is the beginning of the beginning
|
||||
# confref ok
|
||||
----------------------------------------
|
||||
< This is not the bear you're looking for. >
|
||||
----------------------------------------
|
||||
\
|
||||
\ .
|
||||
___ //
|
||||
{~._.~}//
|
||||
( Y )K/
|
||||
()~*~()
|
||||
(_)-(_)
|
||||
Luke
|
||||
Skywalker
|
||||
koala
|
||||
# This is the end, My only friend, the end of our elaborate templates, the end
|
||||
THIS
|
||||
|
||||
is( $out, $koala_output, 'file generated properly' );
|
||||
|
||||
$out = processTemplate({
|
||||
CONFREF => \%config,
|
||||
TEMPLATE_PATH => 'templates',
|
||||
TEMPLATE_EXPAND_QUEUE => [
|
||||
'10e-smith-lib'
|
||||
],
|
||||
FILTER => sub { $_[0] =~ /^\s*$/ ? '' : $_[0] },
|
||||
UID => $<,
|
||||
GID => (split / /, $()[0],
|
||||
OUTPUT_TYPE => 'string'
|
||||
});
|
||||
|
||||
is( $out, $koala_output, 'string generated properly' );
|
||||
|
||||
my $h_scratch = scratch_copy('10e-smith-lib/hosts.conf');
|
||||
my $a_scratch = scratch_copy('10e-smith-lib/accounts.conf');
|
||||
use esmith::AccountsDB;
|
||||
use esmith::HostsDB;
|
||||
my $acct = esmith::AccountsDB->open($a_scratch);
|
||||
my $host = esmith::HostsDB->open($h_scratch);
|
||||
$out = processTemplate({
|
||||
MORE_DATA => { Author => 'Douglas Adams' },
|
||||
TEMPLATE_PATH => 'templates_DB',
|
||||
TEMPLATE_EXPAND_QUEUE => [
|
||||
'10e-smith-lib'
|
||||
],
|
||||
OUTPUT_TYPE => 'string'
|
||||
});
|
||||
is( $out, <<'THIS', 'DB & MORE_DATA' );
|
||||
Chapter 1
|
||||
|
||||
The story so far:
|
||||
|
||||
In the beginning the Universe was created. This has made a lot
|
||||
of people very angry and been widely regarded as a bad move.
|
||||
-- Douglas Adams
|
||||
|
||||
$DB ok
|
||||
default vars ok
|
||||
|
||||
confref not defined
|
||||
|
||||
The end of labor is to gain leisure.
|
||||
THIS
|
||||
|
20
root/etc/e-smith/tests/10e-smith-lib/templates/10moof
Normal file
20
root/etc/e-smith/tests/10e-smith-lib/templates/10moof
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
my $ksez = $Koala_Say;
|
||||
my $line = '-' x length $ksez;
|
||||
|
||||
$OUT = <<KOALA_SEZ;
|
||||
$line
|
||||
< $ksez >
|
||||
$line
|
||||
KOALA_SEZ
|
||||
}
|
||||
\
|
||||
\ .
|
||||
___ //
|
||||
\{~._.~\}//
|
||||
( Y )K/
|
||||
()~*~()
|
||||
(_)-(_)
|
||||
Luke
|
||||
Skywalker
|
||||
koala
|
@ -0,0 +1,3 @@
|
||||
# This is the beginning of the beginning
|
||||
# { keys %$confref == 1 && exists $confref->{Koala_Say}
|
||||
? "confref ok" : "confref not ok" }
|
@ -0,0 +1 @@
|
||||
# This is the end, My only friend, the end of our elaborate templates, the end
|
20
root/etc/e-smith/tests/10e-smith-lib/templates2/10moof
Normal file
20
root/etc/e-smith/tests/10e-smith-lib/templates2/10moof
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
my $ksez = $Koala_Say;
|
||||
my $line = '-' x length $ksez;
|
||||
|
||||
$OUT = <<KOALA_SEZ;
|
||||
$line
|
||||
< $ksez >
|
||||
$line
|
||||
KOALA_SEZ
|
||||
}
|
||||
\
|
||||
\ .
|
||||
___ //
|
||||
\{~._.~\}//
|
||||
( Y )K/
|
||||
()~*~()
|
||||
(_)-(_)
|
||||
Luke
|
||||
Skywalker
|
||||
koala
|
@ -0,0 +1 @@
|
||||
# This is the end, My only friend, the end of our elaborate templates, the end
|
9
root/etc/e-smith/tests/10e-smith-lib/templates_DB/10DB
Normal file
9
root/etc/e-smith/tests/10e-smith-lib/templates_DB/10DB
Normal file
@ -0,0 +1,9 @@
|
||||
{ '$DB ok' if defined $DB && $DB->isa('esmith::ConfigDB') }
|
||||
{ my $ok = 1;
|
||||
foreach my $rec ($DB->get_all) {
|
||||
my $key = $rec->key;
|
||||
my $type = $rec->props <= 1 ? "SCALAR" : "HASH";
|
||||
$ok = 0 unless *{$key}{$type};
|
||||
}
|
||||
'default vars ok' if $ok;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
|
||||
{ if( *{confref}{SCALAR} ) {
|
||||
"confref not defined";
|
||||
} else {
|
||||
"confref defined"
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
Chapter 1
|
||||
|
||||
The story so far:
|
||||
|
||||
In the beginning the Universe was created. This has made a lot
|
||||
of people very angry and been widely regarded as a bad move.
|
||||
-- { # Testing MORE_DATA
|
||||
$Author
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
|
||||
The end of labor is to gain leisure.
|
112
root/etc/e-smith/tests/10e-smith-lib/uidgid.conf
Normal file
112
root/etc/e-smith/tests/10e-smith-lib/uidgid.conf
Normal file
@ -0,0 +1,112 @@
|
||||
# This file stores uid/gid information from the CreatingSystemUsers topic of
|
||||
# the Engineering Wiki. It is read by the uidgid.t test script. Please keep it
|
||||
# up to date.
|
||||
[passwd]
|
||||
0 root 0
|
||||
1 bin 1
|
||||
2 daemon 2
|
||||
3 adm 4
|
||||
4 lp 7
|
||||
8 mail 12
|
||||
9 news 13
|
||||
10 uucp 14
|
||||
11 operator 0
|
||||
12 games 100
|
||||
13 gopher 30
|
||||
14 ftp 50
|
||||
23 squid 23
|
||||
27 mysql 27
|
||||
32 rpc 32
|
||||
37 rpm 37
|
||||
38 ntp 38
|
||||
48 apache 48
|
||||
53 dns 53
|
||||
55 ldap 55
|
||||
69 vcsa 69
|
||||
74 sshd 74
|
||||
77 pcap 77
|
||||
99 nobody 99
|
||||
100 www 101
|
||||
101 admin 101
|
||||
102 public 103
|
||||
400 alias 400
|
||||
401 qmaild 400
|
||||
402 qmaill 400
|
||||
403 qmailp 400
|
||||
404 qmailq 401
|
||||
405 qmailr 401
|
||||
406 qmails 401
|
||||
407 qmailscan 407
|
||||
408 jabber 408
|
||||
410 dnscache 410
|
||||
411 dnslog 411
|
||||
420 nutups 420
|
||||
421 trend 421
|
||||
422 fax 422
|
||||
451 stunnel 451
|
||||
452 memtestlog 452
|
||||
1001 imaplog 1001
|
||||
1002 smelog 1002
|
||||
1003 cvmlog 1003
|
||||
1004 mn_dvr 1004
|
||||
1005 spamd 1005
|
||||
2999 smelastsys 2999
|
||||
|
||||
[group]
|
||||
0 root
|
||||
1 bin
|
||||
2 daemon
|
||||
3 sys
|
||||
4 adm
|
||||
5 tty
|
||||
6 disk
|
||||
7 lp
|
||||
8 mem
|
||||
9 kmem
|
||||
10 wheel
|
||||
12 mail
|
||||
13 news
|
||||
14 uucp
|
||||
15 man
|
||||
19 floppy
|
||||
20 games
|
||||
21 slocate
|
||||
22 utmp
|
||||
23 squid
|
||||
27 mysql
|
||||
30 gopher
|
||||
32 rpc
|
||||
37 rpm
|
||||
38 ntp
|
||||
40 dip
|
||||
48 apache
|
||||
50 ftp
|
||||
53 dns
|
||||
54 lock
|
||||
55 ldap
|
||||
69 vcsa
|
||||
74 sshd
|
||||
77 pcap
|
||||
99 nobody
|
||||
100 users
|
||||
101 admin
|
||||
102 www
|
||||
103 public
|
||||
400 nofiles
|
||||
401 qmail
|
||||
407 qmailscan
|
||||
408 jabber
|
||||
410 dnscache
|
||||
411 dnslog
|
||||
420 nutups
|
||||
421 trend
|
||||
422 fax
|
||||
451 stunnel
|
||||
452 memtestlog
|
||||
500 shared
|
||||
1001 imaplog
|
||||
1002 smelog
|
||||
1003 cvmlog
|
||||
1004 mn_dvr
|
||||
1005 spamd
|
||||
2999 smelastsys
|
78
root/etc/e-smith/tests/10e-smith-lib/uidgid.t
Normal file
78
root/etc/e-smith/tests/10e-smith-lib/uidgid.t
Normal file
@ -0,0 +1,78 @@
|
||||
#!/usr/bin/perl -w
|
||||
# vim: ft=perl:
|
||||
|
||||
use strict;
|
||||
use Test::More 'no_plan';
|
||||
use Unix::PasswdFile;
|
||||
use Unix::GroupFile;
|
||||
|
||||
use constant TRUE => 1;
|
||||
use constant FALSE => 0;
|
||||
|
||||
my $conffile = 'uidgid.conf';
|
||||
|
||||
exit 1 if not -e $conffile;
|
||||
|
||||
my %passwdlist = ();
|
||||
my %grouplist = ();
|
||||
my $passwd = FALSE;
|
||||
my $group = FALSE;
|
||||
|
||||
open(CONF, "<$conffile") or die "Can't open $conffile: $!\n";
|
||||
|
||||
while(<CONF>)
|
||||
{
|
||||
next if /^(#|\s)/;
|
||||
if (/\[passwd]/)
|
||||
{
|
||||
$passwd = TRUE;
|
||||
next;
|
||||
}
|
||||
elsif (/\[group]/)
|
||||
{
|
||||
$group = TRUE;
|
||||
$passwd = FALSE;
|
||||
next;
|
||||
}
|
||||
next if not $passwd and not $group;
|
||||
|
||||
if ($passwd)
|
||||
{
|
||||
my ($uid, $name, $gid) = split;
|
||||
$passwdlist{$name}{uid} = $uid;
|
||||
$passwdlist{$name}{gid} = $gid;
|
||||
}
|
||||
elsif ($group)
|
||||
{
|
||||
my ($gid, $name) = split;
|
||||
$grouplist{$name} = $gid;
|
||||
}
|
||||
}
|
||||
close(CONF);
|
||||
|
||||
# We can now confirm the uid and gid of every user, and the gid of every
|
||||
# group, on the system.
|
||||
# I don't know of a good way to query every user on the system, so for now
|
||||
# lets just read them from the passwd file.
|
||||
my $pw = Unix::PasswdFile->new('/etc/passwd', mode => 'r')
|
||||
or die "Can't open /etc/passwd: $!\n";
|
||||
|
||||
foreach my $user ($pw->users)
|
||||
{
|
||||
my ($name,$passwd,$uid,$gid,undef) = getpwnam($user);
|
||||
ok( exists $passwdlist{$name}, "user $name is on our list" );
|
||||
ok( $uid == $passwdlist{$name}{uid}, "user $name has uid of $uid" );
|
||||
ok( $gid == $passwdlist{$name}{gid}, "user $name has gid of $gid" );
|
||||
}
|
||||
|
||||
my $gr = Unix::GroupFile->new('/etc/group', mode => 'r')
|
||||
or die "Can't open /etc/group: $!\n";
|
||||
|
||||
foreach my $group ($gr->groups)
|
||||
{
|
||||
my ($name,$passwd,$gid,$members) = getgrnam($group);
|
||||
ok( exists $grouplist{$name}, "group $name is on our list" );
|
||||
ok( $gid == $grouplist{$name}, "group $group has gid of $gid" );
|
||||
}
|
||||
|
||||
exit 0;
|
10
root/sbin/e-smith/config
Executable file
10
root/sbin/e-smith/config
Executable file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
exec "/sbin/e-smith/db", "configuration", @ARGV;
|
||||
die "Could not exec /sbin/e-smith/db";
|
84
root/sbin/e-smith/create-system-user
Normal file
84
root/sbin/e-smith/create-system-user
Normal file
@ -0,0 +1,84 @@
|
||||
#! /usr/bin/perl -w
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
|
||||
sub usage
|
||||
{
|
||||
my $msg = shift;
|
||||
warn("$msg\n") if $msg;
|
||||
die("Usage: $0: user userid descr home_dir shell\n");
|
||||
}
|
||||
|
||||
my $user = shift || usage("Must give username param");
|
||||
my $uid = shift || usage("Must give userid param");
|
||||
my $user_desc = shift || usage("Must give user desc param");
|
||||
my $home = shift || usage("Must give home param");
|
||||
my $shell = shift || usage("Must give shell param");
|
||||
|
||||
use User::pwent;
|
||||
use User::grent;
|
||||
|
||||
if (my $pw = getpwnam($user))
|
||||
{
|
||||
my $euid = $pw->uid;
|
||||
exit 0 if $euid == $uid; # Do not create user if it already exists with correct uid
|
||||
warn ("Users $user exists but has uid of $euid - should be $uid\n");
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if (my $pw = getpwuid($uid))
|
||||
{
|
||||
my $name = $pw->name;
|
||||
warn "User id of $uid is already taken by user $name\n";
|
||||
warn "Falling back to a system chosen uid\n";
|
||||
# We can now go ahead and create the user and group leaving the system to choose uid/gid
|
||||
die ("Failed to create user $user\n") if
|
||||
system("/usr/sbin/useradd",
|
||||
"-r",
|
||||
"-d", $home,
|
||||
"-M",
|
||||
"-s", $shell,
|
||||
"-c", $user_desc,
|
||||
$user);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (my $pw = getgrgid($uid))
|
||||
{
|
||||
my $name = $pw->name;
|
||||
warn "Group id of $uid is already taken by user $name\n";
|
||||
# We can now go ahead and create the user but the gid will be chosen by the system
|
||||
die ("Failed to create user $user\n") if
|
||||
system("/usr/sbin/useradd",
|
||||
"-u", $uid,
|
||||
"-d", $home,
|
||||
"-M",
|
||||
"-s", $shell,
|
||||
"-c", $user_desc,
|
||||
$user);
|
||||
}
|
||||
else
|
||||
{
|
||||
# We can now go ahead and create the user and group
|
||||
die ("Failed to create group $uid\n") if
|
||||
system("/usr/sbin/groupadd",
|
||||
"-g", $uid,
|
||||
$user);
|
||||
|
||||
die ("Failed to create user $user\n") if
|
||||
system("/usr/sbin/useradd",
|
||||
"-u", $uid,
|
||||
"-g", $uid,
|
||||
"-d", $home,
|
||||
"-M",
|
||||
"-s", $shell,
|
||||
"-c", $user_desc,
|
||||
$user);
|
||||
}
|
||||
exit 0;
|
344
root/sbin/e-smith/db
Normal file
344
root/sbin/e-smith/db
Normal file
@ -0,0 +1,344 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use esmith::config;
|
||||
use esmith::db;
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Set up the command list and usage strings
|
||||
|
||||
my %commands = (
|
||||
'keys'
|
||||
=> {
|
||||
'function' => \&DB_keys,
|
||||
'usage' => "$0 dbfile keys",
|
||||
},
|
||||
|
||||
'print'
|
||||
=> {
|
||||
'function' => \&DB_print,
|
||||
'usage' => "$0 dbfile print [key]",
|
||||
},
|
||||
|
||||
'show'
|
||||
=> {
|
||||
'function' => \&DB_show,
|
||||
'usage' => "$0 dbfile show [key]",
|
||||
},
|
||||
|
||||
'get'
|
||||
=> {
|
||||
'function' => \&DB_get,
|
||||
'usage' => "$0 dbfile get key",
|
||||
},
|
||||
|
||||
'set'
|
||||
=> {
|
||||
'function' => \&DB_set,
|
||||
'usage' => "$0 dbfile set key type "
|
||||
. "[prop1 val1] [prop2 val2] ...",
|
||||
},
|
||||
|
||||
'setdefault'
|
||||
=> {
|
||||
'function' => \&DB_set_default,
|
||||
'usage' => "$0 dbfile setdefault key type "
|
||||
. "[prop1 val1] [prop2 val2] ...",
|
||||
},
|
||||
|
||||
'delete'
|
||||
=> {
|
||||
'function' => \&DB_delete,
|
||||
'usage' => "$0 dbfile delete key",
|
||||
},
|
||||
|
||||
'printtype'
|
||||
=> {
|
||||
'function' => \&DB_printtype,
|
||||
'usage' => "$0 dbfile printtype [key]",
|
||||
},
|
||||
|
||||
'gettype'
|
||||
=> {
|
||||
'function' => \&DB_gettype,
|
||||
'usage' => "$0 dbfile gettype key",
|
||||
},
|
||||
|
||||
'settype'
|
||||
=> {
|
||||
'function' => \&DB_settype,
|
||||
'usage' => "$0 dbfile settype key type",
|
||||
},
|
||||
|
||||
'printprop'
|
||||
=> {
|
||||
'function' => \&DB_printprop,
|
||||
'usage' => "$0 dbfile printprop key [prop1] "
|
||||
. "[prop2] [prop3] ...",
|
||||
},
|
||||
|
||||
'getprop'
|
||||
=> {
|
||||
'function' => \&DB_getprop,
|
||||
'usage' => "$0 dbfile getprop key prop",
|
||||
},
|
||||
|
||||
'setprop'
|
||||
=> {
|
||||
'function' => \&DB_setprop,
|
||||
'usage' => "$0 dbfile setprop key "
|
||||
. "prop1 val1 [prop2 val2] "
|
||||
. "[prop3 val3] ...",
|
||||
},
|
||||
|
||||
'delprop'
|
||||
=> {
|
||||
'function' => \&DB_delprop,
|
||||
'usage' => "$0 dbfile delprop key prop1 "
|
||||
. "[prop2] [prop3] ...",
|
||||
},
|
||||
|
||||
);
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Set up general usage message.
|
||||
|
||||
my $usage = "usage:
|
||||
$commands{'keys'}{'usage'}
|
||||
$commands{'print'}{'usage'}
|
||||
$commands{'show'}{'usage'}
|
||||
$commands{'get'}{'usage'}
|
||||
$commands{'set'}{'usage'}
|
||||
$commands{'setdefault'}{'usage'}
|
||||
$commands{'delete'}{'usage'}
|
||||
$commands{'printtype'}{'usage'}
|
||||
$commands{'gettype'}{'usage'}
|
||||
$commands{'settype'}{'usage'}
|
||||
$commands{'printprop'}{'usage'}
|
||||
$commands{'getprop'}{'usage'}
|
||||
$commands{'setprop'}{'usage'}
|
||||
$commands{'delprop'}{'usage'}
|
||||
";
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Prepend $ENV{'DBPATH'} to dbfile if defined otherwise let the library
|
||||
# deal with it.
|
||||
|
||||
my $dbfile = shift;
|
||||
die $usage unless $dbfile;
|
||||
|
||||
my $dbpath = $ENV{'DBPATH'};
|
||||
$dbfile = "$dbpath/$dbfile" if defined $dbpath;
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Tie the databasefile to a hash
|
||||
|
||||
my $db = esmith::db->open($dbfile);
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Run the appropriate command
|
||||
|
||||
my $command = shift;
|
||||
die $usage unless $command;
|
||||
die $usage unless exists $commands{$command};
|
||||
$commands{$command}{'function'}->(@ARGV);
|
||||
|
||||
exit 0;
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
sub DB_print
|
||||
{
|
||||
my $key = shift;
|
||||
|
||||
if (defined $key)
|
||||
{
|
||||
$db->print($key) ? exit 0 : exit 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->print() ? exit 0 : exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub DB_keys
|
||||
{
|
||||
my @keys = $db->get();
|
||||
|
||||
exit 1 unless (scalar @keys);
|
||||
print join("\n", @keys), "\n";
|
||||
}
|
||||
|
||||
sub DB_show
|
||||
{
|
||||
my $key = shift;
|
||||
|
||||
if (defined $key)
|
||||
{
|
||||
$db->show($key) ? exit 0 : exit 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->show() ? exit 0 : exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub DB_get
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'get'}{'usage'}\n" unless $key;
|
||||
|
||||
my $value = $db->get($key);
|
||||
exit 1 unless defined $value;
|
||||
print "$value\n" if defined $value;
|
||||
}
|
||||
|
||||
sub DB_set
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'set'}{'usage'}\n" unless $key;
|
||||
die "$commands{'set'}{'usage'}\n" unless scalar @_;
|
||||
|
||||
my $type = shift;
|
||||
die "$commands{'set'}{'usage'}\n" unless defined $type;
|
||||
die "$commands{'set'}{'usage'}\n" if scalar @_ % 2;
|
||||
|
||||
$db->set($key, $type) or exit 1;
|
||||
|
||||
&DB_setprop($key, @_) if scalar @_;
|
||||
}
|
||||
|
||||
sub DB_set_default
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'setdefault'}{'usage'}\n" unless $key;
|
||||
die "$commands{'setdefault'}{'usage'}\n" unless scalar @_;
|
||||
|
||||
my $type = shift;
|
||||
die "$commands{'setdefault'}{'usage'}\n" unless $type;
|
||||
die "$commands{'setdefault'}{'usage'}\n" if scalar @_ % 2;
|
||||
|
||||
# Only set values if the key does not exist
|
||||
|
||||
exit 0 if defined $db->get($key);
|
||||
|
||||
&DB_set($key, $type, @_);
|
||||
}
|
||||
|
||||
sub DB_delete
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'delete'}{'usage'}\n" unless $key;
|
||||
|
||||
$db->delete($key) ? exit 0 : exit 1;
|
||||
}
|
||||
|
||||
sub DB_printtype
|
||||
{
|
||||
my $key = shift;
|
||||
|
||||
if (defined $key)
|
||||
{
|
||||
$db->print_type($key) ? exit 0 : exit 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->print_type() ? exit 0 : exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub DB_gettype
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'get'}{'usage'}\n" unless $key;
|
||||
|
||||
my $value = $db->get_type($key);
|
||||
exit 1 unless defined $value;
|
||||
print "$value\n" if defined $value;
|
||||
}
|
||||
|
||||
sub DB_settype
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'settype'}{'usage'}\n" unless $key;
|
||||
my $type = shift;
|
||||
die "$commands{'settype'}{'usage'}\n" unless $type;
|
||||
|
||||
$db->set_type($key, $type) ? exit 0 : exit 1;
|
||||
}
|
||||
|
||||
sub DB_printprop
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'printprop'}{'usage'}\n" unless $key;
|
||||
|
||||
my @props = @_;
|
||||
|
||||
if (scalar @props)
|
||||
{
|
||||
foreach (@props)
|
||||
{
|
||||
$db->print_prop($key, $_)
|
||||
if defined $db->get_prop($key, $_);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->print_prop($key) ? exit 0 : exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub DB_getprop
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'getprop'}{'usage'}\n" unless $key;
|
||||
|
||||
my $prop = shift;
|
||||
die "$commands{'getprop'}{'usage'}\n" unless scalar $prop;
|
||||
|
||||
my $val = $db->get_prop($key, $prop);
|
||||
|
||||
if (defined $val)
|
||||
{
|
||||
print "$val\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub DB_setprop
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'setprop'}{'usage'}\n" unless $key;
|
||||
die "$commands{'setprop'}{'usage'}\n" unless scalar @_;
|
||||
die "$commands{'setprop'}{'usage'}\n" if scalar @_ % 2;
|
||||
|
||||
my %properties = @_;
|
||||
|
||||
foreach (sort keys %properties)
|
||||
{
|
||||
$db->set_prop($key, $_, $properties{$_});
|
||||
}
|
||||
}
|
||||
|
||||
sub DB_delprop
|
||||
{
|
||||
my $key = shift;
|
||||
die "$commands{'delprop'}{'usage'}\n" unless $key;
|
||||
die "$commands{'delprop'}{'usage'}\n" unless scalar @_;
|
||||
|
||||
foreach (@_)
|
||||
{
|
||||
$db->delete_prop($key, $_);
|
||||
}
|
||||
}
|
46
root/sbin/e-smith/expand-template
Normal file
46
root/sbin/e-smith/expand-template
Normal file
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2004 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use Errno;
|
||||
use Getopt::Long;
|
||||
use esmith::templates;
|
||||
|
||||
my %options = ();
|
||||
|
||||
GetOptions(\%options, 'output_filename=s', 'expand_queue=s');
|
||||
|
||||
$options{'template_path'} = $ARGV[0] || die "Usage: $0 /path/to/file/to/expand\n";
|
||||
|
||||
$options{'output_filename'} = $options{'template_path'}
|
||||
unless ( exists $options{'output_filename'} );
|
||||
|
||||
|
||||
my %args = (
|
||||
TEMPLATE_PATH => $options{'template_path'},
|
||||
OUTPUT_FILENAME => $options{'output_filename'},
|
||||
);
|
||||
|
||||
$args{TEMPLATE_EXPAND_QUEUE} = [$options{'expand_queue'}]
|
||||
if exists $options{expand_queue};
|
||||
|
||||
if ( -f $options{'output_filename'} )
|
||||
{
|
||||
# If the target file exists, preserve its ownership and mode
|
||||
use File::stat;
|
||||
|
||||
my $f = stat($options{'output_filename'} );
|
||||
$args{UID} = $f->uid;
|
||||
$args{GID} = $f->gid;
|
||||
$args{PERMS} = $f->mode;
|
||||
}
|
||||
|
||||
esmith::templates::processTemplate(\%args);
|
||||
|
24
root/sbin/e-smith/signal-event
Normal file
24
root/sbin/e-smith/signal-event
Normal file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use esmith::event;
|
||||
|
||||
my $usage = "usage:
|
||||
$0 eventname [arg1 [arg2...]]
|
||||
";
|
||||
|
||||
my ($event, @args) = @ARGV;
|
||||
die $usage unless $event;
|
||||
|
||||
my $exitcode = event_signal($event, @args);
|
||||
|
||||
# reverse exitcode for command-line usage
|
||||
exit ($exitcode ? 0 : 1);
|
||||
|
540
root/usr/share/perl5/vendor_perl/esmith/AccountsDB.pm
Normal file
540
root/usr/share/perl5/vendor_perl/esmith/AccountsDB.pm
Normal file
@ -0,0 +1,540 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::AccountsDB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use esmith::db;
|
||||
|
||||
use vars qw( $AUTOLOAD @ISA );
|
||||
|
||||
use esmith::DB::db;
|
||||
@ISA = qw(esmith::DB::db);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::AccountsDB - interface to esmith configuration database
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::AccountsDB;
|
||||
my $a = esmith::AccountsDB->open;
|
||||
|
||||
my @users = $a->users();
|
||||
my @groups = $a->groups();
|
||||
my @ibays = $a->ibays();
|
||||
my @printers = $a->printers();
|
||||
my @pseudonyms = $a->pseudonyms();
|
||||
|
||||
$a->is_user_in_group($user, $group);
|
||||
my @groups = $a->user_group_list($user);
|
||||
$a->add_user_to_groups($user, @groups);
|
||||
$a->remove_user_from_groups($user, @groups);
|
||||
|
||||
$a->create_user_auto_pseudonyms($user);
|
||||
$a->remove_user_auto_pseudonyms($user);
|
||||
$a->remove_all_user_pseudonyms($user);
|
||||
my $dp = $a->dot_pseudonym($user);
|
||||
my $up = $a->underbar_pseudonym($user);
|
||||
my $uid = $a->get_next_uid();
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides an abstracted interface to the esmith accounts
|
||||
database.
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = sprintf '%d.%03d', q$Revision: 1.18 $ =~ /: (\d+).(\d+)/;
|
||||
|
||||
=head2 open()
|
||||
|
||||
Loads an existing account database and returns an esmith::AccountsDB
|
||||
object representing it.
|
||||
|
||||
=begin testing
|
||||
|
||||
use esmith::TestUtils qw(scratch_copy);
|
||||
|
||||
use_ok("esmith::AccountsDB");
|
||||
use esmith::db;
|
||||
use vars qw($a);
|
||||
|
||||
my $conf = scratch_copy('10e-smith-lib/accounts.conf');
|
||||
$a = esmith::AccountsDB->open($conf);
|
||||
isa_ok($a, 'esmith::AccountsDB');
|
||||
is( $a->get("global")->prop('type'), "system", "We can get stuff from the db");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open {
|
||||
my($class, $file) = @_;
|
||||
$file = $file || $ENV{ESMITH_ACCOUNT_DB} || "accounts";
|
||||
return $class->SUPER::open($file);
|
||||
}
|
||||
|
||||
=head2 open_ro()
|
||||
|
||||
Like esmith::DB->open_ro, but if given no $file it will try to open the
|
||||
file in the ESMITH_ACCOUNT_DB environment variable or accounts.
|
||||
|
||||
=begin testing
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open_ro {
|
||||
my($class, $file) = @_;
|
||||
$file = $file || $ENV{ESMITH_ACCOUNT_DB} || "accounts";
|
||||
return $class->SUPER::open_ro($file);
|
||||
}
|
||||
|
||||
=head2 users(), groups(), ibays(), printers(), pseudonyms()
|
||||
|
||||
Returns a list of records (esmith::DB::db::Record objects) of the
|
||||
given type.
|
||||
|
||||
=for testing
|
||||
foreach my $t (qw(users groups pseudonyms)) {
|
||||
my @list = $a->$t();
|
||||
ok(@list, "Got a list of $t");
|
||||
isa_ok($list[0], 'esmith::DB::db::Record');
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my ($called_sub_name) = ($AUTOLOAD =~ m/([^:]*)$/);
|
||||
my @types = qw( users groups ibays printers pseudonyms);
|
||||
if (grep /^$called_sub_name$/, @types) {
|
||||
$called_sub_name =~ s/s$//g; # de-pluralize
|
||||
return $self->get_all_by_prop(type => $called_sub_name);
|
||||
}
|
||||
}
|
||||
|
||||
=head1 GROUP MANAGEMENT
|
||||
|
||||
=head2 $a->is_user_in_group($user, $group)
|
||||
|
||||
Returns true if the user is a member of the group, false otherwise. The
|
||||
arguments are a user name and a group name.
|
||||
|
||||
This routine will return undef if there is no such group, false (but
|
||||
defined) if the user is not in the group, and true if the user is in the
|
||||
group.
|
||||
|
||||
=for testing
|
||||
ok($a->is_user_in_group('bart', 'simpsons'), "Bart is in group Simpsons");
|
||||
ok(not($a->is_user_in_group('moe', 'simpsons')), "Moe is not in group Simpsons");
|
||||
ok(not(defined $a->is_user_in_group('moe', 'flanders')), "No such group as Flanders");
|
||||
|
||||
=cut
|
||||
|
||||
sub is_user_in_group {
|
||||
my ($self, $user, $group) = @_;
|
||||
$group = $self->get($group) || return undef;
|
||||
my $members = $group->prop('Members');
|
||||
|
||||
return grep(/^$user$/, split /,/, $members) ? 1 : 0;
|
||||
}
|
||||
|
||||
=head2 $a->user_group_list($user)
|
||||
|
||||
Get a list of groups (by name) of which a user is a member. The $user argument
|
||||
is simply the username.
|
||||
|
||||
=for testing
|
||||
my @groups = $a->user_group_list('bart');
|
||||
is_deeply(\@groups, ['simpsons'], "Bart's group list is 'simpsons'");
|
||||
|
||||
=cut
|
||||
|
||||
sub user_group_list {
|
||||
my ($self, $user) = @_;
|
||||
my @groups = $self->groups();
|
||||
my @user_groups;
|
||||
foreach my $g (@groups) {
|
||||
push(@user_groups, $g->key())
|
||||
if $self->is_user_in_group($user, $g->key());
|
||||
}
|
||||
return @user_groups;
|
||||
}
|
||||
|
||||
=head2 $a->add_user_to_groups($user, @groups)
|
||||
|
||||
Given a list of groups (by name), adds the user to all of them.
|
||||
|
||||
Doesn't signal the group-modify event, just does the DB work.
|
||||
|
||||
Note: the method used here is a bit kludgy. It could result in a user
|
||||
being in the same group twice.
|
||||
|
||||
=for testing
|
||||
my @groups = $a->groups();
|
||||
$a->remove_user_from_groups('maggie', map { $_->key() } @groups);
|
||||
my @mg = $a->user_group_list('maggie');
|
||||
is(scalar @mg, 0, "Maggie has been removed from all groups");
|
||||
$a->add_user_to_groups('maggie', 'simpsons');
|
||||
@mg = $a->user_group_list('maggie');
|
||||
is_deeply(\@mg, ['simpsons'], "Maggie has been added to group 'simpsons'");
|
||||
$a->remove_user_from_groups('maggie', 'simpsons');
|
||||
@mg = $a->user_group_list('maggie');
|
||||
is_deeply(\@mg, [], "Maggie's been removed from all groups again");
|
||||
$a->set_user_groups('maggie', 'simpsons');
|
||||
@mg = $a->user_group_list('maggie');
|
||||
is_deeply(\@mg, ['simpsons'], "Maggie's groups have been set to: 'simpsons'");
|
||||
|
||||
=cut
|
||||
|
||||
sub add_user_to_groups {
|
||||
my ($self, $user, @groups) = @_;
|
||||
GROUP: foreach my $group (@groups) {
|
||||
unless (($group) = ($group =~ /(^[\w.-]+$)/))
|
||||
{
|
||||
warn "Group name doesn't look like a group!\n";
|
||||
next GROUP;
|
||||
}
|
||||
|
||||
my $group_rec = $self->get($group) || next GROUP;
|
||||
my @members = split(/,/, $group_rec->prop('Members'));
|
||||
push @members, $user;
|
||||
# Remove duplicates
|
||||
my %members = map { $_ => 1 } @members;
|
||||
$group_rec->set_prop('Members', join(',', sort keys %members));
|
||||
}
|
||||
}
|
||||
|
||||
=head2 $a->remove_user_from_groups($user, @groups)
|
||||
|
||||
Given a list of groups, removes a user from all of them.
|
||||
Doesn't signal the group-modify event, just does the DB work.
|
||||
|
||||
=cut
|
||||
|
||||
sub remove_user_from_groups {
|
||||
my ($self, $user, @groups) = @_;
|
||||
|
||||
GROUP: foreach my $g (@groups) {
|
||||
my $group_rec = $self->get($g) || next GROUP;
|
||||
my $members = $group_rec->prop('Members');
|
||||
my @members = split (/,/, $members);
|
||||
@members = grep (!/^$user$/, @members);
|
||||
@members = qw(admin) unless @members; # admin *must* be in every group
|
||||
$group_rec->set_prop('Members', join(',', @members));
|
||||
}
|
||||
}
|
||||
|
||||
=head2 $a->set_user_groups($user, @groups)
|
||||
|
||||
Sets the user's groups in one fell swoop. Under the hood, it's removing
|
||||
the user from every group they're in then adding them to the set you give.
|
||||
|
||||
=cut
|
||||
|
||||
sub set_user_groups
|
||||
{
|
||||
my ($self, $user, @groups) = @_;
|
||||
my @old_groups = $self->user_groups_list($user);
|
||||
$self->remove_user_from_groups($user, @old_groups);
|
||||
$self->add_user_to_groups($user, @groups);
|
||||
}
|
||||
|
||||
=head1 PSEUDONYM MANAGEMENT
|
||||
|
||||
=head2 $a->create_user_auto_pseudonyms($user)
|
||||
|
||||
Given a user name, creates standard pseudonyms ("dot" and "underbar" style)
|
||||
for that user.
|
||||
|
||||
=for testing
|
||||
my $user = 'bart';
|
||||
ok($a->pseudonyms(), "There are pseudonyms in the accounts db");
|
||||
$a->remove_user_auto_pseudonyms($user);
|
||||
ok(! $a->get('bart.simpson'), "Removed dot-pseudonym");
|
||||
ok(! $a->get('bart_simpson'), "Removed underbar-pseudonym");
|
||||
$a->create_user_auto_pseudonyms($user);
|
||||
ok($a->get('bart.simpson'), "Created dot-pseudonym");
|
||||
ok($a->get('bart_simpson'), "Created underbar-pseudonym");
|
||||
|
||||
=cut
|
||||
|
||||
sub create_user_auto_pseudonyms {
|
||||
my ($self, $user) = @_;
|
||||
my $user_rec = $self->get($user);
|
||||
my $firstName = $user_rec->prop("FirstName");
|
||||
my $lastName = $user_rec->prop("LastName");
|
||||
|
||||
my $dot_pseudonym = dot_pseudonym($self, $user);
|
||||
my $underbar_pseudonym = underbar_pseudonym($self, $user);
|
||||
|
||||
my $dot_acct = $self->get($dot_pseudonym) ||
|
||||
$self->new_record($dot_pseudonym, { type => 'pseudonym',
|
||||
Account => $user} );
|
||||
|
||||
my $underbar_acct = $self->get($underbar_pseudonym) ||
|
||||
$self->new_record($underbar_pseudonym, { type => 'pseudonym',
|
||||
Account => $user} );
|
||||
}
|
||||
|
||||
|
||||
=head2 $a->remove_all_user_pseudonyms($user)
|
||||
|
||||
Given a username, remove any pseudonyms related to that user from the
|
||||
accounts database. Also removes any pseudonyms related to a pseudonym
|
||||
being removed. Returns the number of pseudonym records deleted.
|
||||
|
||||
=cut
|
||||
|
||||
sub remove_all_user_pseudonyms {
|
||||
my ($self, $user) = @_;
|
||||
my $count = 0;
|
||||
foreach my $p_rec (grep { $_->prop("Account") eq $user } $self->pseudonyms())
|
||||
{
|
||||
foreach my $p_p_rec (grep { $_->prop("Account") eq $p_rec->key } $self->pseudonyms())
|
||||
{
|
||||
$p_p_rec->delete;
|
||||
$count++;
|
||||
}
|
||||
$p_rec->delete;
|
||||
$count++;
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
=head2 $a->remove_user_auto_pseudonyms($user)
|
||||
|
||||
Given a username, remove the dot_pseudonym and underbar_pseudonym
|
||||
related to that user from the accounts database. Returns the number
|
||||
of pseudonym records deleted.
|
||||
|
||||
=cut
|
||||
|
||||
sub remove_user_auto_pseudonyms {
|
||||
my ($self, $user) = @_;
|
||||
my $dot_pseudonym = dot_pseudonym($self, $user);
|
||||
my $underbar_pseudonym = underbar_pseudonym($self, $user);
|
||||
my $count = 0;
|
||||
foreach my $p_rec ($self->get($dot_pseudonym),
|
||||
$self->get($underbar_pseudonym))
|
||||
{
|
||||
if (defined $p_rec && $p_rec->prop("type") eq "pseudonym" &&
|
||||
$p_rec->prop("Account") eq $user)
|
||||
{
|
||||
$p_rec->delete;
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
=head2 $a->dot_pseudonym($user)
|
||||
|
||||
Returns the "dot"-style pseudonym for a user as a string. For instance,
|
||||
dot_pseudonym("bart") might return "bart.simpson".
|
||||
|
||||
=cut
|
||||
|
||||
sub dot_pseudonym {
|
||||
my ($self, $user) = @_;
|
||||
my $user_rec = $self->get($user);
|
||||
my $firstName = $user_rec->prop("FirstName");
|
||||
my $lastName = $user_rec->prop("LastName");
|
||||
|
||||
my $dot_pseudonym = lc("$firstName $lastName");
|
||||
|
||||
$dot_pseudonym =~ s/^\s+//; # Strip leading whitespace
|
||||
$dot_pseudonym =~ s/\s+$//; # Strip trailing whitespace
|
||||
$dot_pseudonym =~ s/\s+/ /g; # Multiple spaces become single spaces
|
||||
$dot_pseudonym =~ s/\s/./g; # Change all spaces to dots
|
||||
return $dot_pseudonym;
|
||||
}
|
||||
|
||||
=head2 $a->underbar_pseudonym($user)
|
||||
|
||||
Returns the "underbar"-style pseudonym for a user as a string. For instance,
|
||||
underbar_pseudonym("bart") might return "bart_simpson".
|
||||
|
||||
=begin testing
|
||||
|
||||
my @users = $a->users();
|
||||
my $user = 'bart';
|
||||
my $rec = $a->get($user);
|
||||
my $firstName = $rec->prop("FirstName");
|
||||
my $lastName = $rec->prop("LastName");
|
||||
my $up = $a->underbar_pseudonym($user);
|
||||
is($up, "bart_simpson", "Underbar pseudonym created correctly");
|
||||
my $dp = $a->dot_pseudonym($user);
|
||||
is($dp, "bart.simpson", "Underbar pseudonym created correctly");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub underbar_pseudonym {
|
||||
my ($self, $user) = @_;
|
||||
my $user_rec = $self->get($user);
|
||||
my $firstName = $user_rec->prop("FirstName");
|
||||
my $lastName = $user_rec->prop("LastName");
|
||||
|
||||
my $underbar_pseudonym = lc("$firstName $lastName");
|
||||
|
||||
$underbar_pseudonym =~ s/^\s+//; # Strip leading whitespace
|
||||
$underbar_pseudonym =~ s/\s+$//; # Strip trailing whitespace
|
||||
$underbar_pseudonym =~ s/\s+/ /g; # Multiple spaces become single spaces
|
||||
$underbar_pseudonym =~ s/\s/_/g; # Change all spaces to underbars
|
||||
return $underbar_pseudonym;
|
||||
}
|
||||
|
||||
=head2 $a->activeUsers()
|
||||
|
||||
Returns the number of active users, ie, accounts which have passwords set and
|
||||
are of type 'user'.
|
||||
|
||||
=begin testing
|
||||
|
||||
my $numActiveUsers = scalar $a->activeUsers();
|
||||
like($numActiveUsers, qr/[0-9]+/, "active users returns a number");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub activeUsers()
|
||||
{
|
||||
my $self = shift;
|
||||
my @users = $self->users();
|
||||
|
||||
return unless @users;
|
||||
return grep { $_->prop("PasswordSet") eq 'yes' } @users;
|
||||
}
|
||||
|
||||
=head2 get_next_uid
|
||||
|
||||
Returns the next available UID from /etc/passwd. All UIDs are above the range
|
||||
reserved for 'system' accounts (currently 5000).
|
||||
|
||||
=for testing
|
||||
SKIP: {
|
||||
skip "Must be root to run get_next_uid" if $<;
|
||||
my $u = $a->get_next_uid();
|
||||
ok($u > 5000, "UID should be greater than 5000");
|
||||
ok(! getpwuid($u), "UID should not yet exist");
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub get_next_uid {
|
||||
use esmith::ConfigDB;
|
||||
|
||||
my $id;
|
||||
my $db = esmith::ConfigDB->open || die "Couldn't open config db";
|
||||
|
||||
if ($id = $db->get('MinUid'))
|
||||
{
|
||||
$id = $id->value();
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->new_record('MinUid');
|
||||
$id = 5000;
|
||||
}
|
||||
|
||||
my $maxid = 1 << 31;
|
||||
setpwent();
|
||||
setgrent();
|
||||
while (getpwuid $id || getgrgid $id)
|
||||
{
|
||||
die "All userids in use" if ($id == $maxid);
|
||||
$id++;
|
||||
}
|
||||
endpwent();
|
||||
endgrent();
|
||||
|
||||
$db->set_value('MinUid', $id + 1);
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 new_record ($key, \%props)
|
||||
|
||||
This method is overridden from esmith::DB::db. We do an additional check
|
||||
for implicit accounts here - accounts that exist in /etc/passwd but not
|
||||
in the db. Otherwise it behaves just like the superclass method.
|
||||
|
||||
=begin testing
|
||||
|
||||
isnt($a->new_record("root", {type=>'system'}), "OK",
|
||||
"can't create existing account");
|
||||
is($a->get("nobody"), undef, "nobody doesn't exist in db");
|
||||
isnt($a->new_record("nobody", {type=>'system'}), "OK",
|
||||
"can't create account in /etc/passwd");
|
||||
isnt($a->new_record("screwy", {type=>'user'}), undef,
|
||||
"created a regular user");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub new_record
|
||||
{
|
||||
my ($self, $key, $props) = @_;
|
||||
|
||||
if(getpwnam($key) || getgrnam($key))
|
||||
{
|
||||
warn "Attempt to create account '$key' which already exists ",
|
||||
"in passwd";
|
||||
return undef;
|
||||
}
|
||||
return $self->SUPER::new_record($key, $props);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 validate_account_name ($name)
|
||||
|
||||
Check $name to see if it is a valid account name. Valid account names
|
||||
start with a letter or number and contain only letters, numbers,
|
||||
underscores, dots and dashes.
|
||||
|
||||
=begin testing
|
||||
|
||||
is($a->validate_account_name("root"), "OK", "root is a valid name");
|
||||
is($a->validate_account_name("fred.frog"), "OK", "fred.frog is a valid name");
|
||||
is($a->validate_account_name("jane_doe"), "OK", "jane_doe is a valid name");
|
||||
isnt($a->validate_account_name("^root"), "OK", "^root is not a valid name");
|
||||
is(esmith::AccountsDB::validate_account_name("root"), "OK", "called as a function");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub validate_account_name
|
||||
{
|
||||
my $self;
|
||||
# Were we called as a method or a function?
|
||||
if($#_ > 0)
|
||||
{
|
||||
$self = shift;
|
||||
}
|
||||
my $name = shift;
|
||||
return ($name =~ /[^0-9a-z\-_\.]/ or $name !~ /^[a-z]/) ? undef : 'OK';
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
SME Server Developers <bugs@e-smith.com>
|
||||
|
||||
See http://www.e-smith.org/ for more information
|
||||
|
||||
|
||||
|
398
root/usr/share/perl5/vendor_perl/esmith/ConfigDB.pm
Normal file
398
root/usr/share/perl5/vendor_perl/esmith/ConfigDB.pm
Normal file
@ -0,0 +1,398 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::ConfigDB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use vars qw( $AUTOLOAD @ISA );
|
||||
|
||||
use esmith::DB::db;
|
||||
@ISA = qw( esmith::DB::db );
|
||||
|
||||
use esmith::ConfigDB::Record;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::ConfigDB - interface to esmith configuration database
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::ConfigDB;
|
||||
my $db = esmith::ConfigDB->open;
|
||||
my $db = esmith::ConfigDB->open_ro;
|
||||
|
||||
my @services = $db->services();
|
||||
|
||||
# Singleton Records
|
||||
my $record = $db->get($key);
|
||||
my $value = $record->value;
|
||||
$record->set_value($value);
|
||||
|
||||
# BAD!
|
||||
my $value = $db->get($key)->value() # Throws a runtime error if $key
|
||||
# doesn't exist
|
||||
$value = $db->get($key)->prop($p) # Throws a runtime error if $key
|
||||
# doesn't exist
|
||||
|
||||
# GOOD
|
||||
my $record = $db->get($key);
|
||||
my $value;
|
||||
if ($record)
|
||||
{
|
||||
$value = $record->prop($prop);
|
||||
}
|
||||
|
||||
# Typed Records (eventually they all will be)
|
||||
my $prop = $record->prop($p);
|
||||
$record->set_prop($prop, $propvalue);
|
||||
my $value = $db->get_value($key) # Returns undef if record doesn't exist
|
||||
$value = $db->get_prop($key, $p) # Returns undef if record doesn't exist
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides an abstracted interface to the esmith master
|
||||
configuration database.
|
||||
|
||||
Unless otherwise noted, esmith::ConfigDB acts like esmith::DB::db.
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = sprintf '%d.%03d', q$Revision: 1.29 $ =~ /: (\d+).(\d+)/;
|
||||
|
||||
=head2 open()
|
||||
|
||||
Like esmith::DB->open, but if given no $file it will try to open the
|
||||
file in the ESMITH_CONFIG_DB environment variable or configuration.
|
||||
|
||||
=begin testing
|
||||
|
||||
use esmith::TestUtils qw(scratch_copy);
|
||||
use_ok("esmith::ConfigDB");
|
||||
|
||||
my $scratch_copy_of_conf = scratch_copy('10e-smith-lib/configuration.conf');
|
||||
$C = esmith::ConfigDB->open($scratch_copy_of_conf);
|
||||
isa_ok($C, 'esmith::ConfigDB');
|
||||
is( $C->get("AccessType")->prop('type'), "dedicated",
|
||||
"We can get stuff from the db");
|
||||
|
||||
is( $C->get_prop("AccessType",'type'), "dedicated",
|
||||
"We can get_prop stuff from the db");
|
||||
|
||||
is( $C->get_value("AccessType"), "dedicated",
|
||||
"We can get_value stuff from the db");
|
||||
|
||||
is( $C->get_value("NoSuchKey"), undef,
|
||||
"We can get_value non-existant keys");
|
||||
|
||||
is( $C->get_prop("diald","status"), "disabled",
|
||||
"We can get_prop stuff from the db");
|
||||
|
||||
is( $C->get_prop("NoSuchKey","NoSuchProp"), undef,
|
||||
"We can get_prop non-existant keys");
|
||||
|
||||
is( $C->get_prop("diald","NoSuchProp"), undef,
|
||||
"We can get_prop non-existant props");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
$file = $file || $ENV{ESMITH_CONFIG_DB} || "configuration";
|
||||
return $class->SUPER::open($file);
|
||||
}
|
||||
|
||||
=head2 open_ro()
|
||||
|
||||
Like esmith::DB->open_ro, but if given no $file it will try to open the
|
||||
file in the ESMITH_CONFIG_DB environment variable or configuration.
|
||||
|
||||
=begin testing
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open_ro
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
$file = $file || $ENV{ESMITH_CONFIG_DB} || "configuration";
|
||||
return $class->SUPER::open_ro($file);
|
||||
}
|
||||
|
||||
=head2 new_record()
|
||||
|
||||
This method creates a new record in the configuration database. As arguments,
|
||||
it expects the key to the record, followed by a hash references with its
|
||||
properties, including the type.
|
||||
|
||||
my $db = esmith::ConfigDB->open;
|
||||
my $record = $db->new_record('zope', { type => 'service',
|
||||
status => 'disabled' });
|
||||
|
||||
my %defaults = qw(
|
||||
type => 'service',
|
||||
status => 'disabled',
|
||||
maintainer => 'admin@domain.com'
|
||||
);
|
||||
my $record = $db->get('zope');
|
||||
unless ($record)
|
||||
{
|
||||
$record = $db->new_record('zope', \%defaults);
|
||||
}
|
||||
|
||||
=head2 get()
|
||||
|
||||
Like their esmith::DB counterparts except they return
|
||||
esmith::ConfigDB::Record objects which have a few extra methods.
|
||||
|
||||
my $record = $db->get('zope');
|
||||
|
||||
=begin testing
|
||||
|
||||
my $rec = eval { $C->get("I_dont_exist"); };
|
||||
ok( !$rec, 'get() on a non-existent key' );
|
||||
is( $@, '', ' doesnt blow up' );
|
||||
|
||||
isa_ok( $C->get("AccessType"), 'esmith::ConfigDB::Record',
|
||||
"get()ened records are ConfigDB::Records" );
|
||||
|
||||
$rec = $C->new_record("I_dont_exist", { type => "foo" });
|
||||
isa_ok( $rec, 'esmith::ConfigDB::Record',
|
||||
"new_record()s are ConfigDB::Records" );
|
||||
$rec->delete("I_dont_exist");
|
||||
ok( !$C->get("I_dont_exist"), 'delete()' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub get
|
||||
{
|
||||
my ($self) = shift;
|
||||
|
||||
my $rec = $self->SUPER::get(@_);
|
||||
return $rec ? bless $rec, 'esmith::ConfigDB::Record' : undef;
|
||||
}
|
||||
|
||||
sub new_record
|
||||
{
|
||||
my ($self) = shift;
|
||||
|
||||
my $rec = $self->SUPER::new_record(@_);
|
||||
return $rec ? bless $rec, 'esmith::ConfigDB::Record' : undef;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 getLocale()
|
||||
|
||||
Retrieves the locale and keyboard settings from the configuration database.
|
||||
Returns ($lang, $kbdtype, $keytable) on success. Returns undef if the record
|
||||
doesn't exist.
|
||||
|
||||
=cut
|
||||
|
||||
sub getLocale
|
||||
{
|
||||
my $self = shift;
|
||||
my $rec = $self->get('sysconfig') or return undef;
|
||||
my $lang = $rec->prop('Language') || 'en_US';
|
||||
my $kbdtype = $rec->prop('KeyboardType') || 'pc';
|
||||
my $keytable = $rec->prop('Keytable') || 'us';
|
||||
return ( $lang, $kbdtype, $keytable );
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 hosts_allow_spec ($service [,$daemon])
|
||||
|
||||
Given a service, return the string suitable for /etc/hosts.allow,
|
||||
checking to see if the service is defined, whether it is enabled and
|
||||
whether access is set to public, private, or localhost.
|
||||
|
||||
An optional argument provides the tag which appears in hosts.allow. If not
|
||||
given, the service name is used.
|
||||
|
||||
For example, one of the following:
|
||||
|
||||
# 'oidentd' is not defined in the configuration database
|
||||
# 'oidentd' is disabled in the configuration database
|
||||
in.identd: 127.0.0.1
|
||||
in.identd: 127.0.0.1 192.168.1.1/255.255.255.0
|
||||
in.identd: ALL
|
||||
|
||||
And here's the hosts.allow fragment:
|
||||
|
||||
{
|
||||
$OUT = $DB->hosts_allow_spec('oidentd', 'in.identd');
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub hosts_allow_spec
|
||||
{
|
||||
my $self = shift;
|
||||
my $service_name = shift;
|
||||
my $daemon = shift || $service_name;
|
||||
|
||||
my $service = $self->get($service_name)
|
||||
or return
|
||||
"# '$service_name' is not defined in the configuration database";
|
||||
|
||||
my $status = $service->prop('status') || "disabled";
|
||||
return "# '$service_name' is disabled in the configuration database"
|
||||
unless ( $status eq "enabled" );
|
||||
|
||||
my $access = $service->prop('access') || "private";
|
||||
|
||||
use esmith::NetworksDB;
|
||||
my $ndb = esmith::NetworksDB->open_ro;
|
||||
|
||||
my @spec = ( "$daemon:", $ndb->local_access_spec($access) );
|
||||
return "@spec";
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 wins_server
|
||||
|
||||
Return the value of the WINS server from the config db
|
||||
or undef if we don't have a WINS server set and we are
|
||||
not the domain master
|
||||
|
||||
=cut
|
||||
|
||||
sub wins_server
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
my $wins_server = $self->get_prop( 'smb', 'WINSServer' );
|
||||
|
||||
return $wins_server if $wins_server;
|
||||
|
||||
my $server_role = $self->get_prop( 'smb', 'ServerRole' ) || 'WS';
|
||||
|
||||
return $self->get_prop( 'InternalInterface', 'IPAddress' )
|
||||
if $server_role =~ m{^(PDC|ADS)$};
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 services()
|
||||
|
||||
Returns a list of services in the configuration database
|
||||
|
||||
=for testing
|
||||
foreach my $t (qw(services)) {
|
||||
my @list = $C->$t();
|
||||
ok(@list, "Got a list of $t");
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub AUTOLOAD
|
||||
{
|
||||
my $self = shift;
|
||||
my ($called_sub_name) = ( $AUTOLOAD =~ m/([^:]*)$/ );
|
||||
my @types = qw( services );
|
||||
if ( grep /^$called_sub_name$/, @types )
|
||||
{
|
||||
$called_sub_name =~ s/s$//g; # de-pluralize
|
||||
return $self->list_by_type($called_sub_name);
|
||||
}
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 _loadDefaults ($forceReset)
|
||||
|
||||
Behaves just like the esmith::DB method of the same name. This is a private
|
||||
method used internally.
|
||||
|
||||
=begin testing
|
||||
|
||||
$scratch_copy_of_conf = scratch_copy('10e-smith-lib/configuration.conf', 'configuration.conf.scratch');
|
||||
is ($scratch_copy_of_conf, 'configuration.conf.scratch', 'scratch copy name');
|
||||
$ENV{'ESMITH_CONFIG_DB'} = $scratch_copy_of_conf;
|
||||
$C = esmith::ConfigDB->open();
|
||||
is ($C->{file}, $scratch_copy_of_conf, 'file name');
|
||||
my $accesstype = $C->get("AccessType")->value;
|
||||
ok($C->new_record('foobar', {type=>'service', status=>'disabled'}),
|
||||
"Set up foobar record");
|
||||
is($C->get('foobar')->prop('status'), "disabled", "foobar is disabled");
|
||||
$ENV{'ESMITH_DB_DEFAULTSDIR'} = "10e-smith-lib/db";
|
||||
ok($C->_loadDefaults(), "Loaded defaults");
|
||||
is($C->get('foobar')->prop('status'), 'enabled', "We forced status enabled");
|
||||
is($C->get('bazbar')->prop('status'), 'enabled', "We included a new default");
|
||||
is($C->get('AccessType')->value, $accesstype, "AccessType has not changed");
|
||||
|
||||
=end testing
|
||||
|
||||
=head2 record_has_defaults ($name)
|
||||
|
||||
Behaves just like the esmith::DB method of the same name.
|
||||
|
||||
=begin testing
|
||||
|
||||
$ENV{'ESMITH_DB_DEFAULTSDIR'} = "10e-smith-lib/db";
|
||||
is($C->record_has_defaults('foobar'), 1, "foobar has some defaults");
|
||||
is($C->record_has_defaults('notthisone'), undef, "notthisone does not");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
# There would normally be a method here, but we inherit _loadDefaults
|
||||
# from esmith::DB. The tests need to go here because the superclass is
|
||||
# all virtual and testing requires concrete open/get/set methods.
|
||||
|
||||
=pod
|
||||
|
||||
=head2 migrate
|
||||
|
||||
Just like the esmith::DB method of the same name.
|
||||
|
||||
=begin testing
|
||||
|
||||
$scratch_copy_of_conf = scratch_copy('10e-smith-lib/configuration.conf', 'configuration.conf.scratch');
|
||||
is ($scratch_copy_of_conf, 'configuration.conf.scratch', 'scratch copy name');
|
||||
$ENV{'ESMITH_CONFIG_DB'} = $scratch_copy_of_conf;
|
||||
$C = esmith::ConfigDB->open();
|
||||
is($C->get('quux'), undef, "No quux here");
|
||||
$ENV{'ESMITH_DB_DEFAULTSDIR'} = "10e-smith-lib/db";
|
||||
ok($C->migrate(), "We can migrate");
|
||||
my $quux = $C->get('quux');
|
||||
ok($quux, "We got quux");
|
||||
is($quux->prop('status'), 'enabled', "We migrated to quux");
|
||||
$quux->delete;
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
# There would normally be a method here, but we inherit migrate
|
||||
# from esmith::DB. The tests need to go here because the superclass is
|
||||
# all virtual and testing requires concrete open/get/set methods.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
SME Server Developers <bugs@e-smith.com>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<esmith::DB>, L<esmith::DB::db>, L<esmith::AccountsDB>, L<esmith::DomainsDB>,
|
||||
L<esmith::HostsDB>, L<esmith::NetworksDB>, L<esmith::ConfigDB::Record>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
108
root/usr/share/perl5/vendor_perl/esmith/ConfigDB/Record.pm
Normal file
108
root/usr/share/perl5/vendor_perl/esmith/ConfigDB/Record.pm
Normal file
@ -0,0 +1,108 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::ConfigDB::Record;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use esmith::ConfigDB;
|
||||
require esmith::DB::db::Record;
|
||||
our @ISA = qw(esmith::DB::db::Record);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::ConfigDB::Record - record in an esmith::ConfigDB database.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Just like esmith::DB::db::Record except...
|
||||
|
||||
my $value = $record->value;
|
||||
$record->set_value($value);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This provides some extra functionality needed by the esmith::ConfigDB
|
||||
databases.
|
||||
|
||||
Unless noted, it works just like esmith::DB::db::Record.
|
||||
|
||||
=head2 New Methods
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<value>
|
||||
|
||||
=item B<set_value>
|
||||
|
||||
my $value = $record->value;
|
||||
$record->set_value($value);
|
||||
|
||||
Gets/sets the value of the $record. Some ConfigDB entries don't have
|
||||
a set of properties, but rather a single value.
|
||||
|
||||
It will warn if you use these on $records with properties.
|
||||
|
||||
=begin testing
|
||||
|
||||
use esmith::ConfigDB;
|
||||
$Scratch_Conf = '10e-smith-lib/scratch.conf';
|
||||
unlink $Scratch_Conf;
|
||||
$c = esmith::ConfigDB->create($Scratch_Conf);
|
||||
END { unlink $Scratch_Conf }
|
||||
|
||||
{
|
||||
my $warning = '';
|
||||
local $SIG{__WARN__} = sub { $warning = join '', @_ };
|
||||
|
||||
my $wib = $c->new_record('wibble', { type => 'yar' });
|
||||
$wib->set_value('foo');
|
||||
is( $wib->value, 'foo', 'value/set_value' );
|
||||
is( $warning, '', ' no warning' );
|
||||
|
||||
$wib->set_prop(bar => 42);
|
||||
is( $wib->value, 'foo' );
|
||||
like( $warning, qr/value\(\) should not be used on records with properties, use prop\(\)/, 'value() warns if the record has props');
|
||||
|
||||
$wib->set_value(92);
|
||||
like( $warning, qr/set_value\(\) should not be used on records with properties, use set_prop\(\)/, 'value() warns if the record has props');
|
||||
is( $wib->value, 92 );
|
||||
}
|
||||
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub value {
|
||||
my($self) = shift;
|
||||
|
||||
my %props = $self->props;
|
||||
warn "value() should not be used on records with properties, use prop()" if
|
||||
keys %props > 1;
|
||||
return $self->prop('type');
|
||||
}
|
||||
|
||||
sub set_value {
|
||||
my($self, $value) = @_;
|
||||
|
||||
my %props = $self->props;
|
||||
warn "set_value() should not be used on records with properties, ".
|
||||
"use set_prop()" if keys %props > 1;
|
||||
return $self->set_prop('type', $value);
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<esmith::ConfigDB>, L<esmith::DB::db::Record>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
22
root/usr/share/perl5/vendor_perl/esmith/ConfigDB/UTF8.pm
Normal file
22
root/usr/share/perl5/vendor_perl/esmith/ConfigDB/UTF8.pm
Normal file
@ -0,0 +1,22 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2008 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::ConfigDB::UTF8;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use esmith::DB::db;
|
||||
use esmith::config::utf8;
|
||||
our @ISA = qw( esmith::DB::db );
|
||||
|
||||
sub tie_class
|
||||
{
|
||||
return 'esmith::config::utf8';
|
||||
}
|
||||
|
||||
1;
|
||||
|
705
root/usr/share/perl5/vendor_perl/esmith/DB.pm
Normal file
705
root/usr/share/perl5/vendor_perl/esmith/DB.pm
Normal file
@ -0,0 +1,705 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::DB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp;
|
||||
use File::Basename;
|
||||
use esmith::templates;
|
||||
|
||||
use constant TRUE => 1;
|
||||
use constant FALSE => 0;
|
||||
|
||||
our $VERSION = sprintf '%d.%03d', q$Revision: 1.40 $ =~ /: (\d+).(\d+)/;
|
||||
our $Error = undef;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::DB - virtual interface to E-Smith databases
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
# Note: Do not instantiate this class directly. Use a subclass.
|
||||
# Examples in this documentation where you see it being used directly
|
||||
# are merely for consistency. Substitute a subclass in our examples.
|
||||
use esmith::DB;
|
||||
my $db = esmith::DB->create($filename) or
|
||||
die esmith::DB->error;
|
||||
my $db = esmith::DB->open($filename) or
|
||||
die esmith::DB->error;
|
||||
my $db = esmith::DB->open_ro($filename) or
|
||||
die esmith::DB->error;
|
||||
|
||||
my %DB = esmith::DB->as_hash($filename) or
|
||||
die esmith::DB->error;
|
||||
|
||||
$db->reload;
|
||||
|
||||
my $file = $db->file;
|
||||
|
||||
my $record = $db->new_record($key, \%properties);
|
||||
|
||||
my $record = $db->get($key);
|
||||
my @all_records = $db->get_all;
|
||||
my @all_records_by_prop = $db->get_all_by_prop($prop => $val);
|
||||
|
||||
$db->set_prop($key, $prop, $value);
|
||||
$db->set_value($key, $value);
|
||||
|
||||
$db->set_prop($key, $prop, $value, type => $type);
|
||||
$db->set_value($key, $value, create => 0);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module is a general interface to E-Smith's databases of various
|
||||
types and formats. It is not intended to be used directly, but that
|
||||
subclasses will implement the interface presented here to provide a
|
||||
single interface no matter what the underlying format.
|
||||
|
||||
For example, there is esmith::DB::db to interface with esmith::db
|
||||
flatfile databases. There could also be esmith::DB::Berkeley to use
|
||||
Berkeley database files, or even esmith::DB::DBI.
|
||||
|
||||
Most of the methods herein are "virtual". They don't exist. The
|
||||
subclass is responsible for impelmenting them. There are a handful of
|
||||
concrete methods that have been implemented for you that should work
|
||||
with any subclass.
|
||||
|
||||
=head2 Virtual Methods
|
||||
|
||||
This is the esmith::DB interface. Subclassers are expected to
|
||||
implement these methods.
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<create>
|
||||
|
||||
my $db = esmith::DB->create($new_config_file) ||
|
||||
die esmith::DB->error;
|
||||
|
||||
Creates a brand new, empty configuration database and returns a
|
||||
subclass of the esmith::DB object representing it.
|
||||
|
||||
Should the $new_config_file already exist or for some reason you can't
|
||||
write to it, esmith::DB->error will return the reason and
|
||||
create() will return false.
|
||||
|
||||
=item I<open>
|
||||
|
||||
my $db = esmith::DB->open($config_file) ||
|
||||
die esmith::DB->error
|
||||
|
||||
Loads an existing configuration database and returns a
|
||||
subclass of the esmith::DB::db object representing it.
|
||||
|
||||
Should the $config_file not exist or not be openable it will return
|
||||
false and esmith::DB->error will contain the reason.
|
||||
|
||||
=item I<open_ro>
|
||||
|
||||
my $db = esmith::DB->open_ro($config_file) ||
|
||||
die esmith::DB->error;
|
||||
|
||||
Like open(), but the database is read-only. new_record() and all methods
|
||||
which could change a record (set_prop(), merge_props(), delete(), etc...)
|
||||
will both throw exceptions if used.
|
||||
|
||||
=item I<error>
|
||||
|
||||
my $error = esmith::DB->error;
|
||||
|
||||
Returns a string describing the error from the last failing method.
|
||||
|
||||
=item I<reload>
|
||||
|
||||
$db->reload;
|
||||
|
||||
Flushes out the $db's cache (if there is one) and reloads all
|
||||
configuration data from disk.
|
||||
|
||||
=item I<file>
|
||||
|
||||
my $file = $db->file;
|
||||
|
||||
File which this $db represents.
|
||||
|
||||
=item I<new_record>
|
||||
|
||||
my $record = $db->new_record($key, \%properties);
|
||||
|
||||
Adds a new record at $key in the $db setting it to the given
|
||||
%properties. Returns a subclass of the esmith::DB::Record object.
|
||||
|
||||
If a record already exists for the $key it will return false.
|
||||
|
||||
=item I<get>
|
||||
|
||||
my $record = $db->get($key);
|
||||
|
||||
Gets an existing record from the $db with the given $key. Returns an
|
||||
esmith::DB::Record object representing the data in $key.
|
||||
|
||||
If there's no record for the $key it will return false.
|
||||
|
||||
=item I<get_all>
|
||||
|
||||
my @records = $db->get_all;
|
||||
|
||||
Gets all the records out of the given $db as a list of
|
||||
esmith::DB::Record objects.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Concrete methods
|
||||
|
||||
These are all implemented in terms of the esmith::DB interface and
|
||||
its not necessary for a subclass to implement them.
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<as_hash>
|
||||
|
||||
my %db = $db->as_hash;
|
||||
my %db = esmith::DB->as_hash($file);
|
||||
|
||||
Returns the entire database as a hash of hashes. Each key is a key in
|
||||
the database, and the value is a hash of it's properties.
|
||||
|
||||
my $value = $db{some_key}{some_prop};
|
||||
|
||||
When used as an object method it will use the already opened database.
|
||||
When used as a class method it will open the given $file.
|
||||
|
||||
=cut
|
||||
|
||||
sub as_hash
|
||||
{
|
||||
my ( $proto, $file ) = @_;
|
||||
my $class = ref $proto || $proto;
|
||||
|
||||
my $self;
|
||||
if ( ref $proto )
|
||||
{ # object method
|
||||
$self = $proto;
|
||||
}
|
||||
else
|
||||
{ # class method
|
||||
$self = $class->open($file) or return;
|
||||
}
|
||||
my %hash = ();
|
||||
foreach my $rec ( $self->get_all )
|
||||
{
|
||||
my $key = $rec->key;
|
||||
my %props = $rec->props;
|
||||
|
||||
# Setup the hash
|
||||
$hash{$key} = \%props;
|
||||
}
|
||||
|
||||
return %hash;
|
||||
}
|
||||
|
||||
=item I<get_all_by_prop>
|
||||
|
||||
my @records_by_prop = $db->get_all_by_prop($property => $value);
|
||||
|
||||
Like get_all() except it gets only those records whose $property has
|
||||
the given $value. For properties with multiple comma-delimited values
|
||||
(ie: name|val1,val2,val3), only one of the properties needs to match.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_all_by_prop
|
||||
{
|
||||
my ( $self, $prop, @rest ) = @_;
|
||||
my %props;
|
||||
|
||||
if ( ref($prop) eq 'HASH' )
|
||||
{
|
||||
carp "get_all_by_prop called with anonymous hash argument";
|
||||
%props = ( %{$prop} );
|
||||
}
|
||||
else
|
||||
{
|
||||
%props = ($prop, @rest);
|
||||
}
|
||||
my @things = sort { $a->key cmp $b->key } grep
|
||||
{
|
||||
my $found = 1;
|
||||
while ( my ($p, $v) = each (%props) )
|
||||
{
|
||||
$found &= ( defined $_->prop($p) and $_->prop($p) =~ /(?:^|,)$v(?:,|$)/ );
|
||||
}
|
||||
$found;
|
||||
} $self->get_all;
|
||||
@things;
|
||||
}
|
||||
|
||||
=item I<get_value>
|
||||
|
||||
my $value = $db->get_value( $key );
|
||||
|
||||
Shortcut method to get the value from the record defined by the given
|
||||
key. Returns undef if the record does not exist.
|
||||
|
||||
The following code is unsafe if the key doesn't exist:
|
||||
|
||||
my $value = $db->get("foo")->value || 'default';
|
||||
|
||||
and should be:
|
||||
|
||||
my $value = 'default';
|
||||
|
||||
if (my $r = $db->get("foo"))
|
||||
{
|
||||
$value = $r->value;
|
||||
}
|
||||
|
||||
With this method, you can use:
|
||||
|
||||
my $value = $db->get_value("foo") || 'default';
|
||||
|
||||
=cut
|
||||
|
||||
sub get_value
|
||||
{
|
||||
my $self = shift;
|
||||
my $item = $self->get(shift);
|
||||
return undef unless $item;
|
||||
return $item->value;
|
||||
}
|
||||
|
||||
=item I<get_prop>
|
||||
|
||||
my $prop = $db->get_prop( $key, $prop );
|
||||
|
||||
Shortcut method to get a property from the record defined by the given key.
|
||||
|
||||
Returns undef if the record for that key doesn't exist, or the property does
|
||||
not exist.
|
||||
|
||||
The following code is unsafe if either the key or property doesn't exist:
|
||||
|
||||
my $status = $db->get("foo")->prop('status') || 'disabled';
|
||||
|
||||
and should be written as:
|
||||
|
||||
my $status;
|
||||
|
||||
if (my $s = $db->get("foo"))
|
||||
{
|
||||
$status = $s->prop('status');
|
||||
}
|
||||
|
||||
$status ||= "default";
|
||||
|
||||
With this method, you can use:
|
||||
|
||||
my $value = $db->get_prop("foo", "status") || 'default';
|
||||
|
||||
=cut
|
||||
|
||||
sub get_prop
|
||||
{
|
||||
my $self = shift;
|
||||
my $item = $self->get(shift);
|
||||
return undef unless $item;
|
||||
return $item->prop(shift);
|
||||
}
|
||||
|
||||
=item I<set_value>
|
||||
|
||||
$db->set_value($key, $value)[, create => 1]);
|
||||
|
||||
Shortcut method to set a value to a key in the database without extracting the
|
||||
record first.
|
||||
|
||||
If the record is not pre-existing, it will be created, unless the 'create'
|
||||
option is passed with a value of 0.
|
||||
|
||||
Returns 0 for any errors, 1 for success.
|
||||
|
||||
=cut
|
||||
|
||||
sub set_value
|
||||
{
|
||||
my $self = shift;
|
||||
my ($key, $value, %options) = @_;
|
||||
|
||||
my %defaults = (create => 1);
|
||||
%options = (%defaults, %options);
|
||||
|
||||
my $record = $self->get($key);
|
||||
unless ($record)
|
||||
{
|
||||
if ($options{create})
|
||||
{
|
||||
$record = $self->new_record($key, {type => $value})
|
||||
or return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
$record->set_value($value)
|
||||
or return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=item I<set_prop>
|
||||
|
||||
$db->set_prop($key, $prop, $value[, type => $type]);
|
||||
|
||||
Shortcut method to set a property on a record without having to extract the
|
||||
record first.
|
||||
|
||||
If the optional type option is passed, it will be used to create the record if
|
||||
it does not already exist. Otherwise, a non-existent record will cause this
|
||||
method to return an error.
|
||||
|
||||
Returns 0 for any errors, 1 for success.
|
||||
|
||||
=cut
|
||||
|
||||
sub set_prop
|
||||
{
|
||||
my $self = shift;
|
||||
my ($key, $prop, $value, %options) = @_;
|
||||
my %defaults = (type => '');
|
||||
%options = (%defaults, %options);
|
||||
|
||||
my $record = $self->get($key);
|
||||
unless ($record)
|
||||
{
|
||||
if ($options{type})
|
||||
{
|
||||
$record = $self->new_record($key, {type => $options{type}})
|
||||
or return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
$record->set_prop($prop, $value)
|
||||
or return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
=item I<keys>
|
||||
|
||||
foreach my $key ($db->keys)
|
||||
{
|
||||
|
||||
A simple convenience function to prevent having to access the config hash
|
||||
inside the db object (technically private), or calling map across a get_all
|
||||
call, which is what this is going to do. :)
|
||||
|
||||
This method returns a list of keys to the records in the db. It does not sort.
|
||||
|
||||
=cut
|
||||
|
||||
sub keys
|
||||
{
|
||||
my $self = shift;
|
||||
return map { $_->{key} } $self->get_all;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 migrate
|
||||
|
||||
Process the fragments in the migration queue for this database, using
|
||||
processTemplate.
|
||||
|
||||
The defaults are loaded from /etc/e-smith/db/<dbname>/migrate by default, but
|
||||
the environment variable ESMITH_DB_DEFAULTSDIR can be set to use a different
|
||||
hierarchy if required.
|
||||
|
||||
The entries in "migrate" are perl fragments which will be evaluated and
|
||||
so can munge anything they choose to. But, please be gentle :-)
|
||||
|
||||
So you could have
|
||||
|
||||
/etc/e-smith/db/configuration/migrate/sshd/access
|
||||
|
||||
which is a perl fragment which does something funky to migrate the access
|
||||
property from some old value to some new value.
|
||||
|
||||
After running all the migration scripts, and reloading the DB's data into
|
||||
its local cache, the private method _loadDefaults is called to set any
|
||||
missing default values and any forced settings.
|
||||
|
||||
=cut
|
||||
|
||||
sub migrate
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
my $dbfile = basename( $self->{file} );
|
||||
unless ($dbfile)
|
||||
{
|
||||
carp "migrate can't determine filename";
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $defaults_dir = $ENV{ESMITH_DB_DEFAULTSDIR} || "/etc/e-smith/db";
|
||||
my $dir = "$defaults_dir/$dbfile/migrate";
|
||||
|
||||
eval {
|
||||
if ( -d $dir )
|
||||
{
|
||||
processTemplate(
|
||||
{
|
||||
MORE_DATA => { 'DB_FILENAME' => $dbfile },
|
||||
TEMPLATE_PATH => '',
|
||||
OUTPUT_TYPE => 'string',
|
||||
TEMPLATE_EXPAND_QUEUE =>
|
||||
[ $dir, "/etc/e-smith/templates-default" ]
|
||||
}
|
||||
);
|
||||
$self->reload;
|
||||
}
|
||||
$self->_loadDefaults();
|
||||
};
|
||||
if ($@)
|
||||
{
|
||||
warn "Warning: Migration of $dbfile failed fatally: $@\n";
|
||||
$self->set_error($@);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 resetToDefaults
|
||||
|
||||
Reset all entries to their default values, if defaults exist. This calls
|
||||
the internal method _loadDefaults with the forceReset flag set. It should
|
||||
not be used lightly!!
|
||||
|
||||
=cut
|
||||
|
||||
sub resetToDefaults
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
$self->_loadDefaults(1);
|
||||
}
|
||||
|
||||
=head2 record_has_defaults
|
||||
|
||||
Returns true if there are defaults or force directories for the
|
||||
given record name
|
||||
|
||||
=cut
|
||||
|
||||
sub record_has_defaults
|
||||
{
|
||||
my ( $self, $name ) = @_;
|
||||
|
||||
my $dbfile = basename( $self->{file} );
|
||||
|
||||
unless ($dbfile)
|
||||
{
|
||||
carp "record_has_defaults can't determine filename";
|
||||
return undef;
|
||||
}
|
||||
|
||||
unless ($name)
|
||||
{
|
||||
carp "record_has_defaults can't determine record name";
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $defaults_dir = $ENV{ESMITH_DB_DEFAULTSDIR} || "/etc/e-smith/db";
|
||||
my $dir = "$defaults_dir/$dbfile";
|
||||
|
||||
return ( -d "$dir/defaults/$name" ) || ( -d "$dir/force/$name" );
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 _loadDefaults ($forceReset)
|
||||
|
||||
B<This is a private method.>
|
||||
|
||||
Load the default properties for a given database.
|
||||
Caller can provide a flag to force resetting properties that already exist.
|
||||
|
||||
Any forced properties will be evaluated after setting the default properties.
|
||||
|
||||
The defaults are loaded from the following directories in order (the
|
||||
environment variable ESMITH_DB_DEFAULTSDIR can be set to use a different
|
||||
hierarchy if required):
|
||||
|
||||
/etc/e-smith/db/<dbname>/defaults
|
||||
/etc/e-smith/db/<dbname>/force
|
||||
|
||||
Each of these directories is arranged as a set of subdirectories, with the
|
||||
directory name equal to the key for the given database. With these
|
||||
subdirectories are files, which are named by the properties of these
|
||||
database keys.
|
||||
|
||||
The entries in "defaults" will be skipped if the existing key/property
|
||||
already exists (unless the $forceReset argument is provided). These are
|
||||
simple files, whose contents are the value to be used for that property.
|
||||
|
||||
The entries in "force" are always loaded into the given key/property.
|
||||
These are again simple files, like "defaults".
|
||||
|
||||
To make this concrete, you might have:
|
||||
|
||||
/etc/e-smith/db/configuration/defaults/sshd/access
|
||||
|
||||
containing the single word "private", which would be the default. This
|
||||
value would only be used if no "access" property existed, or the
|
||||
$forceReset option is passed.
|
||||
|
||||
You can override both "defaults" and "migrate" with
|
||||
|
||||
/etc/e-smith/db/configuration/force/sshd/access
|
||||
|
||||
containing the single word "public" to force the value of that property.
|
||||
|
||||
=cut
|
||||
|
||||
sub _loadDefaults
|
||||
{
|
||||
my ( $self, $force ) = @_;
|
||||
|
||||
my $dbfile = basename( $self->{file} );
|
||||
unless ($dbfile)
|
||||
{
|
||||
carp "_loadDefaults can't determine filename";
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $defaults_dir = $ENV{ESMITH_DB_DEFAULTSDIR} || "/etc/e-smith/db";
|
||||
|
||||
my @propQueue =
|
||||
( "$defaults_dir/$dbfile/defaults", "$defaults_dir/$dbfile/force", );
|
||||
|
||||
foreach my $dir (@propQueue)
|
||||
{
|
||||
|
||||
# Always process the force dir
|
||||
$force = 1 if ( $dir =~ /\/force$/ );
|
||||
|
||||
next unless opendir DH, $dir;
|
||||
foreach my $key ( grep !/^\./, readdir DH )
|
||||
{
|
||||
if ( -d "$dir/$key" )
|
||||
{
|
||||
my %props = ();
|
||||
|
||||
my $rec = $self->get($key);
|
||||
|
||||
opendir DH2, "$dir/$key";
|
||||
foreach my $prop ( grep !/^\./, readdir DH2 )
|
||||
{
|
||||
unless ($force)
|
||||
{
|
||||
next if ( $rec && defined $rec->prop($prop) );
|
||||
}
|
||||
open FH, "$dir/$key/$prop";
|
||||
my $val = join "", (<FH>);
|
||||
chomp $val;
|
||||
|
||||
$props{$prop} = $val;
|
||||
close FH;
|
||||
}
|
||||
closedir DH2;
|
||||
if ($rec)
|
||||
{
|
||||
$rec->merge_props(%props);
|
||||
}
|
||||
else
|
||||
{
|
||||
$rec = $self->new_record( $key, \%props );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
warn "Found non-directory $key in $dir\n";
|
||||
}
|
||||
}
|
||||
close DH;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 get_value_and_delete ($key)
|
||||
|
||||
Retrieve the value of the named key, return it, and delete the record.
|
||||
If the key does not exist, it returns undef. This is normally called from
|
||||
migration code.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_value_and_delete
|
||||
{
|
||||
my ( $self, $key ) = @_;
|
||||
my $ret;
|
||||
my $rec = $self->get($key);
|
||||
if ($rec)
|
||||
{
|
||||
$ret = $rec->value;
|
||||
$rec->delete;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 get_prop_and_delete ($key, $prop)
|
||||
|
||||
Retrieve the named property of the named key, return the value, and delete the
|
||||
property from the record. Returns undef if the property or key does not exist.
|
||||
This is normally called from migration code.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_prop_and_delete
|
||||
{
|
||||
my ( $self, $key, $prop ) = @_;
|
||||
my $ret;
|
||||
my $rec = $self->get($key);
|
||||
if ($rec)
|
||||
{
|
||||
$ret = $rec->prop($prop);
|
||||
$rec->delete_prop($prop);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub set_error
|
||||
{
|
||||
my $self = shift;
|
||||
$Error = shift;
|
||||
}
|
||||
|
||||
sub error
|
||||
{
|
||||
return $Error;
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
SME Server Developers <bugs@e-smith.com>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
157
root/usr/share/perl5/vendor_perl/esmith/DB/Record.pm
Normal file
157
root/usr/share/perl5/vendor_perl/esmith/DB/Record.pm
Normal file
@ -0,0 +1,157 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::DB::Record;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use esmith::DB;
|
||||
|
||||
our $VERSION = sprintf '%d.%03d', q$Revision: 1.6 $ =~ /: (\d+).(\d+)/;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::DB::Record - an individual record in an E-Smith database
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<DO NOT USE THIS CLASS DIRECTLY!> use via esmith::DB.
|
||||
|
||||
my $key = $record->key;
|
||||
|
||||
my %properties = $record->props;
|
||||
|
||||
my $value = $record->prop($prop_key);
|
||||
$record->set_prop($prop_key, $prop_val);
|
||||
|
||||
my $value = $record->delete_prop($prop_key);
|
||||
|
||||
$record->merge_props(%more_properties);
|
||||
$record->reset_props(%new_properties);
|
||||
|
||||
$record->delete;
|
||||
|
||||
print $record->show;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This class is a general interface to individual records in esmith::DB
|
||||
databases. It should not be used directly, but rather esmith::DBs
|
||||
should hand you esmith::DB::Record objects.
|
||||
|
||||
Each subclass of esmith::DB will also have to subclass and implement
|
||||
an esmith::DB::Record subclass.
|
||||
|
||||
|
||||
=head2 Virtual Methods
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<key>
|
||||
|
||||
my $key = $record->key;
|
||||
|
||||
Returns the $key for this $record;
|
||||
|
||||
=item B<props>
|
||||
|
||||
my %properties = $record->props;
|
||||
my $num_props = $record->props;
|
||||
|
||||
Returns a hash of all the properties for this $record. In scalar
|
||||
context it will return the number of properties this $record has.
|
||||
|
||||
=item B<prop>
|
||||
|
||||
=item B<set_prop>
|
||||
|
||||
my $value = $record->prop($property);
|
||||
$record->set_prop($property, $value);
|
||||
|
||||
Gets/sets the $value of the $property in this $record.
|
||||
|
||||
set_prop() will die if the database is read-only.
|
||||
|
||||
=item B<delete_prop>
|
||||
|
||||
my $value = $record->delete_prop($property);
|
||||
|
||||
Deletes a $property from the $record, returning the old $value.
|
||||
|
||||
delete_prop() will die if the database is read-only.
|
||||
|
||||
=item B<merge_props>
|
||||
|
||||
$record->merge_props(%properties);
|
||||
|
||||
Adds the %properties to the $records existing properties. Any new
|
||||
keys will be added, any existing keys will be overwritten.
|
||||
|
||||
merge_props() will die if the database is read-only.
|
||||
|
||||
=item B<reset_props>
|
||||
|
||||
$record->reset_props(%properties);
|
||||
|
||||
Replaces the $record's properties with the contents of %properties.
|
||||
Any old properties will be deleted.
|
||||
|
||||
reset_props() will die if the database is read-only.
|
||||
|
||||
=item B<delete>
|
||||
|
||||
$record->delete;
|
||||
|
||||
Deletes the $record from its database.
|
||||
|
||||
delete() will die if the database is read-only.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head2 Concrete methods
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<show>
|
||||
|
||||
my $formatted = $record->show;
|
||||
|
||||
Returns the $record's key and properties in a nice, human readable
|
||||
format suitable for printing.
|
||||
|
||||
=cut
|
||||
|
||||
sub show {
|
||||
my($self) = shift;
|
||||
|
||||
my $out = $self->key."\n";
|
||||
|
||||
my %props = $self->props;
|
||||
|
||||
# Determine our longest key so we know how to format.
|
||||
my $max_len = 0;
|
||||
foreach (keys %props) { $max_len = length if length > $max_len }
|
||||
|
||||
# But don't go too far.
|
||||
$max_len = 40 if $max_len > 40;
|
||||
|
||||
foreach my $prop (sort { $a cmp $b } keys %props) {
|
||||
$out .= sprintf " %${max_len}s = %s\n", $prop, $props{$prop};
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<esmith::DB>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
660
root/usr/share/perl5/vendor_perl/esmith/DB/db.pm
Normal file
660
root/usr/share/perl5/vendor_perl/esmith/DB/db.pm
Normal file
@ -0,0 +1,660 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::DB::db;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp;
|
||||
|
||||
our $VERSION = sprintf '%d.%03d', q$Revision: 1.29 $ =~ /: (\d+).(\d+)/;
|
||||
|
||||
use esmith::db;
|
||||
use esmith::config;
|
||||
use esmith::DB::db::Record;
|
||||
use esmith::DB;
|
||||
our @ISA = qw(esmith::DB);
|
||||
|
||||
=for testing
|
||||
use_ok('esmith::DB::db');
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::DB::db - interface to esmith::db databases
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
I<Works just like an esmith::DB class except where noted>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides an abstracted interface to esmith::db flat-file
|
||||
databases. It will read from and write to esmith::db files and can be
|
||||
safely used right along side esmith::db. This follows the esmith::DB
|
||||
interface and will work as documented there unless otherwise stated.
|
||||
|
||||
You should use this instead of esmith::db, and replace any existing
|
||||
esmith::db code with this.
|
||||
|
||||
I<Note for esmith::db users> the old concept of a 'type' is now simply
|
||||
another property.
|
||||
|
||||
my $type = $record->prop('type');
|
||||
|
||||
replaces db_get_type().
|
||||
|
||||
The $record returned by esmith::DB::db subclass is an esmith::DB::db::Record
|
||||
subclass object. See the esmith::DB::db manpage for details on how it is used.
|
||||
|
||||
=head2 Methods
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<create>
|
||||
|
||||
Puts its error on esmith::DB::db->error
|
||||
|
||||
=begin testing
|
||||
|
||||
$Scratch_Conf = '10e-smith-lib/scratch.conf';
|
||||
unlink $Scratch_Conf;
|
||||
$db = esmith::DB::db->create($Scratch_Conf);
|
||||
END { unlink $Scratch_Conf }
|
||||
|
||||
isa_ok( $db, 'esmith::DB::db', 'create()' );
|
||||
ok( -e $Scratch_Conf, 'created a new config file' );
|
||||
ok(! esmith::DB::db->create($Scratch_Conf),
|
||||
'create() wont walk over an existing config' );
|
||||
like( esmith::DB::db->error, qr/^File exists/, ' right error message' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub create
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
$file = $class->_file_path($file);
|
||||
my $self;
|
||||
|
||||
eval {
|
||||
$self = $class->_init($file);
|
||||
croak "File exists" if -e $file;
|
||||
|
||||
$self->{config} = $self->_get_config($file)
|
||||
|| croak "Can't get the esmith::config object";
|
||||
|
||||
# touch the config file so it gets created immediately
|
||||
open( FILE, ">>$file" )
|
||||
or die "Failed to open $file for appending: $!\n";
|
||||
close FILE;
|
||||
|
||||
# Migrate, and check for errors, propagating them if they happen.
|
||||
unless ( $self->migrate() )
|
||||
{
|
||||
chomp $@;
|
||||
$self->set_error($@);
|
||||
return;
|
||||
}
|
||||
};
|
||||
if ($@)
|
||||
{
|
||||
chomp $@;
|
||||
$self->set_error($@);
|
||||
return;
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
||||
=item B<open>
|
||||
|
||||
=for notes
|
||||
There's currently no way to get the reason why from esmith::config.
|
||||
|
||||
=begin testing
|
||||
|
||||
unlink $Scratch_Conf;
|
||||
ok( !esmith::DB::db->open($Scratch_Conf), 'open() on a non-existent db' );
|
||||
is( esmith::DB::db->error, "File doesn't exist", ' right error' );
|
||||
|
||||
esmith::DB::db->create($Scratch_Conf);
|
||||
$DB = esmith::DB::db->open($Scratch_Conf);
|
||||
isa_ok( $DB, 'esmith::DB::db' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
$file = $class->_file_path($file);
|
||||
my $self = $class->_init($file);
|
||||
|
||||
if ( -e $file && !-w $file )
|
||||
{
|
||||
$self->{ro} = 1;
|
||||
}
|
||||
|
||||
return $self->_open($file) ? $self : undef;
|
||||
}
|
||||
|
||||
=item B<open_local>
|
||||
|
||||
=for notes
|
||||
There's currently no way to get the reason why from esmith::config.
|
||||
|
||||
=begin testing
|
||||
|
||||
unlink $Scratch_Conf;
|
||||
ok( !esmith::DB::db->open_local($Scratch_Conf), 'open() on a non-existent db' );
|
||||
is( esmith::DB::db->error, "File doesn't exist", ' right error' );
|
||||
|
||||
esmith::DB::db->create($Scratch_Conf);
|
||||
$DB = esmith::DB::db->open_local($Scratch_Conf);
|
||||
isa_ok( $DB, 'esmith::DB::db' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open_local
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
$file = $class->_file_path($file);
|
||||
my $self = $class->_init($file);
|
||||
|
||||
if ( -e $file && !-w $file )
|
||||
{
|
||||
$self->{ro} = 1;
|
||||
}
|
||||
|
||||
return $self->_open($file) ? $self : undef;
|
||||
}
|
||||
|
||||
=begin testing
|
||||
|
||||
ok( my $db = esmith::DB::db->open_ro($Scratch_Conf),
|
||||
'open_ro on a non-existent db');
|
||||
eval { $db->new_record('foo', { type => 'bar' }) };
|
||||
like( $@, qr/^This DB is opened read-only/ );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open_ro
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
$file = $class->_file_path($file);
|
||||
my $self = $class->_init($file);
|
||||
|
||||
$self->{ro} = 1;
|
||||
|
||||
return $self->_open($file) ? $self : undef;
|
||||
}
|
||||
|
||||
=begin testing
|
||||
|
||||
ok( my $db = esmith::DB::db->open_ro_local($Scratch_Conf),
|
||||
'open_ro on a non-existent db');
|
||||
eval { $db->new_record('foo', { type => 'bar' }) };
|
||||
like( $@, qr/^This DB is opened read-only/ );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open_ro_local
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
$file = $class->_file_path($file);
|
||||
my $self = $class->_init($file);
|
||||
|
||||
$self->{ro} = 1;
|
||||
|
||||
return $self->_open($file) ? $self : undef;
|
||||
}
|
||||
|
||||
|
||||
sub is_ro
|
||||
{
|
||||
return $_[0]->{ro} ? 1 : 0;
|
||||
}
|
||||
|
||||
sub _open
|
||||
{
|
||||
my ( $self, $file ) = @_;
|
||||
|
||||
eval {
|
||||
|
||||
# This is unfortunately not atomic, but I don't think
|
||||
# that's a big deal.
|
||||
die "File doesn't exist\n" unless -e $file;
|
||||
die "File isn't readable\n" unless -r $file;
|
||||
|
||||
$self->{config} = $self->_get_config($file)
|
||||
|| die "Can't get the esmith::config object";
|
||||
};
|
||||
if ($@)
|
||||
{
|
||||
chomp $@;
|
||||
$self->set_error($@);
|
||||
return;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _get_config
|
||||
{
|
||||
my ( $self, $file ) = @_;
|
||||
|
||||
my %config;
|
||||
tie %config, $self->tie_class, $file;
|
||||
|
||||
return \%config;
|
||||
}
|
||||
|
||||
sub _init
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
|
||||
my $self = bless { file => $file }, $class;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _file_path
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
|
||||
if ($file =~ m:/:)
|
||||
{
|
||||
use File::Basename;
|
||||
warn "Deprecated pathname $file passed to _file_path()\n"
|
||||
if dirname($file) eq "/home/e-smith";
|
||||
return $file;
|
||||
}
|
||||
|
||||
if (-e "/home/e-smith/db/$file")
|
||||
{
|
||||
return "/home/e-smith/db/$file";
|
||||
} elsif (-e "/home/e-smith/$file") {
|
||||
warn "Database found in old location /home/e-smith/$file";
|
||||
return "/home/e-smith/$file";
|
||||
} else {
|
||||
return "/home/e-smith/db/$file";
|
||||
}
|
||||
}
|
||||
|
||||
=item B<as_hash>
|
||||
|
||||
=begin testing
|
||||
|
||||
use esmith::TestUtils qw(scratch_copy);
|
||||
my $scratch = scratch_copy('10e-smith-lib/db_dummy.conf');
|
||||
my %db = esmith::DB::db->as_hash($scratch);
|
||||
|
||||
my %expect = ( Foo => { type => 'Bar' },
|
||||
Night => { type => 'Day' },
|
||||
Squid => { type => 'cephalopod',
|
||||
arms => 10,
|
||||
species => 'Loligo' },
|
||||
Pipe => { type => 'art',
|
||||
pipe => 'this is not a | got that?',},
|
||||
Haiku => { type => 'poem',
|
||||
words =>
|
||||
"Damian Conway\nGod damn! Damian Conway\nDamian Conway",
|
||||
},
|
||||
Octopus => { type => 'cephalopod',
|
||||
arms => 8,
|
||||
species => '',
|
||||
}
|
||||
);
|
||||
|
||||
is_deeply( \%db, \%expect );
|
||||
|
||||
%db = esmith::DB::db->open($scratch)->as_hash;
|
||||
is_deeply( \%db, \%expect );
|
||||
|
||||
=end testing
|
||||
|
||||
=item B<reload>
|
||||
|
||||
=begin testing
|
||||
|
||||
my $db2 = esmith::DB::db->open($Scratch_Conf);
|
||||
my $something = $DB->new_record('something', { type => "wibble" });
|
||||
isa_ok( $something, 'esmith::DB::db::Record', 'new record in 1st DB' );
|
||||
|
||||
ok( !$db2->get('something'), ' 2nd DB still cant see new record' );
|
||||
ok( $db2->reload, ' reload' );
|
||||
ok( $db2->get('something'), ' 2nd DB can see new record' );
|
||||
|
||||
$something->delete;
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub reload
|
||||
{
|
||||
my ($self) = shift;
|
||||
|
||||
$self->_open( $self->file );
|
||||
}
|
||||
|
||||
=item B<file>
|
||||
|
||||
=for testing
|
||||
is( $db->file, $Scratch_Conf, 'file()' );
|
||||
|
||||
=cut
|
||||
|
||||
sub file
|
||||
{
|
||||
my ($self) = shift;
|
||||
return $self->{file};
|
||||
}
|
||||
|
||||
=item B<new_record>
|
||||
|
||||
=begin testing
|
||||
|
||||
my $record = $DB->new_record('Big Brother', { year => 1984,
|
||||
day => 'night',
|
||||
type => 'Govt',
|
||||
});
|
||||
isa_ok( $record, 'esmith::DB::db::Record', 'new_record' );
|
||||
is( $record->key, 'Big Brother', 'key' );
|
||||
is( $record->prop('type'), 'Govt', 'type' );
|
||||
is_deeply( {$record->props}, {year => 1984, day => 'night', type => 'Govt'},
|
||||
'props' );
|
||||
is( $record->prop('year'), 1984, 'prop() get' );
|
||||
is( $record->prop('day'), 'night', 'prop() get again' );
|
||||
|
||||
|
||||
$record = $DB->new_record('No props');
|
||||
isa_ok( $record, 'esmith::DB::db::Record', 'new_record() w/o props' );
|
||||
is( $record->key, 'No props', ' key' );
|
||||
|
||||
my $db2 = esmith::DB::db->open($DB->file);
|
||||
ok( $db2->get('No props'), ' can be gotten' );
|
||||
|
||||
$record->delete;
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub new_record
|
||||
{
|
||||
my ( $self, $key, $props ) = @_;
|
||||
|
||||
croak "This DB is opened read-only" if $self->is_ro;
|
||||
|
||||
if ( defined db_get( $self->{config}, $key ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
my $type = exists $props->{type} ? delete $props->{type} : '';
|
||||
db_set( $self->{config}, $key, $type, $props );
|
||||
$self->tie_class->_writeconf($self->{file}, $self->{config});
|
||||
|
||||
return esmith::DB::db::Record->_construct( $self, $key, $self->{config} );
|
||||
}
|
||||
|
||||
=item B<get>
|
||||
|
||||
=begin testing
|
||||
|
||||
my $rec = $DB->get('Big Brother');
|
||||
isa_ok( $rec, 'esmith::DB::db::Record', 'get' );
|
||||
is( $rec->key, 'Big Brother', ' right key' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub get
|
||||
{
|
||||
my ( $self, $key ) = @_;
|
||||
|
||||
unless ( defined db_get( $self->{config}, $key ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
return esmith::DB::db::Record->_construct( $self, $key, $self->{config} );
|
||||
}
|
||||
|
||||
=item B<get_all>
|
||||
|
||||
=begin testing
|
||||
|
||||
$DB->new_record('Borg', { type => 'Govt', resistance => 'futile' });
|
||||
my @records = $DB->get_all;
|
||||
is( @records, 2, 'get_all' );
|
||||
ok( !(grep { !$_->isa('esmith::DB::db::Record') } @records),
|
||||
' theyre all records' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub get_all
|
||||
{
|
||||
my ($self) = shift;
|
||||
|
||||
return
|
||||
map { esmith::DB::db::Record->_construct( $self, $_, $self->{config} ) }
|
||||
db_get( $self->{config} );
|
||||
}
|
||||
|
||||
=item B<get_all_by_prop>
|
||||
|
||||
=begin testing
|
||||
|
||||
$DB->new_record('Pretz', { type => 'snack', flavor => 'old fashion' });
|
||||
my @records = $DB->get_all_by_prop(type => 'Govt');
|
||||
is( @records, 2, 'get_all_by_prop() type' );
|
||||
ok( !(grep { $_->prop('type') ne 'Govt' } @records),
|
||||
' theyre the right type' );
|
||||
|
||||
$DB->new_record('Pork lips', { type => 'snack', flavor => 'old fashion' });
|
||||
@records = $DB->get_all_by_prop(flavor => 'old fashion');
|
||||
is( @records, 2, 'get_all_by_prop()' );
|
||||
ok( !(grep { $_->prop('flavor') ne 'old fashion' } @records),
|
||||
' they have the right properties' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub tie_class
|
||||
{
|
||||
return 'esmith::config';
|
||||
}
|
||||
|
||||
sub close
|
||||
{
|
||||
}
|
||||
|
||||
=begin deprecated
|
||||
|
||||
=item B<list_by_type>
|
||||
|
||||
Given a type of item to look for in the database (eg "service", "ibay"),
|
||||
returns a list of items which are that type. This is the underlying
|
||||
routine behind esmith::AccountsDB::ibays() and similar methods.
|
||||
|
||||
=end deprecated
|
||||
|
||||
=for testing
|
||||
ok($DB->list_by_type("Govt"), "list_by_type *deprecated*");
|
||||
|
||||
=cut
|
||||
|
||||
sub list_by_type
|
||||
{
|
||||
my ( $self, $type ) = @_;
|
||||
|
||||
return map $_->key, $self->get_all_by_prop( type => $type );
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLE
|
||||
|
||||
The full docs can be found in esmith::DB and esmith::DB::Record, but
|
||||
here's a cheat sheet for esmith::config and esmith::db users.
|
||||
|
||||
=over 4
|
||||
|
||||
=item opening the default config
|
||||
|
||||
use esmith::config
|
||||
my %config;
|
||||
tie %config, 'esmith::config;
|
||||
|
||||
Now:
|
||||
|
||||
use esmith::ConfigDB;
|
||||
my $config = esmith::ConfigDB->open;
|
||||
|
||||
=item opening a specific config database
|
||||
|
||||
my %config;
|
||||
tie %config, 'esmith::config', $config_file;
|
||||
|
||||
Now:
|
||||
|
||||
my $config = esmith::ConfigDB->open($config_file);
|
||||
|
||||
=item creating a new config database
|
||||
|
||||
This one's important. Before you could just tie esmith::config to any file
|
||||
and it would create it for you. Now you have to explicitly create it.
|
||||
|
||||
my %config;
|
||||
tie %config, 'esmith::config', $new_config_file;
|
||||
|
||||
Now:
|
||||
|
||||
my $config = esmith::ConfigDB->create($new_config_file);
|
||||
|
||||
=item checking if a record exists
|
||||
|
||||
print "Yep" if exists $config{foo};
|
||||
|
||||
now:
|
||||
|
||||
print "Yep" if $config->get('foo'); # unless of course, 'foo' is zero
|
||||
|
||||
=item creating a new record
|
||||
|
||||
Previously you could just create records on the fly:
|
||||
|
||||
# single value
|
||||
$config{foo} = 'whatever';
|
||||
|
||||
# with properties
|
||||
db_set(\%config, 'whatever', 'sometype', { with => 'properties' });
|
||||
|
||||
Now you have to explicitly create them:
|
||||
|
||||
# single value
|
||||
my $foo = $config->new_record('foo');
|
||||
$foo->set_value('foo');
|
||||
|
||||
# with properties
|
||||
my %defaults = ( 'type' => 'sometype',
|
||||
'linux' => 'stable',
|
||||
'windows' => 'stable?' );
|
||||
my $foo = $config->new_record('foo', \%defaults);
|
||||
|
||||
Note that 'type' is now just another property.
|
||||
|
||||
Here's a handy "create this if it doesn't already exist" idiom.
|
||||
|
||||
my $rec = $config->get($key) ||
|
||||
$config->new_record($key);
|
||||
|
||||
=item getting a value
|
||||
|
||||
Entries in a database should no longer be thought of as values, but as
|
||||
records.
|
||||
|
||||
my $val = $config{foo};
|
||||
|
||||
Now this only works with entries with single value. Things with
|
||||
multiple properties are dealt with differently.
|
||||
|
||||
my $record = $config->get('foo');
|
||||
my $val = $record->value;
|
||||
|
||||
=item setting a value
|
||||
|
||||
$config{foo} = 'something';
|
||||
|
||||
now
|
||||
|
||||
my $record = $config->get('foo');
|
||||
$record->set_value('something');
|
||||
|
||||
=item getting a property
|
||||
|
||||
my $this = db_get_prop(\%config, 'foo', 'this');
|
||||
|
||||
now:
|
||||
|
||||
my $foo = $config->get('foo');
|
||||
my $this = $foo->prop('this');
|
||||
|
||||
=item getting & setting properties
|
||||
|
||||
my $val = db_get_prop(\%config, 'foo', 'some prop');
|
||||
db_set_prop(\%config, 'foo', 'some prop' => $new_val);
|
||||
|
||||
now:
|
||||
|
||||
my $val = $record->prop('some prop');
|
||||
$record->set_prop('some prop' => $new_val);
|
||||
|
||||
=item get/setting the type
|
||||
|
||||
my $type = db_get_type(\%config, 'foo');
|
||||
db_set_type(\%config, 'foo', $new_type);
|
||||
|
||||
type is now just a property
|
||||
|
||||
my $record = $db->get('foo');
|
||||
my $type = $record->prop('type');
|
||||
$record->set_prop('type', $new_type);
|
||||
|
||||
=item getting all the properties
|
||||
|
||||
my %props = db_get_prop(\%config, 'foo');
|
||||
|
||||
now
|
||||
|
||||
my %props = $record->props;
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
SME Server Developers <bugs@e-smith.com>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<esmith::AccountsDB>, L<esmith::ConfigDB>, L<esmith::DB::db::Record>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
353
root/usr/share/perl5/vendor_perl/esmith/DB/db/Record.pm
Normal file
353
root/usr/share/perl5/vendor_perl/esmith/DB/db/Record.pm
Normal file
@ -0,0 +1,353 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::DB::db::Record;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp;
|
||||
|
||||
use esmith::db;
|
||||
use esmith::DB::db;
|
||||
|
||||
require esmith::DB::Record;
|
||||
our @ISA = qw(esmith::DB::Record);
|
||||
|
||||
|
||||
=begin testing
|
||||
|
||||
use_ok('esmith::DB::db::Record');
|
||||
use_ok('esmith::DB::db');
|
||||
|
||||
use File::Copy;
|
||||
$Scratch_Conf = '10e-smith-lib/scratch.conf';
|
||||
copy('10e-smith-lib/db_dummy.conf', $Scratch_Conf);
|
||||
END { unlink $Scratch_Conf }
|
||||
|
||||
$DB = esmith::DB::db->open($Scratch_Conf);
|
||||
$Squid = $DB->get('Squid');
|
||||
|
||||
=end testing
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::DB::db::Record - Individual records in an esmith::db database
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Unless otherwise noted, works just like esmith::DB::Record.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This class represents entries in esmith::db flat-file database. A
|
||||
single object is a single line.
|
||||
|
||||
This class is not useful by itself but rather they are handed out
|
||||
via esmith::DB::db objects.
|
||||
|
||||
|
||||
=begin protected
|
||||
|
||||
=head2 Protected Methods
|
||||
|
||||
These methods are only allowed to be called by esmith::DB::db classes.
|
||||
|
||||
=item B<_construct>
|
||||
|
||||
my $record = esmith::DB::db::Record->_construct($db, $key, $config);
|
||||
|
||||
Generates a new esmith::DB::db::Record representing data inside the
|
||||
$db (an esmith::DB::db object).
|
||||
|
||||
This does *not* write anything into $db. This is here so a $db can
|
||||
initialize a new Record from existing data.
|
||||
|
||||
=end protected
|
||||
|
||||
=cut
|
||||
|
||||
sub _construct {
|
||||
my($class, $db, $key, $config) = @_;
|
||||
|
||||
die "_construct may only be called by esmith::DB::db"
|
||||
unless caller->isa('esmith::DB::db');
|
||||
|
||||
my $self = {
|
||||
db => $db,
|
||||
config => $config,
|
||||
key => $key
|
||||
};
|
||||
|
||||
return bless $self, $class;
|
||||
}
|
||||
|
||||
=head2 Methods
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<key>
|
||||
|
||||
=for testing
|
||||
is( $Squid->key, 'Squid', 'key()' );
|
||||
|
||||
=cut
|
||||
|
||||
sub key {
|
||||
my($self) = shift;
|
||||
return $self->{key};
|
||||
}
|
||||
|
||||
=item B<props>
|
||||
|
||||
=for testing
|
||||
is_deeply( {$Squid->props}, {arms => 10, species => 'Loligo',
|
||||
type => 'cephalopod'}, 'props()' );
|
||||
|
||||
=cut
|
||||
|
||||
sub props {
|
||||
my($self) = shift;
|
||||
|
||||
my %props = db_get_prop($self->{config}, $self->{key});
|
||||
$props{type} = db_get_type($self->{config}, $self->{key});
|
||||
foreach my $prop (keys %props) {
|
||||
$props{$prop} =~ s{\\\|}{\|}g if $props{$prop};
|
||||
}
|
||||
return wantarray ? %props : keys %props;
|
||||
}
|
||||
|
||||
=item B<prop>
|
||||
|
||||
=item B<set_prop>
|
||||
|
||||
=begin testing
|
||||
|
||||
is( $Squid->prop('arms'), 10, 'prop()' );
|
||||
$Squid->set_prop('arms', 1000);
|
||||
is( $Squid->prop('arms'), 1000, 'set_prop()' );
|
||||
|
||||
is( $Squid->prop('type'), 'cephalopod', 'prop() type get' );
|
||||
$Squid->set_prop('type', 'tree dweller');
|
||||
is( $Squid->prop('type'), 'tree dweller', 'set_prop() type set' );
|
||||
|
||||
$Squid->set_prop('bar', 'foo | bar');
|
||||
is( $Squid->prop('bar'), 'foo bar', 'prop/set_prop with pipes - pipe stripped' );
|
||||
|
||||
{
|
||||
my $warning = '';
|
||||
local $SIG{__WARN__} = sub { $warning = join '', @_ };
|
||||
$Squid->prop('bar', 'foo');
|
||||
like( $warning, qr/^prop\(\) got extra arguments 'foo'. Maybe you ment set_prop\(\)\?/, 'prop()/set_prop() mixup warns' );
|
||||
|
||||
$warning = '';
|
||||
is( $Squid->prop('I_dont_exist'), undef, 'prop() on non-existent prop' );
|
||||
is( $warning, '', ' no warning' );
|
||||
|
||||
$warning = '';
|
||||
$Squid->set_prop('I_dont_exist', undef);
|
||||
is( $Squid->prop('I_dont_exist'), '', 'set_prop() with undef value' );
|
||||
is( $warning, '', ' no warning' );
|
||||
$Squid->delete_prop('I_dont_exist');
|
||||
}
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub prop {
|
||||
my($self, $property) = splice @_, 0, 2;
|
||||
|
||||
warn sprintf "prop() got extra arguments '%s'. Maybe you ment set_prop()?",
|
||||
"@_" if @_;
|
||||
|
||||
my $value;
|
||||
if( $property eq 'type' ) {
|
||||
$value = db_get_type($self->{config}, $self->{key});
|
||||
}
|
||||
else {
|
||||
$value = db_get_prop($self->{config}, $self->{key}, $property);
|
||||
}
|
||||
|
||||
# Unescape escaped pipes. esmith::db can't do this for us.
|
||||
$value =~ s{\\\|}{\|}g if defined $value;
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
sub set_prop {
|
||||
my($self, $property, $value) = @_;
|
||||
|
||||
croak "The DB is open read-only" if $self->{db}->is_ro;
|
||||
|
||||
# Strip pipes - we can't safely escape them while some code
|
||||
# still expects to split on pipe
|
||||
$value =~ s{\|}{}g if defined $value;
|
||||
|
||||
my $ret;
|
||||
if( $property eq 'type' ) {
|
||||
$ret = db_set_type($self->{config}, $self->{key}, $value);
|
||||
}
|
||||
else {
|
||||
$ret = db_set_prop($self->{config}, $self->{key},
|
||||
$property => $value);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
=item B<delete_prop>
|
||||
|
||||
A special case for esmith::DB::db::Record, you're not allowed to
|
||||
delete the 'type' property.
|
||||
|
||||
=for testing
|
||||
is( $Squid->delete_prop('species'), 'Loligo',
|
||||
'delete_prop() returns the old value' );
|
||||
is_deeply( {$Squid->props}, {arms => 1000, bar => 'foo bar',
|
||||
type => 'tree dweller' },
|
||||
' and deletes' );
|
||||
|
||||
=cut
|
||||
|
||||
sub delete_prop {
|
||||
my($self, $property) = @_;
|
||||
|
||||
croak "The DB is open read-only" if $self->{db}->is_ro;
|
||||
|
||||
croak "You're not allowed to delete a type from an esmith::DB::db::Record"
|
||||
if $property eq 'type';
|
||||
|
||||
my $val = $self->prop($property);
|
||||
db_delete_prop($self->{config}, $self->{key}, $property);
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
=item B<merge_props>
|
||||
|
||||
=begin testing
|
||||
|
||||
my $octopus = $DB->get('Octopus');
|
||||
$octopus->merge_props( arms => '8 + 2i', name => 'Fluffy', pipe => 'not |');
|
||||
is_deeply( {$octopus->props}, { arms => '8 + 2i', type => 'cephalopod',
|
||||
species => '', name => 'Fluffy',
|
||||
pipe => 'not ' }, 'merge_props()' );
|
||||
$octopus->merge_props( type => 'foo' );
|
||||
is_deeply( {$octopus->props}, { arms => '8 + 2i', type => 'foo',
|
||||
species => '', name => 'Fluffy',
|
||||
pipe => 'not ' }, ' with type' );
|
||||
|
||||
$octopus->merge_props( { type => 'foo' } );
|
||||
like( $_STDERR_, qr/^merge_props\(\) was accidentally passed a hash ref/m,
|
||||
' anti-hash ref protection');
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub merge_props {
|
||||
my($self, %new_props) = @_;
|
||||
|
||||
croak "The DB is open read-only" if $self->{db}->is_ro;
|
||||
|
||||
if( ref $_[1] ) {
|
||||
carp("merge_props() was accidentally passed a hash ref");
|
||||
}
|
||||
|
||||
my %props = $self->props;
|
||||
my %merged_props = (%props, %new_props);
|
||||
|
||||
# Strip out pipes.
|
||||
foreach my $prop (keys %merged_props) {
|
||||
$merged_props{$prop} =~ s{\|}{}g
|
||||
if defined $merged_props{$prop};
|
||||
}
|
||||
|
||||
my $type = delete $merged_props{type};
|
||||
db_set($self->{config}, $self->{key}, $type, \%merged_props);
|
||||
}
|
||||
|
||||
=item B<reset_props>
|
||||
|
||||
=begin testing
|
||||
|
||||
my $octopus = $DB->get('Octopus');
|
||||
|
||||
eval { $octopus->reset_props( { type => 'foo' } ); };
|
||||
like( $_STDERR_, qr/^reset_props\(\) was accidentally passed a hash ref/m,
|
||||
' anti-hash ref protection');
|
||||
|
||||
$octopus->reset_props( arms => 8, name => 'Rupert', type => 'foo' );
|
||||
is_deeply( {$octopus->props}, { arms => '8', name => 'Rupert',
|
||||
type => 'foo' }, 'reset_props' );
|
||||
|
||||
eval { $octopus->reset_props( arms => '8 + 2i', name => 'Fluffy',
|
||||
pipe => 'not ') };
|
||||
like( $@, qr/^You must have a type property/, ' you must have a type');
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub reset_props {
|
||||
my($self, %new_props) = @_;
|
||||
|
||||
croak "The DB is open read-only" if $self->{db}->is_ro;
|
||||
|
||||
if( ref $_[1] ) {
|
||||
carp("reset_props() was accidentally passed a hash ref");
|
||||
}
|
||||
|
||||
die "You must have a type property" unless $new_props{type};
|
||||
|
||||
# Strip out pipes
|
||||
foreach my $prop (keys %new_props) {
|
||||
$new_props{$prop} =~ s{\|}{}g
|
||||
if defined $new_props{$prop};
|
||||
}
|
||||
|
||||
my $type = delete $new_props{type} || $self->prop('type');
|
||||
db_set($self->{config}, $self->{key}, $type, \%new_props);
|
||||
}
|
||||
|
||||
|
||||
=item B<delete>
|
||||
|
||||
=for testing
|
||||
my $foo = $DB->get('Foo');
|
||||
$foo->delete;
|
||||
ok( !$DB->get('Foo'), 'delete()' );
|
||||
|
||||
=cut
|
||||
|
||||
sub delete {
|
||||
my($self) = shift;
|
||||
|
||||
croak "The DB is open read-only" if $self->{db}->is_ro;
|
||||
db_delete($self->{config}, $self->{key});
|
||||
}
|
||||
|
||||
=item B<show>
|
||||
|
||||
=begin testing
|
||||
|
||||
is( $Squid->show, <<SQUID, 'show' );
|
||||
Squid
|
||||
arms = 1000
|
||||
bar = foo bar
|
||||
type = tree dweller
|
||||
SQUID
|
||||
|
||||
=end testing
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<esmith::DB::db>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
99
root/usr/share/perl5/vendor_perl/esmith/DomainsDB.pm
Normal file
99
root/usr/share/perl5/vendor_perl/esmith/DomainsDB.pm
Normal file
@ -0,0 +1,99 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::DomainsDB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use esmith::DB::db;
|
||||
our @ISA = qw( esmith::DB::db );
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::DomainsDB - interface to esmith domains database
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::DomainsDB;
|
||||
my $c = esmith::DomainsDB->open;
|
||||
|
||||
# everything else works just like esmith::DB::db
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides an abstracted interface to the esmith domain
|
||||
database.
|
||||
|
||||
Unless otherwise noted, esmith::DomainsDB acts like esmith::DB::db.
|
||||
|
||||
=cut
|
||||
|
||||
=head2 open()
|
||||
|
||||
Like esmith::DB->open, but if given no $file it will try to open the
|
||||
file in the ESMITH_DOMAINS_DB environment variable or domains.
|
||||
|
||||
=begin testing
|
||||
|
||||
use_ok("esmith::DomainsDB");
|
||||
|
||||
$C = esmith::DomainsDB->open('10e-smith-lib/domains.conf');
|
||||
isa_ok($C, 'esmith::DomainsDB');
|
||||
is( $C->get("test")->prop('foo'), "bar",
|
||||
"We can get stuff from the db");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open {
|
||||
my ($self, $file) = @_;
|
||||
$file = $file || $ENV{ESMITH_DOMAINS_DB} || "domains";
|
||||
return $self->SUPER::open($file);
|
||||
}
|
||||
|
||||
=head2 open_ro()
|
||||
|
||||
Like esmith::DB->open_ro, but if given no $file it will try to open the
|
||||
file in the ESMITH_DOMAINS_DB environment variable or domains.
|
||||
|
||||
=begin testing
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open_ro {
|
||||
my($class, $file) = @_;
|
||||
$file = $file || $ENV{ESMITH_DOMAINS_DB} || "domains";
|
||||
return $class->SUPER::open_ro($file);
|
||||
}
|
||||
=for testing
|
||||
$C = esmith::DomainsDB->open('10e-smith-lib/domains.conf');
|
||||
isa_ok($C, 'esmith::DomainsDB');
|
||||
can_ok($C, 'domains');
|
||||
can_ok($C, 'get_all_by_prop');
|
||||
is(scalar($C->domains()), 2, "Found 2 domains with domains()");
|
||||
|
||||
=cut
|
||||
|
||||
sub domains {
|
||||
my ($self) = @_;
|
||||
return $self->get_all_by_prop(type => 'domain');
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
SME Server Developers <bugs@e-smith.com>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<esmith::ConfigDB>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
230
root/usr/share/perl5/vendor_perl/esmith/HostsDB.pm
Normal file
230
root/usr/share/perl5/vendor_perl/esmith/HostsDB.pm
Normal file
@ -0,0 +1,230 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::HostsDB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use esmith::DB::db;
|
||||
our @ISA = qw( esmith::DB::db );
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::HostsDB - interface to esmith hostnames/addresses database
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::HostsDB;
|
||||
my $hosts = esmith::HostsDB->open;
|
||||
|
||||
# everything else works just like esmith::DB::db
|
||||
|
||||
# these methods are added
|
||||
my @hosts = $hosts->hosts;
|
||||
my @new_hosts = $hosts->propogate_hosts;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides an abstracted interface to the esmith hosts
|
||||
database.
|
||||
|
||||
Unless otherwise noted, esmith::HostsDB acts like esmith::DB::db.
|
||||
|
||||
=cut
|
||||
|
||||
=head2 Overridden methods
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<open>
|
||||
|
||||
Like esmith::DB->open, but if given no $file it will try to open the
|
||||
file in the ESMITH_HOSTS_DB environment variable or hosts.
|
||||
|
||||
=begin testing
|
||||
|
||||
use_ok("esmith::HostsDB");
|
||||
|
||||
$H = esmith::HostsDB->open('10e-smith-lib/hosts.conf');
|
||||
isa_ok($H, 'esmith::HostsDB');
|
||||
is( $H->get("otherhost.mydomain.xxx")->prop('InternalIP'), "192.168.1.3",
|
||||
"We can get stuff from the db");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open {
|
||||
my($class, $file) = @_;
|
||||
$file = $file || $ENV{ESMITH_HOSTS_DB} || "hosts";
|
||||
return $class->SUPER::open($file);
|
||||
}
|
||||
|
||||
=head2 open_ro()
|
||||
|
||||
Like esmith::DB->open_ro, but if given no $file it will try to open the
|
||||
file in the ESMITH_HOSTS_DB environment variable or hosts.
|
||||
|
||||
=begin testing
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open_ro {
|
||||
my($class, $file) = @_;
|
||||
$file = $file || $ENV{ESMITH_HOSTS_DB} || "hosts";
|
||||
return $class->SUPER::open_ro($file);
|
||||
}
|
||||
=back
|
||||
|
||||
=head2 Additional Methods
|
||||
|
||||
These methods are added be esmith::HostsDB
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<hosts>
|
||||
|
||||
my @hosts = $hosts->hosts;
|
||||
|
||||
Returns a list of all host records in the database.
|
||||
|
||||
=begin testing
|
||||
|
||||
$db = esmith::HostsDB->open('10e-smith-lib/hosts.conf');
|
||||
isa_ok($db, 'esmith::HostsDB');
|
||||
can_ok($db, 'hosts');
|
||||
my @hosts = $db->hosts();
|
||||
isnt( @hosts, 0 );
|
||||
is_deeply(\@hosts, [$db->get_all_by_prop('type' => 'host')]);
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub hosts {
|
||||
my ($self) = @_;
|
||||
return $self->get_all_by_prop('type' => 'host');
|
||||
}
|
||||
|
||||
=item I<propogate_hosts>
|
||||
|
||||
my @new_hosts = $hosts->propogate_hosts($old_name, $new_name);
|
||||
|
||||
When the name of your e-smith machine changes, this will change the
|
||||
name of any hosts which also started with $old_name to use the
|
||||
$new_name.
|
||||
|
||||
Returns a list of the newly tranlsated host records.
|
||||
|
||||
=begin testing
|
||||
|
||||
use esmith::ConfigDB;
|
||||
|
||||
my $hosts_file = '10e-smith-lib/propogate_hosts.conf';
|
||||
END { unlink $hosts_file }
|
||||
|
||||
my $db = esmith::HostsDB->create($hosts_file);
|
||||
|
||||
use esmith::TestUtils qw(scratch_copy);
|
||||
my $c_scratch = scratch_copy('10e-smith-lib/configuration.conf');
|
||||
my $config = esmith::ConfigDB->open($c_scratch);
|
||||
isa_ok($config, 'esmith::ConfigDB');
|
||||
|
||||
my $name = $config->get('SystemName')->value;
|
||||
|
||||
# setup some dummy hosts to propogate.
|
||||
foreach my $host ( "$name.tofu-dog.com", "$name.wibble.org",
|
||||
"wibble.$name.org", "yarrow.hack" )
|
||||
{
|
||||
$db->new_record($host, { type => 'host', HostType => 'Self',
|
||||
ExternalIP => '', InternalIP => ''
|
||||
});
|
||||
}
|
||||
|
||||
$db->reload;
|
||||
my @new_hosts = $db->propogate_hosts($name, "armondo");
|
||||
my @hosts = $db->hosts;
|
||||
is( @hosts, 4 );
|
||||
is_deeply( [sort map { $_->key } @hosts],
|
||||
[sort +('armondo.tofu-dog.com',
|
||||
'armondo.wibble.org',
|
||||
"wibble.$name.org",
|
||||
'yarrow.hack',
|
||||
)]
|
||||
);
|
||||
|
||||
is( @new_hosts, 2 );
|
||||
is_deeply( [sort map { $_->key } @new_hosts],
|
||||
[sort qw(armondo.tofu-dog.com armondo.wibble.org)]
|
||||
);
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub propogate_hosts
|
||||
{
|
||||
my($self, $old_name, $new_name) = @_;
|
||||
|
||||
my @new_hosts = ();
|
||||
foreach my $host ($self->hosts)
|
||||
{
|
||||
my $new_host = $host->key;
|
||||
if( $new_host =~ s/^\Q$old_name.\E/$new_name./ )
|
||||
{
|
||||
push @new_hosts, $self->new_record($new_host,
|
||||
{ $host->props }
|
||||
);
|
||||
$host->delete;
|
||||
}
|
||||
}
|
||||
|
||||
return @new_hosts;
|
||||
}
|
||||
|
||||
|
||||
=head2 $db->get_hosts_by_domain
|
||||
|
||||
Given a domain name (as a string), finds any hosts which match it and
|
||||
return them as a list of record objects.
|
||||
|
||||
=begin testing
|
||||
|
||||
my $h = esmith::HostsDB->open('10e-smith-lib/hosts.conf');
|
||||
my @hosts = $h->get_hosts_by_domain('otherdomain.xxx');
|
||||
is(scalar(@hosts), 2, "Found two hosts in otherdomain.xxx");
|
||||
isa_ok($hosts[0], 'esmith::DB::Record');
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub get_hosts_by_domain {
|
||||
my ($self, $domain) = @_;
|
||||
my @all = $self->get_all();
|
||||
my @return;
|
||||
foreach my $h (@all) {
|
||||
push @return, $h if $h->key() =~ /^[^\.]+\.$domain$/;
|
||||
}
|
||||
return @return;
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
SME Server Developers <bugs@e-smith.com>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<esmith::ConfigDB>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
331
root/usr/share/perl5/vendor_perl/esmith/I18N.pm
Normal file
331
root/usr/share/perl5/vendor_perl/esmith/I18N.pm
Normal file
@ -0,0 +1,331 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::I18N;
|
||||
|
||||
use strict;
|
||||
|
||||
use esmith::ConfigDB;
|
||||
use POSIX qw(setlocale LC_ALL LC_CTYPE);
|
||||
use Locale::gettext;
|
||||
use I18N::AcceptLanguage;
|
||||
use I18N::LangTags qw(is_language_tag locale2language_tag);
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::I18N - Internationalization utilities Mitel Network SME Server
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
This file documents C<esmith::I18N> version B<1.4.0>
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::I18N;
|
||||
|
||||
my $i18n = new esmith::I18N;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides general internationalization and localisation
|
||||
utilities for developers of the Mitel Networks SME Server.
|
||||
|
||||
=begin testing
|
||||
|
||||
use I18N::LangTags qw(is_language_tag locale2language_tag language_tag2locale);
|
||||
use_ok('esmith::I18N');
|
||||
|
||||
=end testing
|
||||
|
||||
=head1 GENERAL UTILITIES
|
||||
|
||||
=cut
|
||||
|
||||
sub new
|
||||
{
|
||||
my $self = shift;
|
||||
my $class = ref($self) || $self;
|
||||
|
||||
my %args = @_;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 availableLocales()
|
||||
|
||||
Returns an array containing the available locales supported by the
|
||||
server.
|
||||
|
||||
=begin testing
|
||||
|
||||
$ENV{ESMITH_CONFIG_DB}="10e-smith-lib/sysconfig-en_US.conf";
|
||||
$ENV{ESMITH_I18N_USRSHARELOCALE}="10e-smith-lib/usr/share/locale";
|
||||
|
||||
my $i18n = new esmith::I18N;
|
||||
my @locales = grep !/CVS/, sort $i18n->availableLocales;
|
||||
|
||||
# NOTE: de is not a valid locale for the test - no server-console file
|
||||
is_deeply(\@locales, [('en_US', 'fr_CA', 'wx_YZ')], "Locales match" );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub availableLocales()
|
||||
{
|
||||
my ($self) = shift;
|
||||
|
||||
my $localedir = $ENV{ESMITH_I18N_USRSHARELOCALE} || '/usr/share/locale';
|
||||
|
||||
return () unless opendir LOCALE, $localedir;
|
||||
|
||||
my @locales;
|
||||
|
||||
foreach my $locale ( grep(!/\./, readdir LOCALE) )
|
||||
{
|
||||
push @locales, $locale if
|
||||
(-f "$localedir/$locale/LC_MESSAGES/server-console.mo" or
|
||||
-f "$localedir/$locale/LC_MESSAGES/server-console.po");
|
||||
}
|
||||
|
||||
closedir LOCALE;
|
||||
return @locales;
|
||||
}
|
||||
|
||||
=head2 fallbackLocale()
|
||||
|
||||
Return system fallback locale
|
||||
|
||||
=cut
|
||||
|
||||
sub fallbackLocale()
|
||||
{
|
||||
return "en_US.utf8";
|
||||
}
|
||||
|
||||
=head2 preferredLocale()
|
||||
|
||||
Retrieves the preferred locale for this server.
|
||||
|
||||
=begin testing
|
||||
|
||||
$ENV{ESMITH_CONFIG_DB}="10e-smith-lib/sysconfig-en_US.conf";
|
||||
|
||||
my $i18n = new esmith::I18N;
|
||||
is($i18n->preferredLocale, 'en_US', "en_US.conf: Preferred locale is en_US");
|
||||
|
||||
$ENV{ESMITH_CONFIG_DB}="10e-smith-lib/sysconfig-fr_CA.conf";
|
||||
|
||||
$i18n = new esmith::I18N;
|
||||
is($i18n->preferredLocale, 'fr_CA', "fr_CA.conf: Preferred locale is fr_CA");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub preferredLocale()
|
||||
{
|
||||
my ($self) = shift;
|
||||
|
||||
my $db = esmith::ConfigDB->open_ro || return $self->fallbackLocale;
|
||||
|
||||
my ($locale, @rest) = $db->getLocale();
|
||||
|
||||
return $locale || $self->fallbackLocale;
|
||||
}
|
||||
|
||||
=head2 setLocale()
|
||||
|
||||
Configure the locale for gettext() for the supplied text domain.
|
||||
|
||||
The method takes two arguments, the text domain, and an optional argument
|
||||
which can be either a language tag or a locale.
|
||||
|
||||
=cut
|
||||
|
||||
sub setLocale()
|
||||
{
|
||||
my ($self, $text_domain, $opt) = @_;
|
||||
my $locale;
|
||||
|
||||
$locale = $self->langtag2locale($opt) if ($opt);
|
||||
$locale ||= $self->preferredLocale;
|
||||
$locale =~ s{(?:\..*)?$}{.utf8};
|
||||
|
||||
$ENV{'LANGUAGE'} = $locale;
|
||||
$ENV{'LANG'} = $ENV{'LANGUAGE'};
|
||||
|
||||
setlocale(LC_MESSAGES, $locale);
|
||||
setlocale(LC_MESSAGES, $locale);
|
||||
setlocale(LC_ALL, $locale);
|
||||
setlocale(LC_ALL, $locale);
|
||||
|
||||
bindtextdomain ($text_domain, "/usr/share/locale");
|
||||
textdomain ($text_domain);
|
||||
}
|
||||
|
||||
|
||||
=head2 langtag2locale
|
||||
|
||||
Even though the directories appear in /usr/share/locale, they also need
|
||||
to appear in /usr/lib/locale to actually be treated as locales. Read the
|
||||
Perl locale docs for details of how horrid this is. For now, we're just
|
||||
going to force things for supported languages.
|
||||
|
||||
=begin testing
|
||||
my $i18n = new esmith::I18N;
|
||||
|
||||
is($i18n->langtag2locale("en"), "en_US", "en langtag is en_US locale");
|
||||
is($i18n->langtag2locale("en-us"), "en_US", "en-us langtag is en_US locale");
|
||||
is($i18n->langtag2locale("en-au"), "en_AU", "en-au langtag is en_AU locale");
|
||||
|
||||
is($i18n->langtag2locale("es"), "es_ES", "es langtag is es_ES locale");
|
||||
is($i18n->langtag2locale("es-es"), "es_ES", "es-es langtag is es_ES locale");
|
||||
is($i18n->langtag2locale("es-ar"), "es_AR", "es-ar langtag is es_AR locale");
|
||||
|
||||
is($i18n->langtag2locale("fr"), "fr_CA", "fr langtag is fr_CA locale");
|
||||
is($i18n->langtag2locale("fr-ca"), "fr_CA", "fr-ca langtag is fr_CA locale");
|
||||
is($i18n->langtag2locale("fr-fr"), "fr_FR", "fr-fr langtag is fr_FR locale");
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub langtag2locale
|
||||
{
|
||||
my ($self, $opt) = @_;
|
||||
|
||||
my $locale;
|
||||
|
||||
if (is_language_tag($opt))
|
||||
{
|
||||
$locale = _language_tag2locale($opt) || $self->fallbackLocale;
|
||||
|
||||
unless (-d "/usr/lib/locale/$locale")
|
||||
{
|
||||
$locale = "da_DK" if ($opt =~ /^da(-.*)?/);
|
||||
$locale = "de_DE" if ($opt =~ /^de(-.*)?/);
|
||||
$locale = "el_GR" if ($opt =~ /^el(-.*)?/);
|
||||
$locale = "en_US" if ($opt =~ /^en(-.*)?/);
|
||||
$locale = "es_ES" if ($opt =~ /^es(-.*)?/);
|
||||
$locale = "fr_CA" if ($opt =~ /^fr(-.*)?/);
|
||||
$locale = "hu_HU" if ($opt =~ /^hu(-.*)?/);
|
||||
$locale = "id_ID" if ($opt =~ /^id(-.*)?/);
|
||||
$locale = "it_IT" if ($opt =~ /^it(-.*)?/);
|
||||
$locale = "nl_NL" if ($opt =~ /^nl(-.*)?/);
|
||||
$locale = "pt_BR" if ($opt =~ /^pt(-.*)?/);
|
||||
$locale = "sl_SL" if ($opt =~ /^sl(-.*)?/);
|
||||
$locale = "sv_SE" if ($opt =~ /^sv(-.*)?/);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$locale = $opt;
|
||||
}
|
||||
|
||||
return $locale;
|
||||
}
|
||||
|
||||
sub _language_tag2locale
|
||||
{
|
||||
my $langtags = $_[0];
|
||||
my @locales;
|
||||
foreach my $maybe (split /[\n\r\t ,]+/, $langtags)
|
||||
{
|
||||
push @locales,
|
||||
lc($1) . ( $2 ? ('_' . uc($2)) : '' )
|
||||
if $maybe =~ m/^([a-zA-Z]{2})(?:-([a-zA-Z]{2}))?$/s;
|
||||
}
|
||||
return $locales[0] unless wantarray; # might be undef!
|
||||
return @locales; # might be empty!
|
||||
}
|
||||
|
||||
=head2 availableLanguages()
|
||||
|
||||
Returns an array containing the available languages supported by the
|
||||
server.
|
||||
|
||||
=begin testing
|
||||
|
||||
$ENV{ESMITH_CONFIG_DB}="10e-smith-lib/sysconfig-en_US.conf";
|
||||
$ENV{ESMITH_I18N_ESMITHLOCALEDIR}="10e-smith-lib/etc/e-smith/locale";
|
||||
|
||||
my $i18n = new esmith::I18N;
|
||||
my @locales = grep !/CVS/, sort $i18n->availableLanguages;
|
||||
|
||||
is_deeply(\@locales, [('en-us', 'es', 'fr-ca', 'jk', 'wx-yz')], "Locales match" );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub availableLanguages
|
||||
{
|
||||
my ($self) = shift;
|
||||
|
||||
my $localedir = $ENV{ESMITH_I18N_ESMITHLOCALEDIR} || '/etc/e-smith/locale';
|
||||
|
||||
return () unless opendir LOCALE, $localedir;
|
||||
|
||||
my @locales = grep(!/\./, readdir LOCALE);
|
||||
closedir LOCALE;
|
||||
return @locales;
|
||||
}
|
||||
|
||||
=head2 fallbackLanguage()
|
||||
|
||||
Return system fallback language
|
||||
|
||||
=cut
|
||||
|
||||
sub fallbackLanguage()
|
||||
{
|
||||
return "en-us";
|
||||
}
|
||||
|
||||
=head2 preferredLanguage()
|
||||
|
||||
Returns the preferred language, determined by the HTTP_ACCEPT_LANGUAGE
|
||||
setting from the browser and the available languages on the server.
|
||||
|
||||
=begin testing
|
||||
|
||||
my $i18n = new esmith::I18N;
|
||||
delete $ENV{HTTP_ACCEPT_LANGUAGE};
|
||||
|
||||
is( $i18n->preferredLanguage(), "en-us", "Preferred language is en-us");
|
||||
is( $i18n->preferredLanguage("en-us"), "en-us", "Preferred language is en-us");
|
||||
is( $i18n->preferredLanguage("en-us, fr-ca"), "en-us", "Preferred language is en-us");
|
||||
is( $i18n->preferredLanguage("fr-ca, en-us"), "fr-ca", "Preferred language is fr-ca");
|
||||
|
||||
$ENV{HTTP_ACCEPT_LANGUAGE} = "de, es";
|
||||
is( $i18n->preferredLanguage(), "es", "Preferred language is es");
|
||||
|
||||
$ENV{HTTP_ACCEPT_LANGUAGE} = "de, fr-ca, es, en-us";
|
||||
is( $i18n->preferredLanguage(), "fr-ca", "Preferred language is fr-ca");
|
||||
|
||||
$ENV{HTTP_ACCEPT_LANGUAGE} = "de, es, fr-ca, en-us";
|
||||
is( $i18n->preferredLanguage(), "es", "Preferred language is es");
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub preferredLanguage
|
||||
{
|
||||
my ($self, $browser_languages) = @_;
|
||||
|
||||
$browser_languages ||= $ENV{HTTP_ACCEPT_LANGUAGE}
|
||||
||= $self->fallbackLanguage;
|
||||
|
||||
my @availableLanguages = $self->availableLanguages;
|
||||
|
||||
my $acceptor = I18N::AcceptLanguage->new();
|
||||
my $language = $acceptor->accepts($browser_languages, \@availableLanguages)
|
||||
|| $self->fallbackLanguage;
|
||||
}
|
||||
|
||||
1;
|
77
root/usr/share/perl5/vendor_perl/esmith/Logger.pm
Normal file
77
root/usr/share/perl5/vendor_perl/esmith/Logger.pm
Normal file
@ -0,0 +1,77 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::Logger;
|
||||
|
||||
use Sys::Syslog qw(:DEFAULT setlogsock);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::Logger - A filehandle abstraction around Syslog.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::Logger;
|
||||
|
||||
tie *FH, 'esmith::Logger';
|
||||
print FH "log message";
|
||||
close FH;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = sprintf '%d.%03d', q$Revision: 1.100 $ =~ /: (\d+).(\d+)/;
|
||||
|
||||
sub TIEHANDLE
|
||||
{
|
||||
my $class = ref($_[0]) || $_[0]; shift;
|
||||
my $self;
|
||||
my $title = shift || 'e-smith';
|
||||
setlogsock 'unix';
|
||||
openlog($title, 'pid', 'local1');
|
||||
return bless \$self, $class;
|
||||
}
|
||||
|
||||
sub PRINT
|
||||
{
|
||||
my $self = shift;
|
||||
syslog('info', "%s", "@_");
|
||||
}
|
||||
|
||||
sub PRINTF
|
||||
{
|
||||
my $self = shift;
|
||||
my $fmt = shift;
|
||||
syslog('info', $fmt, @_);
|
||||
}
|
||||
|
||||
sub WRITE
|
||||
{
|
||||
die "Sorry, WRITE unimplemented.\n";
|
||||
}
|
||||
|
||||
sub READ
|
||||
{
|
||||
die "Can't read from logger.\n";
|
||||
}
|
||||
|
||||
sub READLINE
|
||||
{
|
||||
die "Can't read from logger.\n";
|
||||
}
|
||||
|
||||
sub GETC
|
||||
{
|
||||
die "Can't read from logger.\n";
|
||||
}
|
||||
|
||||
sub CLOSE
|
||||
{
|
||||
closelog();
|
||||
}
|
||||
|
||||
1;
|
16
root/usr/share/perl5/vendor_perl/esmith/NavigationDB.pm
Normal file
16
root/usr/share/perl5/vendor_perl/esmith/NavigationDB.pm
Normal file
@ -0,0 +1,16 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2008 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::NavigationDB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use esmith::ConfigDB::UTF8;
|
||||
our @ISA = qw( esmith::ConfigDB::UTF8 );
|
||||
|
||||
1;
|
||||
|
157
root/usr/share/perl5/vendor_perl/esmith/NetworksDB.pm
Normal file
157
root/usr/share/perl5/vendor_perl/esmith/NetworksDB.pm
Normal file
@ -0,0 +1,157 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::NetworksDB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use esmith::DB::db;
|
||||
our @ISA = qw( esmith::DB::db );
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::NetworksDB - interface to esmith networks database
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::NetworksDB;
|
||||
my $c = esmith::NetworksDB->open;
|
||||
|
||||
# everything else works just like esmith::DB::db
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides an abstracted interface to the esmith master
|
||||
configuration database.
|
||||
|
||||
Unless otherwise noted, esmith::NetworksDB acts like esmith::DB::db.
|
||||
|
||||
=cut
|
||||
|
||||
=head2 open()
|
||||
|
||||
Like esmith::DB->open, but if given no $file it will try to open the
|
||||
file in the ESMITH_NETWORKS_DB environment variable or networks.
|
||||
|
||||
=begin testing
|
||||
|
||||
use_ok("esmith::NetworksDB");
|
||||
|
||||
$C = esmith::NetworksDB->open('10e-smith-lib/networks.conf');
|
||||
isa_ok($C, 'esmith::NetworksDB');
|
||||
is( $C->get("10.0.0.0")->prop('Mask'), "255.255.255.0",
|
||||
"We can get stuff from the db");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
$file = $file || $ENV{ESMITH_NETWORKS_DB} || "networks";
|
||||
return $class->SUPER::open($file);
|
||||
}
|
||||
|
||||
=head2 open_ro()
|
||||
|
||||
Like esmith::DB->open_ro, but if given no $file it will try to open the
|
||||
file in the ESMITH_NETWORKS_DB environment variable or networks.
|
||||
|
||||
=begin testing
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub open_ro
|
||||
{
|
||||
my ( $class, $file ) = @_;
|
||||
$file = $file || $ENV{ESMITH_NETWORKS_DB} || "networks";
|
||||
return $class->SUPER::open_ro($file);
|
||||
}
|
||||
|
||||
=head2 networks
|
||||
|
||||
Return a list of all objects of type "network".
|
||||
|
||||
=cut
|
||||
|
||||
sub networks {
|
||||
my ($self) = @_;
|
||||
return $self->get_all_by_prop(type => 'network');
|
||||
}
|
||||
|
||||
=head2 local_access_spec ([$access])
|
||||
|
||||
Compute the network/netmask entries which are to treated as local access.
|
||||
|
||||
There is also an optional access parameter which can further restrict
|
||||
the values returned. If C<access> is C<localhost>, this routine will only
|
||||
return a single value, equating to access from localhost only.
|
||||
|
||||
If called in scalar context, the returned string is suitable for
|
||||
use in /etc/hosts.allow, smb.conf and httpd.conf, for example:
|
||||
|
||||
127.0.0.1 192.168.1.1/255.255.255.0
|
||||
|
||||
Note: The elements are space separated, which is suitable for use in
|
||||
hosts.allow, smb.conf and httpd.conf. httpd.conf does not permit
|
||||
comma separated lists in C<allow from> directives. Each element is either
|
||||
an IP address, or a network/netmask string.
|
||||
|
||||
If called in list context, returns the array of addresses and network/netmask
|
||||
strings. It's trivial, of course, to convert an array to a comma separated
|
||||
list :-)
|
||||
|
||||
=cut
|
||||
|
||||
sub local_access_spec
|
||||
{
|
||||
my $self = shift;
|
||||
my $access = shift || "private";
|
||||
|
||||
my @localAccess = ("127.0.0.1");
|
||||
|
||||
if ( $access eq "localhost" )
|
||||
{
|
||||
# Nothing more to do
|
||||
}
|
||||
elsif ( $access eq "private" )
|
||||
{
|
||||
foreach my $network ( $self->networks )
|
||||
{
|
||||
my $element = $network->key;
|
||||
my $mask = $network->prop('Mask');
|
||||
$element .= "/$mask" unless ($mask eq "255.255.255.255");
|
||||
push @localAccess, $element;
|
||||
}
|
||||
}
|
||||
elsif ( $access eq "public" )
|
||||
{
|
||||
@localAccess = ("ALL");
|
||||
}
|
||||
else
|
||||
{
|
||||
warn "local_access_spec: unknown access value $access\n";
|
||||
}
|
||||
return wantarray ? @localAccess : "@localAccess";
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
SME Server Developers <bugs@e-smith.com>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<esmith::DB::db>
|
||||
|
||||
L<esmith::DB::Record>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
480
root/usr/share/perl5/vendor_perl/esmith/cgi.pm
Normal file
480
root/usr/share/perl5/vendor_perl/esmith/cgi.pm
Normal file
@ -0,0 +1,480 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::cgi;
|
||||
|
||||
use strict;
|
||||
use esmith::config;
|
||||
use esmith::db;
|
||||
use esmith::util;
|
||||
|
||||
BEGIN
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::cgi - Useful CGI routines for e-smith server and gateway
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
This file documents C<esmith::cgi> version B<1.4.0>
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::cgi;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module contains a collection of useful routines for working with
|
||||
the e-smith manager's CGI interface.
|
||||
=head1 WEB PAGE HEADER GENERATION ROUTINES
|
||||
|
||||
=head2 genHeaderNonCacheable($q, $confref, $title)
|
||||
|
||||
=cut
|
||||
|
||||
sub genHeaderNonCacheable
|
||||
{
|
||||
my ($q, $confref, $title) = @_;
|
||||
genHeader ($q, $confref, $title, '-20y', 1);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genHeaderCacheableNoPasswordCheck($q, $confref, $title)
|
||||
|
||||
=cut
|
||||
|
||||
sub genHeaderCacheableNoPasswordCheck
|
||||
{
|
||||
my ($q, $confref, $title) = @_;
|
||||
genHeader ($q, $confref, $title, '+1d', 0);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genHeaderCacheableNoPasswordCheck($q, $confref, $title)
|
||||
|
||||
=cut
|
||||
|
||||
sub genHeaderNonCacheableNoPasswordCheck
|
||||
{
|
||||
my ($q, $confref, $title) = @_;
|
||||
genHeader ($q, $confref, $title, '-20y', 0);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genHeader($q, $confref, $title, $expiry, $checkpassword)
|
||||
|
||||
=cut
|
||||
|
||||
sub genHeader
|
||||
{
|
||||
my ($q, $confref, $title, $expiry, $checkpassword) = @_;
|
||||
|
||||
print $q->header (-EXPIRES => $expiry, charset => 'UTF-8');
|
||||
|
||||
genHeaderStartHTML ($q, "panel_main");
|
||||
|
||||
print $q->h1 ($title);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genNavigationHeader($q)
|
||||
|
||||
=cut
|
||||
|
||||
sub genNavigationHeader
|
||||
{
|
||||
my ($q, $num) = @_;
|
||||
|
||||
print $q->header (-EXPIRES => '-20y', charset => 'UTF-8');
|
||||
|
||||
genHeaderStartHTML ($q, "panel_nav", $num);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genNoframesHeader($q)
|
||||
|
||||
=cut
|
||||
|
||||
sub genNoframesHeader
|
||||
{
|
||||
my ($q) = @_;
|
||||
|
||||
print $q->header (-EXPIRES => '-20y', charset => 'UTF-8');
|
||||
genHeaderStartHTML ($q, "panel_main");
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genHeaderStartHTML($q)
|
||||
|
||||
=cut
|
||||
|
||||
sub genHeaderStartHTML
|
||||
{
|
||||
my ($q, $page_type, $num) = @_;
|
||||
my ($cssFile);
|
||||
my ($bodyStyle);
|
||||
my ($script) = "//This swaps the class of the selected item.\n"
|
||||
."function swapClass(){\n"
|
||||
."var i,x,tB,j=0,tA=new Array(),arg=swapClass.arguments;\n"
|
||||
."if(document.getElementsByTagName){for(i=4;i<arg.length;i++){tB=document.getElementsByTagName(arg[i]);\n"
|
||||
."for(x=0;x<tB.length;x++){tA[j]=tB[x];j++;}}for(i=0;i<tA.length;i++){\n"
|
||||
."if(tA[i].className){if(tA[i].id==arg[1]){if(arg[0]==1){\n"
|
||||
."tA[i].className=(tA[i].className==arg[3])?arg[2]:arg[3];}else{tA[i].className=arg[2];}\n"
|
||||
."}else if(arg[0]==1 && arg[1]=='none'){if(tA[i].className==arg[2] || tA[i].className==arg[3]){\n"
|
||||
."tA[i].className=(tA[i].className==arg[3])?arg[2]:arg[3];}\n"
|
||||
."}else if(tA[i].className==arg[2]){tA[i].className=arg[3];}}}}}\n";
|
||||
|
||||
if ($page_type eq "panel_nav") {
|
||||
$cssFile = "sme_menu.css";
|
||||
$bodyStyle = "menu"
|
||||
}
|
||||
elsif ($page_type eq "panel_main") {
|
||||
$cssFile = "sme_main.css";
|
||||
$bodyStyle = "main"
|
||||
}
|
||||
# the -CLASS thing gets sent as a body class, not in the header
|
||||
print $q->start_html (-TITLE => 'SME Server server manager',
|
||||
-META => {'copyright' => 'Copyright 1999-2006 Mitel Networks Corporation, Copyright (C) ____COPYYEARS____ Koozali Foundation, Inc.'},
|
||||
-SCRIPT => "$script",
|
||||
-CLASS => "$bodyStyle",
|
||||
-STYLE => {
|
||||
-code => '@import url("/server-common/css/'.$cssFile.'");',
|
||||
-src => '/server-common/css/sme_core.css'
|
||||
});
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head1 WEB PAGE FOOTER GENERATION ROUTINES
|
||||
|
||||
=head2 genFooter($q)
|
||||
|
||||
=cut
|
||||
|
||||
sub genFooter
|
||||
{
|
||||
my ($q) = @_;
|
||||
|
||||
if ($q->isa('CGI::FormMagick'))
|
||||
{
|
||||
print $q->parse_template("/etc/e-smith/web/common/foot.tmpl");
|
||||
return;
|
||||
}
|
||||
|
||||
my $release = esmith::util::determineRelease();
|
||||
|
||||
print $q->p
|
||||
($q->hr ({-CLASS => "sme-copyrightbar"}),
|
||||
$q->div ({-CLASS => "sme-copyright"},
|
||||
"SME Server server ${release}<BR>" .
|
||||
"Copyright 1999-2006 Mitel Networks Corporation, Copyright (C) ____COPYYEARS____ Koozali Foundation, Inc..<BR>" .
|
||||
"All rights reserved.")
|
||||
);
|
||||
|
||||
print '</DIV>';
|
||||
print $q->end_html;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genFooterNoCopyright($q)
|
||||
|
||||
=cut
|
||||
|
||||
sub genFooterNoCopyright
|
||||
{
|
||||
my ($q) = @_;
|
||||
print $q->p ($q->hr);
|
||||
print $q->end_html;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genNavigationFooter($q)
|
||||
|
||||
=cut
|
||||
|
||||
sub genNavigationFooter
|
||||
{
|
||||
my ($q) = @_;
|
||||
print $q->end_html;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genNoframesFooter($q)
|
||||
|
||||
=cut
|
||||
|
||||
sub genNoframesFooter
|
||||
{
|
||||
my ($q) = @_;
|
||||
print $q->end_html;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head1 FONT ROUTINES
|
||||
|
||||
=head2 curFont()
|
||||
|
||||
Returns the preferred font faces eg. "Verdana, Arial, Helvetica, sans-serif".
|
||||
This should be done by CSS now, so if you're calling this, you shouldn't be.
|
||||
|
||||
=cut
|
||||
|
||||
sub curFont
|
||||
{
|
||||
return "Verdana, Arial, Helvetica, sans-serif";
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head1 TABLE GENERATION ROUTINES
|
||||
|
||||
=head2 genCell($q, $text)
|
||||
|
||||
=cut
|
||||
|
||||
sub genCell
|
||||
{
|
||||
my ($q, $text, $class) = @_;
|
||||
|
||||
if ($text =~ /^\s*$/){$text = " "}
|
||||
if ($class) { return $q->td({-class => "$class"}, $text),"\n";}
|
||||
else { return $q->td ($text),"\n";}
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genDoubleCell($q, $text);
|
||||
|
||||
Generates a cell which spans two columns, containing the text specified.
|
||||
|
||||
=cut
|
||||
|
||||
sub genDoubleCell
|
||||
{
|
||||
my ($q, $text) = @_;
|
||||
if ($text =~ /^\s*$/){ $text = " " }
|
||||
return $q->td ({colspan => 2}, $text),"\n";
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genSmallCell($q, $text, $type, $colspan)
|
||||
|
||||
Generates a cell with "small" text (font size is 80%).
|
||||
"$type" can be one of:
|
||||
"normal" : creates <td class="sme-border"> cell
|
||||
"header" : creates <th class="sme-border"> cell
|
||||
|
||||
=cut
|
||||
|
||||
sub genSmallCell
|
||||
{
|
||||
my ($q, $text, $type, $colspan) = @_;
|
||||
$text = '' unless defined $text;
|
||||
$type ||= 'normal';
|
||||
$colspan ||= 1;
|
||||
if ($text =~ /^\s*$/){ $text = " " }
|
||||
if ("$type" eq "header") {
|
||||
return $q->th ({class=>"sme-border", colspan=>$colspan}, $text)."\n";
|
||||
} else {
|
||||
return $q->td ({class=>"sme-border", colspan=>$colspan}, $text)."\n";
|
||||
}
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genSmallCellCentered($q, $text)
|
||||
|
||||
Generates a cell with "small" text (font size is 80%), centered.
|
||||
creates <td class="sme-border-center"> cell
|
||||
|
||||
=cut
|
||||
|
||||
sub genSmallCellCentered
|
||||
{
|
||||
my ($q, $text) = @_;
|
||||
if ($text =~ /^\s*$/){ $text = " " }
|
||||
return $q->td ({class => "sme-border-center"}, $text)."\n";
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genSmallCellRightJustified($q, $text)
|
||||
|
||||
=head2 genSmallCellCentered($q, $text)
|
||||
|
||||
Generates a cell with "small" text (font size is 80%), right justified.
|
||||
creates <td class="sme-border-right"> cell
|
||||
|
||||
=cut
|
||||
|
||||
sub genSmallCellRightJustified
|
||||
{
|
||||
my ($q, $text) = @_;
|
||||
if ($text =~ /^\s*$/){ $text = " " }
|
||||
return $q->td ({class => "sme-border-right"}, $text)."\n";
|
||||
}
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genSmallRedCell($q, $text)
|
||||
|
||||
Generates a cell with "small" text (font size is 80%), left justified.
|
||||
creates <td class="sme-border-warning"> cell
|
||||
|
||||
=cut
|
||||
|
||||
sub genSmallRedCell
|
||||
{
|
||||
my ($q, $text) = @_;
|
||||
if ($text =~ /^\s*$/){ $text = " " }
|
||||
return $q->td ({class => "sme-border-warning"}, $text)."\n";
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genTextRow($q, $text)
|
||||
|
||||
Returns a table row containing a two-column cell containing $text.
|
||||
|
||||
=cut
|
||||
|
||||
sub genTextRow
|
||||
{
|
||||
my ($q, $text) = @_;
|
||||
if ($text =~ /^\s*$/){ $text = " " }
|
||||
return "\n",$q->Tr ($q->td ({colspan => 2}, $text)),"\n";
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genButtonRow($q, $button)
|
||||
|
||||
Returns a table row containing an empty first cell and a second cell
|
||||
containing a button with the value $button.
|
||||
|
||||
=cut
|
||||
|
||||
sub genButtonRow
|
||||
{
|
||||
my ($q, $button) = @_;
|
||||
|
||||
# return $q->Tr ($q->td ({-class => "sme-submitbutton", -colspan => "2"},$q->b ($button))),"\n";
|
||||
# return $q->Tr ($q->td (' '),
|
||||
# $q->td ({-class => "sme-submitbutton"},$q->b ($button))),"\n";
|
||||
return $q->Tr ({-class => "sme-layout"}, $q->th ({-class => "sme-layout", colspan => "2"},$q->b ($button))),"\n";
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genNameValueRow($q, $fieldlabel, $fieldname, $fieldvalue)
|
||||
|
||||
Returns a table row with two cells. The first has the text
|
||||
"$fieldlabel:" in it, and the second has a text field with the default
|
||||
value $fieldvalue and the name $fieldname.
|
||||
|
||||
=cut
|
||||
|
||||
sub genNameValueRow
|
||||
{
|
||||
my ($q, $fieldlabel, $fieldname, $fieldvalue) = @_;
|
||||
|
||||
return $q->Tr (
|
||||
$q->td ({-class => "sme-noborders-label"},
|
||||
"$fieldlabel:"),"\n",
|
||||
$q->td ({-class => "sme-noborders-content"},
|
||||
$q->textfield (
|
||||
-name => $fieldname,
|
||||
-override => 1,
|
||||
-default => $fieldvalue,
|
||||
-size => 32))),"\n";
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
sub genWidgetRow($q, $fieldlabel, $popup)
|
||||
|
||||
=cut
|
||||
|
||||
# used only by backup panel as far as I can see
|
||||
sub genWidgetRow
|
||||
{
|
||||
my ($q, $fieldlabel, $popup) = @_;
|
||||
|
||||
return $q->Tr ($q->td ("$fieldlabel:"),
|
||||
$q->td ($popup));
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head1 STATUS AND ERROR REPORT GENERATION ROUTINES
|
||||
|
||||
=head2 genResult($q, $msg)
|
||||
|
||||
Generates a "status report" page, including the footer
|
||||
|
||||
=cut
|
||||
|
||||
sub genResult
|
||||
{
|
||||
my ($q, $msg) = @_;
|
||||
|
||||
print $q->p ($msg);
|
||||
genFooter ($q);
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=head2 genStateError($q, $confref)
|
||||
|
||||
Subroutine to generate "unknown state" error message.
|
||||
|
||||
=cut
|
||||
|
||||
sub genStateError
|
||||
{
|
||||
my ($q, $confref) = @_;
|
||||
|
||||
genHeaderNonCacheable ($q, $confref, "Internal error");
|
||||
genResult ($q, "Internal error! Unknown state: " . $q->param ("state") . ".");
|
||||
}
|
||||
|
||||
END
|
||||
{
|
||||
}
|
||||
|
||||
#------------------------------------------------------------
|
||||
# return "1" to make the import process return success
|
||||
#------------------------------------------------------------
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Mitel Networks Corporation
|
||||
|
||||
For more information, see http://e-smith.org/
|
||||
|
||||
=cut
|
||||
|
640
root/usr/share/perl5/vendor_perl/esmith/config.pm
Normal file
640
root/usr/share/perl5/vendor_perl/esmith/config.pm
Normal file
@ -0,0 +1,640 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::config;
|
||||
use strict;
|
||||
use vars qw($VERSION);
|
||||
$VERSION = 1.45;
|
||||
|
||||
use Sys::Syslog qw(:DEFAULT setlogsock);
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use Carp qw(cluck);
|
||||
|
||||
my $Default_Config = '/home/e-smith/db/configuration';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::config - Access e-smith config files via hashes
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::config;
|
||||
|
||||
my %config;
|
||||
my $config_obj = tie %config, 'esmith::config', $config_file;
|
||||
|
||||
# Read in the value of Wibble from the $config_file.
|
||||
print $config{Wibble};
|
||||
|
||||
# Write out the value of Wibble to the $config_file.
|
||||
$config{Wibble} = 42;
|
||||
|
||||
my $filename = $config_obj->filename;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The esmith::config package enables Perl programs to read and write
|
||||
entries from the e-smith configuration file using a simple hash
|
||||
interface.
|
||||
|
||||
The configuration file has a simple ASCII representation,
|
||||
with one "key=value" entry per line.
|
||||
|
||||
=begin testing
|
||||
|
||||
use_ok('esmith::config');
|
||||
chdir '10e-smith-lib';
|
||||
|
||||
%Expect = ( foo => 'bar',
|
||||
'this key' => 'has whitespace',
|
||||
'that key ' => 'has trailing whitespace',
|
||||
' another key' => 'has leading whitespace',
|
||||
'this value' => ' has leading whitespace',
|
||||
'that value' => 'has trailing whitespace ',
|
||||
'tricky value' => 'with=equals.',
|
||||
);
|
||||
|
||||
=end testing
|
||||
|
||||
=head2 Tying
|
||||
|
||||
tie %config, 'esmith::config', $config_file;
|
||||
|
||||
Reads in the configuration from the given $config_file, returning a
|
||||
tied hash (%config) populated with the keys & values from the
|
||||
$config_file which you can then use like a normal hash. Any writes or
|
||||
deletes are immediately written back to the $config_file.
|
||||
|
||||
If no $config_file is supplied it falls back to the environment variable
|
||||
ESMITH_CONFIG_DB, and finally defaults to F</home/e-smith/db/configuration>
|
||||
|
||||
If the $config_file doesn't exist it will create one for you.
|
||||
|
||||
=begin testing
|
||||
|
||||
my %config;
|
||||
tie %config, 'esmith::config', 'dummy.conf';
|
||||
ok( tied %config, 'tie worked' );
|
||||
is( $config{foo}, 'bar', ' theres stuff in it' );
|
||||
ok( !exists $config{FILENAME}, ' it only contains config info');
|
||||
is( tied(%config)->{FILENAME}, 'dummy.conf',
|
||||
' and the real object is inside');
|
||||
|
||||
tie %config, 'esmith::config', 'I_dont_exist';
|
||||
ok( tied %config, 'tying a non-existant file' );
|
||||
is( keys %config, 0, ' and its empty' );
|
||||
$config{foo} = 42;
|
||||
isnt( -s 'I_dont_exist', 0 );
|
||||
untie %config;
|
||||
ok( unlink 'I_dont_exist' );
|
||||
|
||||
$ENV{ESMITH_CONFIG_DB} = "dummy.conf";
|
||||
tie %config, 'esmith::config';
|
||||
ok( tied %config, 'tie to ESMITH_CONFIG_DB worked' );
|
||||
is_deeply(\%config, \%Expect, " picked up data");
|
||||
|
||||
=end testing
|
||||
|
||||
=head2 Methods
|
||||
|
||||
You can get at the underlying esmith::config object by using tied().
|
||||
|
||||
my $config_obj = tied %config;
|
||||
|
||||
it has a few useful methods.
|
||||
|
||||
=over 4
|
||||
|
||||
=item filename
|
||||
|
||||
my $file = $config_obj->filename;
|
||||
|
||||
Gets the config filename this object is tied to.
|
||||
|
||||
=begin testing
|
||||
|
||||
my %config;
|
||||
my $obj = tie %config, 'esmith::config', 'dummy.conf';
|
||||
is( $obj->filename, 'dummy.conf', 'filename()' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub filename {
|
||||
my($self) = shift;
|
||||
return $self->{FILENAME};
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=begin _private
|
||||
|
||||
=head2 Private methods
|
||||
|
||||
=over 4
|
||||
|
||||
=item _readconf
|
||||
|
||||
my $config = _readconf($config_file);
|
||||
|
||||
Returns a hash ref of config key/value pairs read out of the given
|
||||
$config_file. If $config_file doesn't exist an empty hash ref will be
|
||||
returned.
|
||||
|
||||
_readconf() understands the config file to be formatted as individual
|
||||
lines of simply:
|
||||
|
||||
key=value
|
||||
|
||||
any further complexity of parsing the value is handled elsewhere.
|
||||
|
||||
=end _private
|
||||
|
||||
=begin testing
|
||||
|
||||
my $config = esmith::config::_readconf('dummy.conf');
|
||||
isnt( keys %$config, 0, '_readconf() got something' );
|
||||
is_deeply( $config, \%Expect, ' read in the right values' );
|
||||
|
||||
$config = esmith::config::_readconf('I_dont_exist');
|
||||
isa_ok( $config, 'HASH', '_readconf from a non-existent file' );
|
||||
is( keys %$config, 0, ' and its empty' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub _readconf
|
||||
{
|
||||
my ($self, $filename) = @_;
|
||||
|
||||
my %config = ();
|
||||
|
||||
unless (open (FH, $filename))
|
||||
{
|
||||
if (-f $filename)
|
||||
{
|
||||
&log("Config: ERROR: \"$filename\" exists but is not readable");
|
||||
}
|
||||
return \%config;
|
||||
}
|
||||
|
||||
my $binmode = $self->_read_binmode;
|
||||
binmode(FH, $binmode) if $binmode;
|
||||
while (my $line = <FH>)
|
||||
{
|
||||
chomp $line;
|
||||
|
||||
# BLIND UNTAINT! Much code wrongly depends on this and
|
||||
# they should be moved away from it.
|
||||
$line =~ /(.*)/;
|
||||
$line = $1;
|
||||
|
||||
# ignore comments and blank lines
|
||||
next if $line =~ /^\s*$/ || $line =~ /^\s*#/;
|
||||
|
||||
my($key, $value) = split /=/, $line, 2;
|
||||
$config{$key} = $value;
|
||||
}
|
||||
|
||||
close(FH);
|
||||
|
||||
return \%config;
|
||||
}
|
||||
|
||||
=begin _private
|
||||
|
||||
=item _writeconf
|
||||
|
||||
my $success = _writeconf($config_file, \%config);
|
||||
|
||||
The given $config_file is overwritten using the entries in %config.
|
||||
|
||||
Returns whether or not the write succeded.
|
||||
|
||||
=end _private
|
||||
|
||||
=begin testing
|
||||
|
||||
my $scratch = 'scratch.conf';
|
||||
ok( esmith::config::_writeconf($scratch, \%Expect),
|
||||
'_writeconf() says it worked' );
|
||||
is_deeply( esmith::config::_readconf($scratch), \%Expect,
|
||||
' wrote the right things' );
|
||||
unlink $scratch;
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub _writeconf
|
||||
{
|
||||
my ($self, $filename, $config) = @_;
|
||||
|
||||
eval {
|
||||
if (-f $filename && ! -r $filename)
|
||||
{
|
||||
die "'$filename' exists but is not readable\n";
|
||||
}
|
||||
|
||||
sysopen (FH, "$filename.$$", O_RDWR | O_CREAT, 0660)
|
||||
or die "Cannot open $filename.$$: $!\n";
|
||||
my $binmode = $self->_write_binmode;
|
||||
binmode(FH, $binmode) if $binmode;
|
||||
|
||||
die "Error writing to $filename.$$: $!" unless
|
||||
printf FH <<EOF, scalar localtime;
|
||||
# DO NOT MODIFY THIS FILE.
|
||||
# This file is automatically maintained by the Mitel Networks SME Server
|
||||
# configuration software. Manually editing this file may put your
|
||||
# system in an unknown state.
|
||||
#
|
||||
# updated: %s
|
||||
EOF
|
||||
|
||||
foreach my $key (sort keys %$config)
|
||||
{
|
||||
print FH "$key=$config->{$key}\n"
|
||||
or die "Error writing to $filename.$$: $!";
|
||||
}
|
||||
|
||||
close (FH) or die "Error closing $filename.$$: $!";
|
||||
|
||||
rename("$filename.$$", $filename)
|
||||
or die "Couldn't rename $filename.$$ to $filename: $!";
|
||||
|
||||
my $gid = getgrnam ('admin') || 0;
|
||||
chown (0, $gid, $filename);
|
||||
};
|
||||
|
||||
if($@) {
|
||||
chomp $@;
|
||||
&log($@);
|
||||
&log("'$filename' will not be updated");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
=begin _private
|
||||
|
||||
=item B<_lock_write>
|
||||
|
||||
=item B<_lock_read>
|
||||
|
||||
$self->_lock_write;
|
||||
$self->_lock_read;
|
||||
|
||||
Sets up read (shared) or write (exclusive) locks on the config file.
|
||||
This is actually locking a semaphore file.
|
||||
|
||||
Returns if the lock succeeded or failed.
|
||||
|
||||
=item B<_unlock>
|
||||
|
||||
$self->_unlock
|
||||
|
||||
Unlocks the config file.
|
||||
|
||||
=end _private
|
||||
|
||||
=cut
|
||||
|
||||
sub _lock_write { $_[0]->_lock(LOCK_EX) }
|
||||
sub _lock_read { $_[0]->_lock(LOCK_SH) }
|
||||
|
||||
sub _lock {
|
||||
return if $] eq 5.006; # Locking is broken in perl 5.6.0
|
||||
my($self, $lock) = @_;
|
||||
|
||||
my $semaphore = $self->{SEMAPHORE_FILE} = $self->{FILENAME}.'.lock';
|
||||
|
||||
eval {
|
||||
open(my $fh, ">>$semaphore") or
|
||||
die "Can't open '$semaphore' semaphore: $!";
|
||||
$self->{SEMAPHORE} = $fh;
|
||||
|
||||
flock($fh, $lock) or
|
||||
die "Can't lock '$semaphore' semaphore: $!";
|
||||
};
|
||||
if( $@ ) {
|
||||
warn $@;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub _unlock {
|
||||
return if $] eq 5.006; # Locking is broken in perl 5.6.0
|
||||
my($self) = @_;
|
||||
|
||||
eval {
|
||||
flock($self->{SEMAPHORE}, LOCK_UN) or
|
||||
die "Can't unlock $self->{SEMAPHORE_FILE}: $!";
|
||||
|
||||
unlink $self->{SEMAPHORE_FILE};
|
||||
delete $self->{SEMAPHORE_FILE};
|
||||
delete $self->{SEMAPHORE};
|
||||
};
|
||||
if( $@ ) {
|
||||
warn $@;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
=end _private
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Constructor for the tied hash. If filename not specified,
|
||||
# defaults to '/home/e-smith/db/configuration'.
|
||||
#------------------------------------------------------------
|
||||
|
||||
sub TIEHASH
|
||||
{
|
||||
my $class = shift;
|
||||
my $filename = shift || $ENV{ESMITH_CONFIG_DB} || $Default_Config;
|
||||
|
||||
if ($filename =~ m:^/home/e-smith/\w+$: )
|
||||
{
|
||||
cluck "*WARNING* esmith::config($filename) called with old " .
|
||||
"database path. The following package needs to be updated: ";
|
||||
|
||||
$filename =~ s:e-smith:e-smith/db:;
|
||||
}
|
||||
|
||||
my $self =
|
||||
{
|
||||
FILENAME => $filename,
|
||||
CONFIG => {},
|
||||
};
|
||||
bless $self, $class;
|
||||
|
||||
$self->{CONFIG} = $self->_readconf($filename);
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Look up a configuration parameter.
|
||||
#------------------------------------------------------------
|
||||
|
||||
sub FETCH
|
||||
{
|
||||
my $self = shift;
|
||||
my $key = shift;
|
||||
|
||||
# Trim leading and trailing whitespace from the key.
|
||||
$key =~ s/^\s+|\s+$//g;
|
||||
|
||||
return $self->{CONFIG}{$key};
|
||||
}
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Store a configuration parameter.
|
||||
#------------------------------------------------------------
|
||||
|
||||
sub STORE
|
||||
{
|
||||
my $self = shift;
|
||||
my $key = shift;
|
||||
my $value = shift;
|
||||
|
||||
die "key not defined" unless defined $key;
|
||||
die "value not defined for key $key" unless defined $value;
|
||||
|
||||
if( $value =~ /\n/ or $key =~ /\n/ ) {
|
||||
&log("$self->{FILENAME}: esmith::config doesn't support newlines in ".
|
||||
"keys or values. Truncating.");
|
||||
$key =~ s/\n.*//s;
|
||||
$value =~ s/\n.*//s;
|
||||
}
|
||||
|
||||
# Trim leading and trailing whitespace from the key and value.
|
||||
$key =~ s/^\s+|\s+$//g;
|
||||
$value =~ s/^\s+|\s+$//g;
|
||||
|
||||
# Make sure that the value has a type. Given the format, it should be
|
||||
# sufficient to ensure that it does not begin with a pipe char.
|
||||
if ($value =~ /^\|/)
|
||||
{
|
||||
warn "ERROR: You should not set a config record without a type (key was $key).\n";
|
||||
}
|
||||
|
||||
# read in config again, just in case it changed
|
||||
$self->_lock_write;
|
||||
$self->{CONFIG} = $self->_readconf($self->{FILENAME});
|
||||
|
||||
if (exists $self->{CONFIG}{$key} and
|
||||
$self->{CONFIG}{$key} eq $value)
|
||||
{
|
||||
$self->_unlock;
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $msg = "$self->{FILENAME}: OLD $key=";
|
||||
|
||||
if (exists $self->{CONFIG}{$key})
|
||||
{
|
||||
$msg .= "$self->{CONFIG}{$key}";
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg .= "(undefined)";
|
||||
}
|
||||
|
||||
&log($msg);
|
||||
|
||||
$self->{CONFIG} {$key} = $value;
|
||||
&log("$self->{FILENAME}: NEW $key=$self->{CONFIG}{$key}");
|
||||
|
||||
$self->_writeconf ($self->{FILENAME}, $self->{CONFIG});
|
||||
$self->_unlock;
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Delete a configuration parameter.
|
||||
#------------------------------------------------------------
|
||||
|
||||
sub DELETE
|
||||
{
|
||||
my $self = shift;
|
||||
my $key = shift;
|
||||
|
||||
# Trim leading and trailing whitespace from the key.
|
||||
$key =~ s/^\s+|\s+$//g;
|
||||
|
||||
# read in config again, just in case it changed
|
||||
$self->_lock_write;
|
||||
$self->{CONFIG} = $self->_readconf($self->{FILENAME});
|
||||
|
||||
my $previous = delete $self->{CONFIG} {$key};
|
||||
$self->_writeconf ($self->{FILENAME}, $self->{CONFIG});
|
||||
$self->_unlock;
|
||||
|
||||
&log("$self->{FILENAME}: DELETE $key=$previous");
|
||||
|
||||
return $previous;
|
||||
}
|
||||
|
||||
=begin _private
|
||||
|
||||
=item CLEAR
|
||||
|
||||
tie method: Clear the configuration file
|
||||
|
||||
=end _private
|
||||
|
||||
=begin testing
|
||||
|
||||
my $scratch = 'scratch.conf';
|
||||
tie %config, 'esmith::config', $scratch;
|
||||
ok( tied %config, 'tying a non-existant file' );
|
||||
is( keys %config, 0, ' and its empty' );
|
||||
$config{fibble} = 'blah';
|
||||
isnt( keys %config, 0, ' and its not empty now' );
|
||||
%config = ();
|
||||
is( keys %config, 0, ' and CLEAR made it empty again' );
|
||||
unlink $scratch;
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub CLEAR
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
$self->{CONFIG} = ();
|
||||
$self->_writeconf ($self->{FILENAME}, $self->{CONFIG});
|
||||
|
||||
&log("$self->{FILENAME}: CLEAR");
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Check whether a particular key exists in the configuration file.
|
||||
#------------------------------------------------------------
|
||||
|
||||
sub EXISTS
|
||||
{
|
||||
my $self = shift;
|
||||
my $key = shift;
|
||||
|
||||
# Trim leading and trailing whitespace from the key.
|
||||
$key =~ s/^\s+|\s+$//g;
|
||||
|
||||
return exists $self->{CONFIG} {$key};
|
||||
}
|
||||
|
||||
#------------------------------------------------------------
|
||||
# FIRSTKEY is called whenever we start iterating over the
|
||||
# configuration table. We cache the configuration table at
|
||||
# this point to ensure reasonable results if the
|
||||
# configuration file is changed by another program during
|
||||
# the iteration.
|
||||
#------------------------------------------------------------
|
||||
|
||||
sub FIRSTKEY
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $discard = keys %{$self->{CONFIG}}; # reset each() iterator
|
||||
|
||||
return each %{$self->{CONFIG}};
|
||||
}
|
||||
|
||||
#------------------------------------------------------------
|
||||
# NEXTKEY is called for all iterations after the first. We
|
||||
# just keep returning results from the cached configuration
|
||||
# table. A null array is returned at the end. If the caller
|
||||
# starts a new iteration, the FIRSTKEY subroutine is called
|
||||
# again, causing the cache to be reloaded.
|
||||
#------------------------------------------------------------
|
||||
|
||||
sub NEXTKEY
|
||||
{
|
||||
my $self = shift;
|
||||
return each %{$self->{CONFIG}};
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Log messages to syslog
|
||||
#------------------------------------------------------------
|
||||
|
||||
sub log
|
||||
{
|
||||
# There is a bug in Perl 5.00504 and above. If you are using the unix
|
||||
# domain socket, do NOT use ndelay as part of the second argument
|
||||
# to openlog().
|
||||
|
||||
my $msg = shift;
|
||||
$msg =~ s/[^[:ascii:]]/_/g;
|
||||
my $program = $0;
|
||||
|
||||
setlogsock 'unix';
|
||||
openlog($program, 'pid', 'local1');
|
||||
syslog('info', "%s", $msg);
|
||||
closelog();
|
||||
}
|
||||
|
||||
=item _read_binmode
|
||||
|
||||
return undef, indicating that by default binmode() need not be called after
|
||||
file open.
|
||||
|
||||
=end _private
|
||||
|
||||
=cut
|
||||
|
||||
sub _read_binmode
|
||||
{
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub _write_binmode
|
||||
{
|
||||
return undef;
|
||||
}
|
||||
|
||||
=head1 BUGS and CAVEATS
|
||||
|
||||
You can't have newlines in keys or values.
|
||||
|
||||
While the config values happen to be untainted B<do not depend on this
|
||||
behavior> as it will change in the future.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
SME Server Developers <bugs@e-smith.com>
|
||||
|
||||
For more information, see http://www.e-smith.org/
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
esmith::db
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
25
root/usr/share/perl5/vendor_perl/esmith/config/utf8.pm
Normal file
25
root/usr/share/perl5/vendor_perl/esmith/config/utf8.pm
Normal file
@ -0,0 +1,25 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2008 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::config::utf8;
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use vars qw(@ISA);
|
||||
@ISA = qw(esmith::config);
|
||||
|
||||
sub _read_binmode
|
||||
{
|
||||
return ":encoding(UTF-8)";
|
||||
}
|
||||
|
||||
sub _write_binmode
|
||||
{
|
||||
return ":utf8";
|
||||
}
|
||||
|
||||
1;
|
||||
|
603
root/usr/share/perl5/vendor_perl/esmith/console.pm
Executable file
603
root/usr/share/perl5/vendor_perl/esmith/console.pm
Executable file
@ -0,0 +1,603 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2006 Mitel Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::console - A class to provide a backend library to the server console.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::console;
|
||||
|
||||
my $console = esmith::console->new();
|
||||
|
||||
($rc, $choice) = $console->message_page
|
||||
(
|
||||
title => gettext("Administrator password not set"),
|
||||
text => gettext("Sorry, you must set the administrator password."),
|
||||
);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This class provides a backend library of methods for the frontend console on
|
||||
the server. The intent is that all of the whiptail code is hidden in this
|
||||
library, and the frontend can just concern itself with the logical progression
|
||||
through any and all applicable screens.
|
||||
|
||||
=head1 Methods
|
||||
|
||||
=cut
|
||||
|
||||
package esmith::console;
|
||||
|
||||
use strict;
|
||||
use vars qw($VERSION @ISA @EXPORT_OK);
|
||||
use esmith::util;
|
||||
use Locale::gettext;
|
||||
use esmith::ConfigDB;
|
||||
use esmith::I18N;
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
|
||||
use constant SCREEN_ROWS => 22;
|
||||
use constant SCREEN_COLUMNS => 76;
|
||||
use constant CONSOLE_SCREENS => "/sbin/e-smith/console-screens";
|
||||
|
||||
BEGIN
|
||||
{
|
||||
# disable CTRL-C
|
||||
$SIG{INT} = 'IGNORE';
|
||||
|
||||
# Set PATH explicitly and clear related environment variables so that calls
|
||||
# to external programs do not cause results to be tainted. See
|
||||
# "perlsec" manual page for details.
|
||||
|
||||
$ENV {'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin';
|
||||
$ENV {'SHELL'} = '/bin/bash';
|
||||
delete $ENV {'ENV'};
|
||||
delete $ENV {'BASH_ENV'};
|
||||
}
|
||||
|
||||
=head2 new
|
||||
|
||||
This is the class constructor.
|
||||
|
||||
=cut
|
||||
|
||||
sub new
|
||||
{
|
||||
my $class = ref($_[0]) || $_[0];
|
||||
my $self = {};
|
||||
esmith::util::setRealToEffective ();
|
||||
|
||||
my $i18n = new esmith::I18N;
|
||||
$i18n->setLocale("server-console");
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Set stdin, stdout and stderr to console
|
||||
#------------------------------------------------------------
|
||||
|
||||
if (defined $ARGV [0])
|
||||
{
|
||||
$ARGV[0] =~ /(console|tty\d*)/ && -c "/dev/$1"
|
||||
or die gettext("Bad ttyname:"), " ", $ARGV[0], "\n";
|
||||
my $tty = $1;
|
||||
|
||||
open (STDIN, "</dev/$tty") or die gettext("Can't redirect stdin"), ": $!\n";
|
||||
open (STDOUT, ">/dev/$tty") or die gettext("Can't redirect stdout"), ": $!\n";
|
||||
|
||||
my $pid = open(STDERR, "|-");
|
||||
die gettext("Can't fork"), ": $!\n" unless defined $pid;
|
||||
|
||||
unless ($pid)
|
||||
{
|
||||
exec qw(/usr/bin/logger -p local1.info -t console);
|
||||
}
|
||||
}
|
||||
|
||||
$self = bless $self, $class;
|
||||
return $self;
|
||||
}
|
||||
|
||||
=head2 screen and dialog
|
||||
|
||||
These method are wrappers around whiptail and dialog, and permit the creation
|
||||
of custom screens depending on the arguments passed. They are typically not
|
||||
called directly, but are used by all of the other page methods that
|
||||
follow. You should only call these method directly if none of the other
|
||||
methods apply.
|
||||
|
||||
=cut
|
||||
|
||||
sub screen
|
||||
{
|
||||
_screen(shift, "/usr/bin/dialog", @_);
|
||||
}
|
||||
|
||||
sub dialog
|
||||
{
|
||||
_screen(shift, "/usr/bin/dialog", @_);
|
||||
}
|
||||
|
||||
sub whiptail
|
||||
{
|
||||
_screen(shift, "/usr/bin/whiptail", @_);
|
||||
}
|
||||
|
||||
sub _screen
|
||||
{
|
||||
my $self = shift;
|
||||
my $whiptail = shift;
|
||||
my @whiptailArgs = @_;
|
||||
|
||||
# now would be a good time to flush output buffers, so the partial
|
||||
# buffers don't get copied:
|
||||
|
||||
$| = 1;
|
||||
print "";
|
||||
|
||||
pipe (READER, WRITER)
|
||||
or die gettext("Couldn't create pipe") . ": $!\n";
|
||||
|
||||
my $pid = fork;
|
||||
|
||||
if (! defined $pid)
|
||||
{
|
||||
die gettext("Couldn't fork") . ": $!\n";
|
||||
}
|
||||
|
||||
elsif ($pid == 0)
|
||||
{
|
||||
#----------------------------------------
|
||||
# Child
|
||||
#----------------------------------------
|
||||
|
||||
# Attach child's STDIN to the reading end of the pipe
|
||||
close READER
|
||||
or die gettext("Couldn't close reading end of pipe") , ": $!\n";
|
||||
|
||||
if ($whiptail =~ m{\bwhiptail$} ) {
|
||||
# whiptail sends its output via STDERR. We temporarily
|
||||
# shut off warnings so they don't interfere with that.
|
||||
local $^W = 0;
|
||||
|
||||
open STDERR, ">& WRITER"
|
||||
or die gettext("Couldn't connect STDERR to pipe"), ": $!\n";
|
||||
|
||||
close WRITER
|
||||
or die gettext("Couldn't close writing end of pipe"), ": $!\n";
|
||||
|
||||
unshift @whiptailArgs, $whiptail,
|
||||
'--backtitle', $self->backtitle;
|
||||
} else {
|
||||
use Fcntl qw/F_SETFD/;
|
||||
|
||||
# Clear close-on-exec on WRITER so that it stays open for dialog to use
|
||||
fcntl(WRITER, F_SETFD, 0);
|
||||
|
||||
unshift @whiptailArgs, $whiptail,
|
||||
'--backtitle', $self->backtitle, "--output-fd", fileno(WRITER);
|
||||
}
|
||||
exec @whiptailArgs;
|
||||
die gettext("Couldn't exec:"), ": $!\n";
|
||||
}
|
||||
|
||||
#----------------------------------------
|
||||
# Parent
|
||||
#----------------------------------------
|
||||
|
||||
close WRITER;
|
||||
|
||||
my $choice = <READER>;
|
||||
close READER;
|
||||
|
||||
waitpid ($pid, 0);
|
||||
my $rc = $?;
|
||||
|
||||
return ($rc, $choice);
|
||||
}
|
||||
|
||||
=head2 backtitle
|
||||
|
||||
Console header line for each page
|
||||
|
||||
=cut
|
||||
|
||||
sub backtitle
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $db = esmith::ConfigDB->open_ro or die "Couldn't open ConfigDB\n";
|
||||
|
||||
sprintf("%-33s%45s",
|
||||
($db->get_prop('sysconfig', 'ProductName') || "SME Server") . " " .
|
||||
($db->get_prop('sysconfig', 'ReleaseVersion') || "UNKNOWN"),
|
||||
"Copyright (C) 1999-2006 Mitel Corporation, Copyright (C) ____COPYYEARS____ Koozali Foundation, Inc."
|
||||
);
|
||||
}
|
||||
|
||||
=head2 message_page
|
||||
|
||||
This method should be used whenever a screen that displays a simple message
|
||||
is required.
|
||||
|
||||
=cut
|
||||
|
||||
sub message_page
|
||||
{
|
||||
my $self = shift;
|
||||
my %params = @_;
|
||||
|
||||
my $title = $params{title};
|
||||
my $message_box = $params{text};
|
||||
|
||||
my $left = defined $params{left} ? $params{left} : gettext("Back");
|
||||
my $right = defined $params{right} ? $params{right} : gettext("Next");
|
||||
|
||||
$self->screen ("--title", $title,
|
||||
"--cancel-label", $left,
|
||||
"--ok-label", $right,
|
||||
"--clear",
|
||||
"--msgbox", $message_box,
|
||||
SCREEN_ROWS,
|
||||
SCREEN_COLUMNS,
|
||||
);
|
||||
}
|
||||
|
||||
=head2 tryagain_page
|
||||
|
||||
This method displays a simple "try again" screen.
|
||||
|
||||
=cut
|
||||
|
||||
sub tryagain_page
|
||||
{
|
||||
my $self = shift;
|
||||
my %params = @_;
|
||||
|
||||
my $title = $params{title};
|
||||
my $choice = $params{choice};
|
||||
|
||||
my $try_again = "; " . gettext("please try again");
|
||||
|
||||
my $message_box = $title . ":'${choice}'" . $try_again;
|
||||
|
||||
$self->screen ("--title", $title,
|
||||
"--cancel-label", gettext("Back"),
|
||||
"--ok-label", gettext("Next"),
|
||||
"--clear",
|
||||
"--msgbox", $message_box,
|
||||
SCREEN_ROWS,
|
||||
SCREEN_COLUMNS,
|
||||
);
|
||||
}
|
||||
|
||||
=head2 password_page
|
||||
|
||||
This method displays a screen suitable for entering a password.
|
||||
|
||||
=cut
|
||||
|
||||
sub password_page
|
||||
{
|
||||
my $self = shift;
|
||||
my %params = @_;
|
||||
|
||||
my $title = $params{title};
|
||||
my $message_box = $params{text};
|
||||
|
||||
my $left = defined $params{left} ? $params{left} : gettext("Back");
|
||||
my $right = defined $params{right} ? $params{right} : gettext("Next");
|
||||
|
||||
$self->dialog ("--title", $title,
|
||||
"--insecure",
|
||||
"--cancel-label", $left,
|
||||
"--ok-label", $right,
|
||||
"--clear",
|
||||
"--passwordbox", "\n" . $message_box,
|
||||
SCREEN_ROWS,
|
||||
SCREEN_COLUMNS,
|
||||
);
|
||||
}
|
||||
|
||||
=head2 yesno_page
|
||||
|
||||
This method displays a simple yes/no screen, so the user can make a
|
||||
simple binary selection.
|
||||
|
||||
=cut
|
||||
|
||||
sub yesno_page
|
||||
{
|
||||
my $self = shift;
|
||||
my %params = @_;
|
||||
|
||||
my $title = $params{title};
|
||||
my $text = $params{text};
|
||||
|
||||
my $left = defined $params{left} ? $params{left} : gettext("Yes");
|
||||
my $right = defined $params{right} ? $params{right} : gettext("No");
|
||||
my @args = (
|
||||
"--title" => $title,
|
||||
"--yes-label" => $left,
|
||||
"--no-label" => $right,
|
||||
);
|
||||
push @args, "--defaultno" if defined $params{defaultno};
|
||||
push @args, "--clear";
|
||||
|
||||
$self->screen (@args,
|
||||
"--yesno", $text,
|
||||
SCREEN_ROWS,
|
||||
SCREEN_COLUMNS,
|
||||
);
|
||||
}
|
||||
|
||||
=head2 input_page
|
||||
|
||||
This method displays a simple input screen with an input box.
|
||||
|
||||
=cut
|
||||
|
||||
sub input_page
|
||||
{
|
||||
my $self = shift;
|
||||
my %params = @_;
|
||||
|
||||
my $title = $params{title};
|
||||
my $text = $params{text};
|
||||
my $value = $params{value};
|
||||
|
||||
my $left = defined $params{left} ? $params{left} : gettext("Back");
|
||||
my $right = defined $params{right} ? $params{right} : gettext("Next");
|
||||
|
||||
$self->screen("--title", $title,
|
||||
"--cancel-label", $left,
|
||||
"--ok-label", $right,
|
||||
"--clear",
|
||||
"--inputbox", $text,
|
||||
SCREEN_ROWS,
|
||||
SCREEN_COLUMNS,
|
||||
$value
|
||||
);
|
||||
}
|
||||
|
||||
=head2 infobox
|
||||
|
||||
This method is similar to a messagebox, but exits immediately, without clearing the screen.
|
||||
|
||||
=cut
|
||||
|
||||
sub infobox
|
||||
{
|
||||
my $self = shift;
|
||||
my %params = @_;
|
||||
my $title = $params{title};
|
||||
my $text = $params{text};
|
||||
my $height = $params{height} || "8";
|
||||
my $width = $params{width} || SCREEN_COLUMNS;
|
||||
$self->screen("--title", $title,
|
||||
"--infobox", $text,
|
||||
$height,
|
||||
$width,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
=head2 textbox
|
||||
|
||||
A text box lets you display the contents of a text file in a dialog box.
|
||||
It is like a simple text file viewer.
|
||||
|
||||
=cut
|
||||
|
||||
sub textbox
|
||||
{
|
||||
my $self = shift;
|
||||
my %params = @_;
|
||||
my $title = $params{title};
|
||||
my $file = $params{file};
|
||||
my $height = $params{height} || '20';
|
||||
my $width = $params{width} || SCREEN_COLUMNS;
|
||||
$self->screen("--title", $title,
|
||||
"--textbox", $file,
|
||||
$height,
|
||||
$width,
|
||||
);
|
||||
}
|
||||
|
||||
=head2 menu_page
|
||||
|
||||
This method displays a screen with a menu.
|
||||
|
||||
=cut
|
||||
|
||||
sub menu_page
|
||||
{
|
||||
my $self = shift;
|
||||
my %params = @_;
|
||||
|
||||
my $title = $params{title};
|
||||
my $text = $params{text};
|
||||
my @args = ("--clear", "--title", $title);
|
||||
if ($params{default})
|
||||
{
|
||||
push @args, "--default-item", $params{default};
|
||||
}
|
||||
|
||||
my $value = $params{value};
|
||||
my $argsref = $params{argsref};
|
||||
|
||||
my $menu_rows = scalar @$argsref / 2;
|
||||
|
||||
$menu_rows = 10 if ($menu_rows > 10);
|
||||
|
||||
my $left = defined $params{left} ? $params{left} : gettext("Back");
|
||||
my $right = defined $params{right} ? $params{right} : gettext("Next");
|
||||
|
||||
$self->dialog(@args,
|
||||
"--cancel-label", $left,
|
||||
"--ok-label", $right,
|
||||
"--menu", $text,
|
||||
SCREEN_ROWS,
|
||||
SCREEN_COLUMNS,
|
||||
$menu_rows,
|
||||
@$argsref,
|
||||
);
|
||||
}
|
||||
|
||||
=head2 keep_option
|
||||
|
||||
??
|
||||
|
||||
=cut
|
||||
|
||||
sub keep_option
|
||||
{
|
||||
my $self = shift;
|
||||
my ($value) = @_;
|
||||
|
||||
my $keep_phrase = gettext("Keep the current setting");
|
||||
|
||||
return ( gettext("keep"), "${keep_phrase}: $value" );
|
||||
}
|
||||
|
||||
=head2 gauge
|
||||
|
||||
This method displays a progress bar. It takes a coderef as parameter, and uses
|
||||
the coderef to drive the --gauge widget of the dialog program, as well as to
|
||||
perform whatever actions are being reported by the progress bar. The coderef
|
||||
should take one parameter, which is the file handle to write the controlling
|
||||
text to. If the return value of the coderef is defined, it is displayed by a
|
||||
message_page after the progress bar terminates.
|
||||
|
||||
All text used to update the progress bar should either be numbers between 0
|
||||
and 100, or arbitrary text sandwiched between leading and training lines
|
||||
of 'XXX' followed by newline. The numbers will update the percentage complete
|
||||
of the display, and the text will update the displayed text. Updating the
|
||||
displayed text will reset the precentage complete to 0, so text should always
|
||||
be followed by number.
|
||||
|
||||
=cut
|
||||
|
||||
sub gauge
|
||||
{
|
||||
my $self = shift;
|
||||
my $sub = shift;
|
||||
my %params = @_;
|
||||
my $title = $params{title} || 'Progress';
|
||||
my $feedback_title = $params{feedback_title} || 'Status';
|
||||
my $init_text = $params{text} || 'Progress';
|
||||
my @args = (
|
||||
'--backtitle', $self->backtitle,
|
||||
'--title', gettext($title),
|
||||
);
|
||||
push @args, "--clear" if $params{clear};
|
||||
push @args, "--colors" if $params{colors};
|
||||
push @args, "--no-collapse" if $params{no_collapse};
|
||||
|
||||
use FileHandle;
|
||||
|
||||
unless (open(WR, '|-'))
|
||||
{
|
||||
exec('/usr/bin/dialog',
|
||||
@args,
|
||||
'--gauge',
|
||||
gettext($init_text),
|
||||
SCREEN_ROWS,
|
||||
SCREEN_COLUMNS,
|
||||
);
|
||||
}
|
||||
WR->autoflush(1);
|
||||
my $text = &$sub(*WR);
|
||||
close(WR);
|
||||
$self->message_page('title' => $feedback_title, 'text' => $text)
|
||||
if defined $text;
|
||||
}
|
||||
|
||||
=head2 run_screens
|
||||
|
||||
This method takes a directory of screens to run, and runs them in order.
|
||||
To support navigation between screens, this method respects an integer
|
||||
return value from the screens.
|
||||
|
||||
0 = all is well, continue to the next screen
|
||||
1 = all is not well, go back to the previous screen
|
||||
2 = catastrophic failure - return from run_screen
|
||||
|
||||
=cut
|
||||
|
||||
sub run_screens
|
||||
{
|
||||
my $self = shift;
|
||||
my ($subdir) = @_;
|
||||
|
||||
my $dir = CONSOLE_SCREENS . "/$subdir";
|
||||
|
||||
# This is fine. Noop if the directory isn't there.
|
||||
unless (-d $dir)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
# This is not fine. If it's there, we should be able to open it.
|
||||
unless ( opendir(SCREENS, $dir) )
|
||||
{
|
||||
warn "Failed to open directory $dir: $!\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
my @screens = sort grep (!/^(\.\.?)$/, readdir (SCREENS));
|
||||
|
||||
my @previous_screens = ();
|
||||
while (@screens)
|
||||
{
|
||||
my $screen = shift @screens;
|
||||
unless ( $screen =~ /(S\d\d[\d\w]+)/ )
|
||||
{
|
||||
warn "Unknown screen type $dir/$screen\n";
|
||||
next;
|
||||
}
|
||||
|
||||
$screen = $1;
|
||||
my $rv = system( "$dir/$screen" );
|
||||
$rv >>= 8;
|
||||
if ($rv == 0)
|
||||
{
|
||||
# Success, move to next screen.
|
||||
push @previous_screens, $screen;
|
||||
}
|
||||
elsif ($rv == 1)
|
||||
{
|
||||
# Failure, go back one screen.
|
||||
unshift @screens, $screen;
|
||||
if (@previous_screens)
|
||||
{
|
||||
unshift @screens, pop @previous_screens;
|
||||
}
|
||||
else
|
||||
{
|
||||
# We're at the beginning of the stack. Just return.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# Catastrophic failure, return. While 2 is the agreed-upon
|
||||
# return code for this, consider it a catastrophic failure
|
||||
# if we don't get a valid return code.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
SME Server Developers <smebugs@mitel.com>
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
743
root/usr/share/perl5/vendor_perl/esmith/db.pm
Normal file
743
root/usr/share/perl5/vendor_perl/esmith/db.pm
Normal file
@ -0,0 +1,743 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::db;
|
||||
|
||||
use esmith::config;
|
||||
use strict;
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::db - Routines for handling the e-smith configuration database
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<THIS MODULE HAS BEEN DEPRECATED>
|
||||
|
||||
use esmith::db;
|
||||
use esmith::config;
|
||||
|
||||
my %config;
|
||||
tie %config, 'esmith::config', $config_file;
|
||||
|
||||
db_set(\%config, $key, $type, \%properties);
|
||||
db_set_type(\%config, $key, $type);
|
||||
db_set_prop(\%config, $key, $property => $new_value);
|
||||
|
||||
my($type, %properties) = db_get(\%config, $key);
|
||||
my $type = db_get_type(\%config, $key);
|
||||
my %properties = db_get_prop(\%config, $key);
|
||||
my $value = db_get_prop(\%config, $key, $property);
|
||||
|
||||
db_delete(\%config, $key);
|
||||
db_delete_prop(\%config, $key, $property);
|
||||
|
||||
db_print(\%config, $key);
|
||||
db_show(\%config, $key);
|
||||
db_print_type(\%config, $key);
|
||||
db_print_prop(\%config, $key, $prop);
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<THIS MODULE HAS BEEN DEPRECATED>. Please use a subclass of
|
||||
esmith::DB::db instead, such as esmith::AccountsDB or esmith::ConfigDB.
|
||||
|
||||
I<Do not try to change this module>. Much code depends on subtle
|
||||
nuances and bugs and you will break things if you try to fix it.
|
||||
Instead, move any existing code away from esmith::db and towards
|
||||
esmith::DB::db.
|
||||
|
||||
|
||||
This module provides utility routines for manipulating e-smith
|
||||
configuration data. OO and non-OO versions of the routines are provided.
|
||||
For example, db_set() is the non-OO while set() can be called with an
|
||||
object reference.
|
||||
|
||||
E-Smith DB entries have three parts. A key, a type and a hash of
|
||||
properties.
|
||||
|
||||
key squid
|
||||
type cephalopod
|
||||
properties arms => 10
|
||||
species => Loligo
|
||||
|
||||
=cut
|
||||
|
||||
use vars qw($VERSION @ISA @EXPORT);
|
||||
$VERSION = sprintf "%d.%03d", q$Revision: 1.16 $ =~ /(\d+)\.(\d+)/;
|
||||
|
||||
use Exporter;
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(
|
||||
db_set
|
||||
db_get
|
||||
db_delete
|
||||
|
||||
db_set_type
|
||||
db_get_type
|
||||
|
||||
db_get_prop
|
||||
db_set_prop
|
||||
db_delete_prop
|
||||
|
||||
db_print
|
||||
db_show
|
||||
|
||||
db_print_type
|
||||
db_print_prop
|
||||
);
|
||||
|
||||
=head2 Functions
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<db_set>
|
||||
|
||||
my $success = db_set(\%config, $key, $raw_value);
|
||||
my $success = db_set(\%config, $key, $type);
|
||||
my $success = db_set(\%config, $key, $type, \%properties);
|
||||
|
||||
Enters a new $key into the %config or replaces an existing $key. It
|
||||
sets the $type and optionally %properties.
|
||||
|
||||
As a "bug which has become a feature" you can feed db_set() the
|
||||
$raw_value for a $key (ie. 'type|prop1|val1|prop2|val2') and it will
|
||||
setup the types and properties properly. I<Do not depend on this> but
|
||||
don't change it either. There's code that depends on this behavior.
|
||||
|
||||
It returns true on success, false on failure.
|
||||
|
||||
If the $key contains a newline it will fail.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_set
|
||||
{
|
||||
my ($hash, $key, $new_value, $hashref) = @_;
|
||||
|
||||
return undef if ($key =~ /\n/);
|
||||
if (defined $hashref)
|
||||
{
|
||||
my $properties = _db_hash_to_string($hashref);
|
||||
if (defined $properties && $properties ne '')
|
||||
{
|
||||
$new_value .= "|$properties";
|
||||
}
|
||||
}
|
||||
$new_value and $new_value =~ s/\n/\\n/g;
|
||||
$$hash{$key} = $new_value;
|
||||
return undef unless defined db_get($hash, $key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 B<db_get>
|
||||
|
||||
my($type, %properties) = db_get(\%config, $key);
|
||||
my $raw_value = db_get(\%config, $key);
|
||||
my @keys = db_get(\%config);
|
||||
|
||||
Reads the $type and %properties for the given $key in %config.
|
||||
|
||||
In scalar context it returns the raw value of $config{$key} B<NOT> the
|
||||
type! But it unescapes newlines. I<Use db_get_type() instead>.
|
||||
|
||||
If a $key is not given it returns all the @keys in the %config.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_get
|
||||
{
|
||||
my ($hash, $key) = @_;
|
||||
|
||||
return sort keys %$hash unless defined $key;
|
||||
return undef unless exists $$hash{$key};
|
||||
|
||||
my $value = $$hash{$key};
|
||||
$value and $value =~ s/\\n/\n/g;
|
||||
return wantarray() ? _db_string_to_type_and_hash($value) : $value;
|
||||
}
|
||||
|
||||
=item B<db_delete>
|
||||
|
||||
db_delete(\%config, $key)
|
||||
|
||||
Deletes the $key from %config.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_delete
|
||||
{
|
||||
my ($hash, $key) = @_;
|
||||
|
||||
return undef unless defined db_get($hash, $key);
|
||||
|
||||
delete $$hash{$key};
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
=item B<db_set_type>
|
||||
|
||||
my $success = db_set_type(\%config, $key, $type)
|
||||
|
||||
Sets the $type for $config{$key}.
|
||||
|
||||
Returns true if the set succeeded, false otherwise.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_set_type
|
||||
{
|
||||
my ($hash, $key, $type) = @_;
|
||||
|
||||
return undef unless defined db_get($hash, $key);
|
||||
|
||||
my %properties = db_get_prop($hash, $key);
|
||||
|
||||
return db_set($hash, $key, $type, \%properties);
|
||||
}
|
||||
|
||||
|
||||
=item B<db_get_type>
|
||||
|
||||
my $type = db_get_type(\%config, $key);
|
||||
|
||||
Returns the $type associated with the $key in the %config database.
|
||||
|
||||
Will return undef if the $key doesn't exist.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_get_type
|
||||
{
|
||||
my ($hash, $key) = @_;
|
||||
|
||||
return undef unless defined db_get($hash, $key);
|
||||
|
||||
my ($type) =
|
||||
_db_string_to_type_and_hash(db_get($hash, $key));
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
||||
=item B<db_set_prop>
|
||||
|
||||
my $success = db_set_prop(\%config, $key, $property => $new_value)
|
||||
|
||||
Sets the given $property of the $key in the %config database to the
|
||||
$new_value. If the $property didn't exist, it will be added.
|
||||
|
||||
Returns true/value if it succeeded/failed.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_set_prop
|
||||
{
|
||||
my ($hash, $key, $prop, $new_value) = @_;
|
||||
|
||||
return undef unless defined db_get($hash, $key);
|
||||
|
||||
my $type = db_get_type($hash, $key);
|
||||
my %properties = db_get_prop($hash, $key);
|
||||
$properties{$prop} = $new_value;
|
||||
return db_set($hash, $key, $type, \%properties);
|
||||
}
|
||||
|
||||
|
||||
=item B<db_get_prop>
|
||||
|
||||
my %properties = db_get_prop(\%config, $key);
|
||||
my $value = db_get_prop(\%config, $key, $property);
|
||||
|
||||
Returns the %properties for a $key in the %config database. If you
|
||||
ask for a specific $property you'll get the $value for that $property.
|
||||
|
||||
Returns undef if the $key or $property doesn't exist.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_get_prop
|
||||
{
|
||||
my ($hash, $key, $prop) = @_;
|
||||
|
||||
my $val = db_get($hash, $key);
|
||||
return (defined $prop ? undef : ()) unless defined $val;
|
||||
|
||||
my($type, %properties) = _db_string_to_type_and_hash($val);
|
||||
|
||||
return %properties unless defined $prop;
|
||||
return undef unless exists $properties{$prop};
|
||||
return $properties{$prop};
|
||||
}
|
||||
|
||||
|
||||
=item B<db_delete_prop>
|
||||
|
||||
db_delete_prop(\%config, $key, $property)
|
||||
|
||||
Deletes a $property from the $key in the %config.
|
||||
|
||||
Returns undef if the $key doesn't exist.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_delete_prop
|
||||
{
|
||||
my ($hash, $key, $prop) = @_;
|
||||
|
||||
return undef unless defined db_get($hash, $key);
|
||||
|
||||
my $type = db_get_type($hash, $key);
|
||||
my %properties = db_get_prop($hash, $key);
|
||||
delete $properties{$prop};
|
||||
return db_set($hash, $key, $type, \%properties);
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=head2 Debugging Functions
|
||||
|
||||
These functions are useful for debugging.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<db_print>
|
||||
|
||||
db_print(\%config);
|
||||
db_print(\%config, $key);
|
||||
|
||||
Prints out keys and raw values in the %config database. If $key is
|
||||
given it prints the $key and its raw value. If no $key is given it
|
||||
prints out all the keys and their raw values.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_print
|
||||
{
|
||||
my ($hash, $key) = @_;
|
||||
|
||||
my @list;
|
||||
|
||||
if (defined $key)
|
||||
{
|
||||
return undef unless defined db_get($hash, $key);
|
||||
@list = ($key);
|
||||
}
|
||||
else
|
||||
{
|
||||
@list = db_get($hash);
|
||||
}
|
||||
|
||||
return undef unless scalar @list;
|
||||
|
||||
foreach (@list)
|
||||
{
|
||||
print "$_=", scalar db_get($hash, $_),"\n";
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
=item B<db_show>
|
||||
|
||||
db_show(\%config);
|
||||
db_show(\%config, $key);
|
||||
|
||||
Prints out keys and their values in a human readable format.
|
||||
|
||||
If $key is given it prints out the $key, type and properties of that
|
||||
$key. Otherwise it prints out the key, type and properties for all
|
||||
keys.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_show
|
||||
{
|
||||
my ($hash, $key) = @_;
|
||||
|
||||
my @list;
|
||||
|
||||
if (defined $key)
|
||||
{
|
||||
return undef unless defined db_get($hash, $key);
|
||||
@list = ($key);
|
||||
}
|
||||
else
|
||||
{
|
||||
@list = db_get($hash) unless defined $key;
|
||||
}
|
||||
|
||||
return undef unless scalar @list;
|
||||
|
||||
foreach (@list)
|
||||
{
|
||||
print "$_=";
|
||||
|
||||
my $type = db_get_type($hash, $_);
|
||||
|
||||
if (defined $type)
|
||||
{
|
||||
print "$type\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print "\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my %properties = db_get_prop($hash, $_);
|
||||
next unless scalar keys %properties;
|
||||
|
||||
foreach my $property (sort keys %properties)
|
||||
{
|
||||
print " $property=$properties{$property}\n";
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
=item B<db_print_type>
|
||||
|
||||
db_print_type(\%config);
|
||||
db_print_type(\%config, $key);
|
||||
|
||||
Prints out keys and their types in the %config database.
|
||||
|
||||
If $key is given, it prints out just that $key and its type.
|
||||
Otherwise it prints out all the keys and their types.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_print_type
|
||||
{
|
||||
my ($hash, $key) = @_;
|
||||
|
||||
my @list;
|
||||
|
||||
if (defined $key)
|
||||
{
|
||||
return undef unless defined db_get($hash, $key);
|
||||
@list = $key;
|
||||
}
|
||||
else
|
||||
{
|
||||
@list = db_get($hash);
|
||||
}
|
||||
|
||||
return undef unless scalar @list;
|
||||
|
||||
foreach (@list)
|
||||
{
|
||||
print "$_=";
|
||||
|
||||
my $type = db_get_type($hash, $_);
|
||||
|
||||
print db_get_type($hash, $_),"\n" if defined $type;
|
||||
print "\n" unless defined $type;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
=item B<db_print_prop>
|
||||
|
||||
db_print_prop(\%config, $key);
|
||||
db_print_prop(\%config, $key, $property);
|
||||
|
||||
Prints out the properties (or a single $property) of the given $key in
|
||||
the %config.
|
||||
|
||||
=cut
|
||||
|
||||
sub db_print_prop
|
||||
{
|
||||
my ($hash, $key, $prop) = @_;
|
||||
|
||||
my @list;
|
||||
my %list;
|
||||
|
||||
return undef unless defined db_get($hash, $key);
|
||||
|
||||
if (defined $prop)
|
||||
{
|
||||
my $value = db_get_prop($hash, $key, $prop);
|
||||
return undef unless defined $value;
|
||||
|
||||
%list = ($prop => $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
%list = db_get_prop($hash, $key);
|
||||
}
|
||||
|
||||
return undef unless scalar keys %list;
|
||||
|
||||
foreach (sort keys %list)
|
||||
{
|
||||
print "$_=$list{$_}\n";
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
=head2 OO Interface
|
||||
|
||||
To add to the confusion, esmith::db has a vestigal object-oriented
|
||||
interface. Use esmith::DB::db instead.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<new>
|
||||
|
||||
my $db = esmith::db->new($db_file)
|
||||
|
||||
Generates a new esmith::db object from the given $db_file
|
||||
|
||||
=cut
|
||||
|
||||
sub new
|
||||
{
|
||||
my($class,$dbname) = @_;
|
||||
|
||||
return $class->open($dbname);
|
||||
}
|
||||
|
||||
|
||||
=item B<open>
|
||||
|
||||
my $db = esmith::db->open($db_name);
|
||||
my $db = esmith::db->open($db_file);
|
||||
|
||||
Takes a database name (or pathname) and opens the named database.
|
||||
The database name form is preferred over the explicit pathname.
|
||||
|
||||
For example
|
||||
|
||||
$db->open( 'configuration' );
|
||||
or
|
||||
$db->open( '/path/to/configuration' );
|
||||
|
||||
=cut
|
||||
|
||||
sub open
|
||||
{
|
||||
my $self = shift;
|
||||
my $dbName = shift;
|
||||
my $class = ref($self) || $self;
|
||||
|
||||
my $dataFile = _db_path($dbName);
|
||||
|
||||
unless ( $esmith::db::REFCOUNT{$dataFile} )
|
||||
{
|
||||
warn "Reading $dataFile into cache\n" if ($esmith::db::DEBUG);
|
||||
|
||||
my %db;
|
||||
tie %db, 'esmith::config', $dataFile;
|
||||
|
||||
$esmith::db::CACHE{$dataFile} = \%db;
|
||||
}
|
||||
|
||||
$self = bless {
|
||||
DBNAME => $dataFile,
|
||||
CACHE => $esmith::db::CACHE{$dataFile}
|
||||
}, $class;
|
||||
|
||||
$esmith::db::REFCOUNT{$dataFile}++;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub DESTROY
|
||||
{
|
||||
my $self = shift;
|
||||
return $self->close();
|
||||
}
|
||||
|
||||
|
||||
=item B<close>
|
||||
|
||||
$db->close;
|
||||
|
||||
Closes this database.
|
||||
|
||||
=cut
|
||||
|
||||
sub close
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
my $dataFile = $self->{'DBNAME'};
|
||||
|
||||
$esmith::db::REFCOUNT{$dataFile}--;
|
||||
|
||||
if ( $esmith::db::REFCOUNT{$dataFile} == 0 )
|
||||
{
|
||||
delete $esmith::db::CACHE{$dataFile};
|
||||
warn "esmith::db::close Closing $dataFile\n" if ($esmith::db::DEBUG);
|
||||
}
|
||||
elsif ( $esmith::db::REFCOUNT{$dataFile} > 0 )
|
||||
{
|
||||
warn "esmith::db::close Not closing $dataFile, references ",
|
||||
$esmith::db::REFCOUNT{$dataFile}, "\n" if ($esmith::db::DEBUG);
|
||||
}
|
||||
else
|
||||
{
|
||||
$esmith::db::REFCOUNT{$dataFile} = 0;
|
||||
warn "esmith::db::close Not closing $dataFile, zero references\n"
|
||||
if ($esmith::db::DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
=item B<set>
|
||||
|
||||
=item B<set_type>
|
||||
|
||||
=item B<set_prop>
|
||||
|
||||
=item B<get>
|
||||
|
||||
=item B<get_type>
|
||||
|
||||
=item B<get_prop>
|
||||
|
||||
=item B<delete>
|
||||
|
||||
=item B<delete_prop>
|
||||
|
||||
These all work like their functional versions (ie. set() == db_set())
|
||||
except it is not necessary to input the %config database.
|
||||
|
||||
=cut
|
||||
|
||||
sub AUTOLOAD
|
||||
{
|
||||
no strict 'refs';
|
||||
|
||||
# fully qualified sub-name stored in $AUTOLOAD package variable
|
||||
$esmith::db::AUTOLOAD =~ /^(.*::)(.*)$/;
|
||||
my ($pkg, $sub) = ($1, $2);
|
||||
|
||||
# use *foo{THING} syntax to check if sub is defined (see perlref)
|
||||
if (defined *{"${pkg}db_${sub}"}{CODE})
|
||||
{
|
||||
my $self = shift;
|
||||
my $cache = $esmith::db::CACHE{$self->{DBNAME}};
|
||||
wantarray ? return (my @p = &{"${pkg}db_${sub}"}($cache, @_))
|
||||
: return (my $p = &{"${pkg}db_${sub}"}($cache, @_));
|
||||
}
|
||||
}
|
||||
|
||||
=begin private
|
||||
|
||||
=head2 Private functions
|
||||
|
||||
=over4
|
||||
|
||||
=item B<_db_hash_to_string>
|
||||
|
||||
my $raw_value = _db_hash_to_string($hashref);
|
||||
|
||||
Takes a reference to a hash and returns a string of pipe "|" delimited
|
||||
pairs suitable for being stored.
|
||||
|
||||
=cut
|
||||
|
||||
sub _db_hash_to_string
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $string = '';
|
||||
|
||||
foreach (sort keys %$hash)
|
||||
{
|
||||
$string .= '|' if length($string);
|
||||
$string .= "$_|";
|
||||
$string .= $$hash{$_} if defined $$hash{$_};
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=item B<_db_string_to_type_and_hash>
|
||||
|
||||
my($type, %properties) = _db_string_to_type_and_hash($raw_value);
|
||||
|
||||
Takes the $raw_value, which is a | delimited string, and spits it up
|
||||
into the $type (the first field) and its %properties (the rest).
|
||||
|
||||
Escaped pipes (\|) are properly ignored as a delimiter.
|
||||
|
||||
=cut
|
||||
|
||||
sub _db_string_to_type_and_hash ($)
|
||||
{
|
||||
my ($arg) = @_;
|
||||
return ('', ()) unless defined $arg;
|
||||
|
||||
# The funky regex is to avoid escaped pipes.
|
||||
# If you specify a negative limit empty trailing fields are omitted.
|
||||
return split(/(?<!\\)\|/, $arg, -1);
|
||||
}
|
||||
|
||||
=item B<_db_path>
|
||||
|
||||
my $dfile = _db_path($database_name);
|
||||
|
||||
Takes a $database_name and returns the $file where it lives.
|
||||
|
||||
=cut
|
||||
|
||||
sub _db_path($)
|
||||
{
|
||||
my ($file) = @_;
|
||||
|
||||
if ($file =~ m:^/:)
|
||||
{
|
||||
return $file;
|
||||
}
|
||||
return "/home/e-smith/db/$file" if (-e "/home/e-smith/db/$file");
|
||||
|
||||
if (-e "/home/e-smith/$file")
|
||||
{
|
||||
warn "Database found in old location /home/e-smith/$file";
|
||||
return "/home/e-smith/$file";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "/home/e-smith/db/$file";
|
||||
}
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=end private
|
||||
|
||||
|
||||
=head1 BUGS and CAVEATS
|
||||
|
||||
keys cannot contain newlines or pipes.
|
||||
|
||||
types and properties cannot contain pipes.
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Mitel Networks Corporation
|
||||
|
||||
For more information, see http://www.e-smith.org/
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
133
root/usr/share/perl5/vendor_perl/esmith/ethernet.pm
Normal file
133
root/usr/share/perl5/vendor_perl/esmith/ethernet.pm
Normal file
@ -0,0 +1,133 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2005 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::ethernet;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
use File::Basename;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::ethernet - Ethernet-related utility routines for e-smith
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
This file documents C<esmith::ethernet> version B<1.4.0>
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::ethernet;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module contains routines for
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head2 probeAdapters()
|
||||
|
||||
Probe for any recognised adapters
|
||||
|
||||
=cut
|
||||
|
||||
sub probeAdapters ()
|
||||
{
|
||||
opendir(my $dh, "/sys/class/net") or die "Couldn't open /sys/class/net: $!";
|
||||
my @nics = grep { $_ !~ m/^\./ } readdir($dh);
|
||||
closedir($dh);
|
||||
my $adapters = '';
|
||||
my $index = 1;
|
||||
foreach my $nic (@nics){
|
||||
# Untaint $nic and makes sure the name looks OK
|
||||
next unless ($nic =~ m/^(\w+[\.:]?\d+)$/);
|
||||
$nic = $1;
|
||||
next if (
|
||||
# skip loopback
|
||||
$nic eq 'lo' ||
|
||||
# skip non links
|
||||
!-l "/sys/class/net/$nic" ||
|
||||
# skip wireless nics
|
||||
-d "/sys/class/net/$nic/wireless" ||
|
||||
-l "/sys/class/net/$nic/phy80211" ||
|
||||
# skip bridges
|
||||
-d "/sys/class/net/$nic/bridge" ||
|
||||
# skip vlans
|
||||
-f "/proc/net/vlan/$nic" ||
|
||||
# skip bonds
|
||||
-d "/sys/class/net/$nic/bonding" ||
|
||||
# skip tun/tap
|
||||
-f "/sys/class/net/$nic/tun_flags" ||
|
||||
# skip dummy
|
||||
-d "/sys/devices/virtual/net/$nic"
|
||||
);
|
||||
# Now we should be left only wth ethernet adapters
|
||||
open HW, "/sys/class/net/$nic/address";
|
||||
my $mac = join("", <HW>);
|
||||
close HW;
|
||||
# Check MAC Addr and untaint it
|
||||
next unless ($mac =~ m/^(([\da-f]{2}:){5}[\da-f]{2})$/i);
|
||||
$mac = $1;
|
||||
# If the device is a slave of a bridge, it's real MAC
|
||||
# address can be found in /proc/net/bonding/bondX
|
||||
if (-l "/sys/class/net/$nic/master"){
|
||||
my $bond = basename (readlink "/sys/class/net/$nic/master");
|
||||
local $/ = '';
|
||||
open SLAVES, "/proc/net/bonding/$bond";
|
||||
my @slaves = <SLAVES>;
|
||||
close SLAVES;
|
||||
my @slaveInfo = grep { /^Slave\ Interface:\ $nic/m } @slaves;
|
||||
foreach (split /\n+/, (join "", @slaveInfo)){
|
||||
$mac = $1 if (/^Permanent\ HW\ addr:\ (.*)$/);
|
||||
}
|
||||
}
|
||||
chomp($mac);
|
||||
my $driver = basename (readlink "/sys/class/net/$nic/device/driver");
|
||||
# Untaint driver name
|
||||
next unless ($driver =~ m/^([\w\-]+)$/);
|
||||
$driver = $1;
|
||||
my $bus = basename (readlink "/sys/class/net/$nic/device/subsystem");
|
||||
my $desc = $nic;
|
||||
if ($bus eq 'pci'){
|
||||
my $dev = basename (readlink "/sys/class/net/$nic/device");
|
||||
# Untaint $dev
|
||||
if ($dev =~ m/^(\d+:\d+:\d+\.\d+)$/){
|
||||
$dev = $1;
|
||||
$desc = `/sbin/lspci -s $dev`;
|
||||
# Extract only description
|
||||
$desc =~ m/^.*:.*:\s+(.*)\s*/;
|
||||
$desc = $1;
|
||||
}
|
||||
}
|
||||
elsif ($bus eq 'virtio'){
|
||||
$desc = 'Virtio Network Device';
|
||||
}
|
||||
# TODO: we should also try to get the description of USB devices
|
||||
$adapters .= "EthernetDriver" . $index++ . "\t" . $driver . "\t" .
|
||||
$mac . "\t" . "\"$desc\"" . "\t" . $nic ."\n";
|
||||
}
|
||||
return $adapters;
|
||||
}
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Return one to make the import process return success.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=AUTHOR
|
||||
|
||||
SME Server Developers <bugs@e-smith.com>
|
||||
|
||||
For more information see http://www.e-smith.org/
|
||||
|
||||
=cut
|
||||
|
220
root/usr/share/perl5/vendor_perl/esmith/event.pm
Normal file
220
root/usr/share/perl5/vendor_perl/esmith/event.pm
Normal file
@ -0,0 +1,220 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2005 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::event;
|
||||
|
||||
use strict;
|
||||
use Exporter;
|
||||
use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );
|
||||
use esmith::Logger;
|
||||
use File::Basename;
|
||||
use File::Temp qw/ :mktemp /;
|
||||
use esmith::ConfigDB;
|
||||
use POSIX;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::event - Routines for handling e-smith events
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::event;
|
||||
|
||||
my $exitcode = event_signal($event, @args);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = sprintf '%d.%03d', q$Revision: 1.16 $ =~ /: (\d+).(\d+)/;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(event_signal);
|
||||
|
||||
our @EXPORT_OK = ();
|
||||
our %EXPORT_TAGS = ();
|
||||
our $return_value = undef;
|
||||
|
||||
tie *LOG, 'esmith::Logger', 'esmith::event';
|
||||
|
||||
sub event_signal
|
||||
{
|
||||
my ($event, @args) = @_;
|
||||
if ($event eq "actions")
|
||||
{
|
||||
warn("'actions' is not a valid event name.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
my $events = "/etc/e-smith/events";
|
||||
my $handlerDir = "$events/$event";
|
||||
|
||||
#------------------------------------------------------------
|
||||
# get event handler filenames
|
||||
#------------------------------------------------------------
|
||||
opendir (DIR, $handlerDir)
|
||||
|| die "Can't open directory $handlerDir\n";
|
||||
|
||||
# Create a hash of handlers (ignore directories),
|
||||
# with value of basename(handler)
|
||||
my %handlers = ();
|
||||
foreach (grep {! -d "$handlerDir/$_"} readdir (DIR))
|
||||
{
|
||||
$handlers{"$handlerDir/$_"} = $_;
|
||||
}
|
||||
|
||||
closedir (DIR);
|
||||
|
||||
# Add generic handlers to list, if their metadata directories
|
||||
# exist
|
||||
$handlers{"$events/actions/generic_template_expand"} = "S05generic_template_expand"
|
||||
if ( -d "$handlerDir/templates2expand");
|
||||
$handlers{"$events/actions/adjust-services"} = "S90adjust-services"
|
||||
if ( -d "$handlerDir/services2adjust");
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Execute all handlers, sending any output to the system log.
|
||||
#
|
||||
# Event handlers are not supposed to generate error messages
|
||||
# under normal conditions, so we do not provide a mechanism
|
||||
# for event handlers to signal errors to the user. Errors can
|
||||
# only be written to the log file.
|
||||
#------------------------------------------------------------
|
||||
print LOG "Processing event: $event @args";
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Run handlers, logging all output.
|
||||
#------------------------------------------------------------
|
||||
|
||||
# assume success
|
||||
my $exitcode = 1;
|
||||
|
||||
foreach my $filename
|
||||
(sort { $handlers{$a} cmp $handlers{$b} } keys %handlers)
|
||||
{
|
||||
my $handler = basename $filename;
|
||||
my $startTime = [gettimeofday];
|
||||
|
||||
my $status = -1;
|
||||
if (-x $filename)
|
||||
{
|
||||
print LOG "Running event handler: $filename";
|
||||
|
||||
unless (($status = _mysystem(\*LOG, $filename, $event, @args)) == 0)
|
||||
{
|
||||
# if any handler fails, the entire event fails
|
||||
$exitcode = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print LOG "Skipping non-executable event handler: $filename";
|
||||
next;
|
||||
}
|
||||
|
||||
my $endTime = [gettimeofday];
|
||||
my $elapsedTime = tv_interval($startTime, $endTime);
|
||||
my $log = "$handler=action|Event|$event|Action|$handler";
|
||||
$log .= "|Start|@$startTime|End|@$endTime|Elapsed|$elapsedTime";
|
||||
$log .= "|Status|$status" if $status;
|
||||
print LOG $log;
|
||||
}
|
||||
|
||||
# Implement event queuing for clustered systems.
|
||||
my $qfifo = "/var/spool/eventq";
|
||||
return $exitcode unless (-e $qfifo);
|
||||
|
||||
# Ensure we aren't called by a cascaded event. We only need to
|
||||
# queue the top-level of such a beast.
|
||||
my $ppid = getppid();
|
||||
open F, "/proc/$ppid/cmdline";
|
||||
my $cmd = <F>;
|
||||
close F;
|
||||
|
||||
unless($cmd =~ "/etc/e-smith/event")
|
||||
{
|
||||
my $fd = POSIX::open($qfifo, &POSIX::O_WRONLY) or return $exitcode;
|
||||
my $argstr = join(" ",$event,@args);
|
||||
$argstr .= "\n";
|
||||
POSIX::write($fd, $argstr, length($argstr));
|
||||
POSIX::close($fd);
|
||||
}
|
||||
|
||||
return $exitcode;
|
||||
}
|
||||
|
||||
sub _mysystem
|
||||
{
|
||||
my ($logger, $filename, $event, @args) = @_;
|
||||
|
||||
my $pid = open(PIPE, "-|");
|
||||
die "Failed to fork: $!\n" unless defined $pid;
|
||||
|
||||
if ($pid)
|
||||
{
|
||||
# Parent
|
||||
while (my $line = <PIPE>)
|
||||
{
|
||||
print $logger $line;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# Child
|
||||
open(STDERR, ">&STDOUT");
|
||||
exec($filename, $event, @args);
|
||||
}
|
||||
close(PIPE);
|
||||
return $?;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Attempt to eval perl handlers for efficiency - not currently used
|
||||
# return 1 on success; 0 on error
|
||||
#------------------------------------------------------------
|
||||
sub _runHandler($)
|
||||
{
|
||||
my ($filename) = @_;
|
||||
|
||||
open(FILE, $filename) || die "Couldn't open $filename: $!";
|
||||
my @lines = <FILE>;
|
||||
close FILE;
|
||||
|
||||
my $string = "";
|
||||
|
||||
unless ( $lines[0] =~ /^#!.*perl/ )
|
||||
{
|
||||
# STDOUT and STDERR are both redirected going to LOG
|
||||
return (system($filename, @ARGV) == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
map { $string .= $_ } @lines;
|
||||
|
||||
print "Eval of $filename...";
|
||||
|
||||
# Override 'exit' in symbol table for handlers
|
||||
sub exit { die "$_[0]\n" };
|
||||
*CORE::GLOBAL::exit = \&esmith::event::exit;
|
||||
|
||||
my $status = eval $string;
|
||||
chomp $@;
|
||||
|
||||
# if $@ is defined, then die or exit was called - use that status
|
||||
$status = $@ if defined $@;
|
||||
|
||||
# for all exit values except 0, assume failure
|
||||
if ($@)
|
||||
{
|
||||
print "Eval of $filename failed: $status\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
print "$status\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
61
root/usr/share/perl5/vendor_perl/esmith/lockfile.pm
Normal file
61
root/usr/share/perl5/vendor_perl/esmith/lockfile.pm
Normal file
@ -0,0 +1,61 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::lockfile;
|
||||
|
||||
use strict;
|
||||
use vars qw($VERSION @ISA @EXPORT_OK);
|
||||
use Exporter;
|
||||
use Fcntl ":flock";
|
||||
use FileHandle;
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT_OK = qw(
|
||||
LockFileOrReturn LockFileOrWait UnlockFile
|
||||
);
|
||||
|
||||
|
||||
sub LockFileOrReturn ($)
|
||||
{
|
||||
# Attempt to lock a file. If the lock fails, return immediately.
|
||||
|
||||
my $lock_file = shift;
|
||||
|
||||
my $FH = new FileHandle;
|
||||
|
||||
$FH->open(">> $lock_file")
|
||||
or die "Cannot open lock file $lock_file for writing: $!.\n";
|
||||
|
||||
flock($FH, LOCK_EX | LOCK_NB) or return 0;
|
||||
|
||||
return $FH;
|
||||
}
|
||||
|
||||
sub LockFileOrWait ($)
|
||||
{
|
||||
# Attempt to lock a file. Wait until the file is available.
|
||||
|
||||
my $lock_file = shift;
|
||||
|
||||
my $FH = new FileHandle;
|
||||
|
||||
$FH->open(">> $lock_file")
|
||||
or die "Cannot open lock file $lock_file for writing: $!.\n";
|
||||
|
||||
flock($FH, LOCK_EX) or return 0;
|
||||
|
||||
return $FH;
|
||||
}
|
||||
|
||||
sub UnlockFile ($)
|
||||
{
|
||||
my $FH = shift;
|
||||
|
||||
flock($FH, LOCK_UN);
|
||||
$FH->close;
|
||||
}
|
||||
|
||||
1;
|
76
root/usr/share/perl5/vendor_perl/esmith/logrotate.pm
Normal file
76
root/usr/share/perl5/vendor_perl/esmith/logrotate.pm
Normal file
@ -0,0 +1,76 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::event;
|
||||
|
||||
use strict;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::logrotate - Routines for handling rotation of log files
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::logrotate;
|
||||
|
||||
NewLogFileSymlink($file);
|
||||
MakeFilenameFromSymlink($file);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=cut
|
||||
|
||||
BEGIN
|
||||
{
|
||||
}
|
||||
|
||||
sub NewLogFileSymlink
|
||||
{
|
||||
my $file = shift;
|
||||
unless (defined $file)
|
||||
{
|
||||
warn("newlogfilesymlink called with no argument");
|
||||
return;
|
||||
}
|
||||
|
||||
my $time = time();
|
||||
|
||||
if (-f "/var/log/${file}")
|
||||
{
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime($time - 1);
|
||||
my $target = sprintf("%s%04d%02d%02d%02d%02d%02d",
|
||||
$file, $year+1900, $mon, $mday, $hour, $min, $sec);
|
||||
move("/var/log/${file}", "/var/log/${target}") or
|
||||
die "Could not move /var/log/${file} to /var/log/${target}";
|
||||
}
|
||||
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime($time);
|
||||
my $target = sprintf("%s%04d%02d%02d%02d%02d%02d",
|
||||
$file, $year+1900, $mon, $mday, $hour, $min, $sec);
|
||||
unlink("/var/log/${file}") or
|
||||
warn "Could not unlink /var/log/${file}";
|
||||
symlink("/var/log/${target}", "/var/log/${file}") or
|
||||
warn "Could not symlink /var/log/${target} to /var/log/${file}";
|
||||
}
|
||||
|
||||
sub MakeFilenameFromSymlink
|
||||
{
|
||||
use File::Basename;
|
||||
my $filename = shift;
|
||||
|
||||
return $filename unless (-l $filename);
|
||||
my $link = readlink $filename;
|
||||
my $directory = dirname($filename);
|
||||
return "${directory}/${link}";
|
||||
}
|
||||
|
||||
END
|
||||
{
|
||||
}
|
||||
|
||||
1;
|
140
root/usr/share/perl5/vendor_perl/esmith/tcpsvd.pm
Normal file
140
root/usr/share/perl5/vendor_perl/esmith/tcpsvd.pm
Normal file
@ -0,0 +1,140 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 2005-2006 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::tcpsvd;
|
||||
use strict;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::tcpsvd - Manage tcpsvd "peers" directory
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::tcpsvd;
|
||||
|
||||
esmith::tcpsvd::configure_peers($service)
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides utility functions for use with tcpsvd from Gerrit
|
||||
Pape's ipsvd package - see http://smarden.org/ipsvd/.
|
||||
|
||||
=cut
|
||||
|
||||
use esmith::NetworksDB;
|
||||
use esmith::ConfigDB;
|
||||
use esmith::util;
|
||||
use esmith::lockfile;
|
||||
use Carp;
|
||||
|
||||
=head2 configure_peers($service [, $peers_directory] )
|
||||
|
||||
configure_peers() configures the "peers" direectory used by tcpsvd for
|
||||
access control and environment maipulation. $service identifies the name
|
||||
of the service managed by supervise or runit. The peers directory (as
|
||||
specified by the optional $peers_directory argument, defaulting to
|
||||
"/var/service/$service/peers") is expected to contain files "0" defining
|
||||
access conditions for public (default) accesss, and "local", defining
|
||||
access conditions for local access. configure_peers() creates a set of
|
||||
symlinks so that tcpsvd uses "local" for all local network access to
|
||||
the service.
|
||||
|
||||
See http://smarden.org/ipsvd/ipsvd-instruct.5.html for all details of
|
||||
the contents of the peers directory.
|
||||
|
||||
=cut
|
||||
|
||||
sub configure_peers
|
||||
{
|
||||
my $service = shift;
|
||||
my $peers = shift || "/var/service/$service/peers";
|
||||
|
||||
unless (opendir(PEERS, $peers))
|
||||
{
|
||||
carp "Cannot read peers directory: $!";
|
||||
return;
|
||||
}
|
||||
|
||||
my $config = esmith::ConfigDB->open;
|
||||
unless ($config)
|
||||
{
|
||||
carp "Could not open config db.";
|
||||
return;
|
||||
}
|
||||
$service = $config->get($service);
|
||||
unless ($service)
|
||||
{
|
||||
carp "No service record for $service";
|
||||
return;
|
||||
}
|
||||
my $access = $service->prop('access') || "localhost";
|
||||
my $nets = esmith::NetworksDB->open;
|
||||
unless ($nets)
|
||||
{
|
||||
carp "Could not open networks db.";
|
||||
return;
|
||||
}
|
||||
|
||||
my $gw = $config->get('GatewayIP');
|
||||
|
||||
# Make a list of local networks, in prefix format
|
||||
my %nets = ($access eq "localhost") ? () :
|
||||
map
|
||||
{
|
||||
$_ => 1,
|
||||
}
|
||||
map
|
||||
{
|
||||
esmith::util::computeAllLocalNetworkPrefixes($_->key, $_->prop('Mask'));
|
||||
}
|
||||
($nets->get_all_by_prop('type', 'network'));
|
||||
|
||||
$nets{'127.0.0.1'} = 1;
|
||||
|
||||
# Setup lock on peers directory while we manipulate it
|
||||
my $lock = esmith::lockfile::LockFileOrWait("$peers/local");
|
||||
|
||||
# Now manage a set of symlinks to the "local" instructions file
|
||||
foreach my $insfile (readdir (PEERS))
|
||||
{
|
||||
next unless -l "$peers/$insfile";
|
||||
if (exists $nets{$insfile})
|
||||
{
|
||||
# Cross this one off the list so that we don't bother creating it
|
||||
delete $nets{$insfile};
|
||||
}
|
||||
else
|
||||
{
|
||||
# We no longer need this entry
|
||||
unlink "$peers/$insfile" or
|
||||
warn "Could not delete access control file $peers/$insfile: $!\n";
|
||||
}
|
||||
}
|
||||
closedir(PEERS);
|
||||
|
||||
foreach my $insfile (keys %nets)
|
||||
{
|
||||
symlink "local", "$peers/$insfile" or
|
||||
warn "Cannot add instructions file for $peers/$insfile: $!\n";
|
||||
}
|
||||
|
||||
if (defined $gw)
|
||||
{
|
||||
# We have a defined gateway address - make sure that the router doesn't have
|
||||
# relay privileges
|
||||
my $gw_ip = $gw->value;
|
||||
unlink "$peers/$gw_ip";
|
||||
symlink "0", "$peers/$gw_ip" or
|
||||
warn "Cannot add instructions file for $peers/$gw_ip: $!\n";
|
||||
}
|
||||
|
||||
# Unlock peers directory
|
||||
$lock && esmith::lockfile::UnlockFile($lock);
|
||||
}
|
||||
|
||||
1;
|
1091
root/usr/share/perl5/vendor_perl/esmith/templates.pm
Normal file
1091
root/usr/share/perl5/vendor_perl/esmith/templates.pm
Normal file
File diff suppressed because it is too large
Load Diff
1413
root/usr/share/perl5/vendor_perl/esmith/util.pm
Normal file
1413
root/usr/share/perl5/vendor_perl/esmith/util.pm
Normal file
File diff suppressed because it is too large
Load Diff
201
root/usr/share/perl5/vendor_perl/esmith/util/link.pm
Normal file
201
root/usr/share/perl5/vendor_perl/esmith/util/link.pm
Normal file
@ -0,0 +1,201 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::util::link;
|
||||
|
||||
use strict;
|
||||
use esmith::ConfigDB;
|
||||
require Exporter;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(getExternalLink);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::util::link - utilities for manipulating network links
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::util::link qw(getExternalLink);
|
||||
|
||||
# wait at most 60 seconds for the link to come up
|
||||
my $timeout = 60;
|
||||
|
||||
# now just get the link
|
||||
if (getExternalLink($timeout))
|
||||
{
|
||||
# the link is up
|
||||
}
|
||||
else
|
||||
{
|
||||
# the link didn't come up
|
||||
}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a collection of generally useful functions for manipulating network
|
||||
links.
|
||||
|
||||
Functions are exported only on request.
|
||||
|
||||
=head2 Functions
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<getExternalLink($timeout)>
|
||||
|
||||
Bring up the external link if it is not already up, waiting at most $timeout
|
||||
seconds. If a $timeout is not specified, it defaults to 300 (5 minutes) for
|
||||
dialup connections. This function can be used for both dialup and dedicated
|
||||
connections, but dedicated connections will always return 1 (true).
|
||||
|
||||
Returns 1 if the external link is already up, or if it comes up within the
|
||||
specfied $timeout period.
|
||||
|
||||
Returns 0 if the external link does not come up within the specified $timeout
|
||||
period.
|
||||
|
||||
=cut
|
||||
|
||||
sub getExternalLink
|
||||
{
|
||||
my $timeout = shift;
|
||||
|
||||
my $configdb = esmith::ConfigDB->open;
|
||||
my $rec = $configdb->get("AccessType");
|
||||
my $accessType = $rec->value;
|
||||
if ($accessType eq "dialup")
|
||||
{
|
||||
return _getDialupLink($timeout);
|
||||
}
|
||||
elsif ($accessType eq "dedicated")
|
||||
{
|
||||
# assume we are up
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
# unknown access type
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
=begin _private
|
||||
|
||||
=item I<getDialupLink($timeout)>
|
||||
|
||||
Bring up the ppp0 link, waiting at most $timeout seconds.
|
||||
|
||||
Returns 1 if the link comes up within the timeout period.
|
||||
|
||||
Returns 0 if the link does not come up within the timeout period.
|
||||
|
||||
The default timeout is 300 seconds.
|
||||
|
||||
=end _private
|
||||
=cut
|
||||
|
||||
sub _getDialupLink
|
||||
{
|
||||
local $|=1;
|
||||
my $timeout = shift(@_) || 300;
|
||||
|
||||
# check for existing ppp link
|
||||
if (-f "/var/run/ppp0.pid")
|
||||
{
|
||||
# already up - return 1
|
||||
return 1;
|
||||
}
|
||||
|
||||
# create a diald monitor channel
|
||||
my $ctlFile = "/etc/diald/diald.ctl";
|
||||
my $monFile = "/tmp/diald.monitor.$$";
|
||||
system('/bin/mknod', $monFile, 'p') == 0
|
||||
or die "Can't mknod $monFile: $!\n";
|
||||
|
||||
# open control channel to diald
|
||||
open (CTL, ">$ctlFile") or die "Can't open $ctlFile: $!\n";
|
||||
|
||||
# set up a child process to monitor the channel
|
||||
|
||||
my $pid = fork;
|
||||
die "Can't fork: $!" unless defined $pid;
|
||||
if ($pid)
|
||||
{
|
||||
# parent
|
||||
|
||||
# if the pipe reader isn't up first, diald will bail, so we open
|
||||
# another pipe writer just to wait for the pipe reader
|
||||
open (MON_W, ">$monFile") or die "can't open $monFile: $!\n";
|
||||
|
||||
# begin monitoring diald status via monitor fifo
|
||||
print CTL "monitor $monFile\n";
|
||||
close CTL;
|
||||
|
||||
# ok, everything is up and ready - send USR1 to diald
|
||||
open (PID, "</var/run/diald.pid")
|
||||
or die "can't open diald pidfile: $!\n";
|
||||
my $dialdPid = <PID>;
|
||||
close PID;
|
||||
kill 'USR1', $dialdPid;
|
||||
|
||||
# Wait for the child to exit, then check for link again
|
||||
waitpid($pid, 0);
|
||||
close MON_W;
|
||||
}
|
||||
else
|
||||
{
|
||||
# child
|
||||
|
||||
open (MON, "<$monFile") or die "Can't open $monFile: $!\n";
|
||||
|
||||
# Parse the diald monitor stream for state information
|
||||
my $state = "";
|
||||
my $elapsed = 0;
|
||||
while (<MON>)
|
||||
{
|
||||
# lucky us; diald sends a STATUS msg every second
|
||||
if (/^STATUS/)
|
||||
{
|
||||
$elapsed++;
|
||||
if ($elapsed >= $timeout)
|
||||
{
|
||||
# time is up - exit with failure code
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
elsif (/^STATE/)
|
||||
{
|
||||
$state = $_;
|
||||
}
|
||||
elsif ($state eq 'UP')
|
||||
{
|
||||
# the link is up - exit with success code
|
||||
exit 0;
|
||||
}
|
||||
next;
|
||||
}
|
||||
close MON;
|
||||
# end child
|
||||
}
|
||||
|
||||
# parent (cont)
|
||||
|
||||
unlink $monFile;
|
||||
|
||||
if ($? == 0 || -f "/var/run/ppp0.pid")
|
||||
{
|
||||
# ok we're up - return 1 (true)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
# out of time - return 0 (false)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
312
root/usr/share/perl5/vendor_perl/esmith/util/network.pm
Normal file
312
root/usr/share/perl5/vendor_perl/esmith/util/network.pm
Normal file
@ -0,0 +1,312 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::util::network;
|
||||
|
||||
use strict;
|
||||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(isValidIP cleanIP isValidPort cmpIP);
|
||||
our %EXPORT_TAGS = (
|
||||
all => [qw(isValidIP cleanIP isValidPort cmpIP)]
|
||||
);
|
||||
|
||||
use Net::IPv4Addr qw(:all);
|
||||
use Mail::RFC822::Address;
|
||||
use esmith::AccountsDB;
|
||||
|
||||
use constant TRUE => 1;
|
||||
use constant FALSE => 0;
|
||||
|
||||
=for testing
|
||||
use_ok('esmith::util::network');
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::util::network - miscellaneous network utilities
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::util::network qw(the functions you want);
|
||||
|
||||
my $ip = cleanIP($orig_ip);
|
||||
my $is_valid = isValidIP($ip);
|
||||
my $is_valid = isValidPort($port);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a collection of generally useful functions for working with IP
|
||||
addresses.
|
||||
|
||||
Functions are exported only on request.
|
||||
|
||||
=head2 Functions
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<cleanIP>
|
||||
|
||||
my $ip = cleanIP($orig_ip);
|
||||
|
||||
If the $orig_ip is valid it will be cleaned up into a cannonical form,
|
||||
stripping any padding zeros and such.
|
||||
|
||||
=begin testing
|
||||
|
||||
use esmith::util::network qw(cleanIP);
|
||||
|
||||
my %ips = (
|
||||
'000.000.000.000' => '0.0.0.0',
|
||||
'0.0.0.0' => '0.0.0.0',
|
||||
'001.2.003.4' => '1.2.3.4',
|
||||
'100.2.3.4' => '100.2.3.4',
|
||||
'10.13.14.015' => '10.13.14.15',
|
||||
'10.33.15.109' => '10.33.15.109',
|
||||
'1.2.3.4.5' => ''
|
||||
);
|
||||
|
||||
while( my($ip, $cleanip) = each %ips ) {
|
||||
is( cleanIP($ip), $cleanip, "cleanIP($ip)" );
|
||||
}
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub cleanIP {
|
||||
my $ip = shift;
|
||||
|
||||
return '' unless isValidIP($ip);
|
||||
$ip =~ s/\b0+(\d+)/$1/g;
|
||||
|
||||
return isValidIP($ip) ? $ip : '';
|
||||
}
|
||||
|
||||
=item I<isValidIP>
|
||||
|
||||
my $is_valid = isValidIP($ip);
|
||||
|
||||
Returns the IP given if $ip is a properly formatted IP address, undef otherwise.
|
||||
|
||||
=begin testing
|
||||
|
||||
use esmith::util::network qw(isValidIP);
|
||||
|
||||
my @goodIPs = qw(1.2.3.4
|
||||
0.0.0.0
|
||||
255.255.255.255
|
||||
001.002.003.004
|
||||
1.32.123.213
|
||||
192.168.0.3
|
||||
02.19.090.19
|
||||
);
|
||||
foreach my $ip (@goodIPs) {
|
||||
ok( isValidIP($ip), "valid $ip");
|
||||
}
|
||||
|
||||
my @badIPs = qw(256.3.2.4
|
||||
-1.39.9.23
|
||||
0
|
||||
1
|
||||
255.255.255.255.0
|
||||
239..19.23.12
|
||||
1.2.3.4.
|
||||
foo.bar.com
|
||||
);
|
||||
|
||||
foreach my $ip (@badIPs) {
|
||||
ok( !isValidIP($ip), "invalid $ip");
|
||||
}
|
||||
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub isValidIP($)
|
||||
{
|
||||
my ($string) = @_;
|
||||
return unless defined ipv4_chkip($string);
|
||||
return $string eq ipv4_chkip($string);
|
||||
}
|
||||
|
||||
=item I<isValidPort>
|
||||
|
||||
my $is_valid = isValidPort($port);
|
||||
|
||||
Returns true if $port is a properly formatted port, false otherwise.
|
||||
|
||||
=begin testing
|
||||
|
||||
@badports = (98765434, -183, 0, 'bad port', 'a');
|
||||
@goodports = (67, 23, 1, 54736);
|
||||
|
||||
foreach $port (@badports) {
|
||||
isnt(esmith::util::network::isValidPort($port), 1);
|
||||
}
|
||||
foreach $port (@goodports) {
|
||||
is(esmith::util::network::isValidPort($port), 1);
|
||||
}
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub isValidPort($)
|
||||
{
|
||||
my $port = shift;
|
||||
|
||||
return FALSE unless defined $port;
|
||||
|
||||
if (($port =~ /^\d+$/) &&
|
||||
($port > 0) &&
|
||||
($port < 65536))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
=item I<cmpIP>
|
||||
|
||||
Performs a cmp operation on two IP addresses.
|
||||
|
||||
=begin testing
|
||||
|
||||
$ip1 = '24.123.212.87';
|
||||
$ip2 = '240.34.216.12';
|
||||
|
||||
is(esmith::util::network::cmpIP($ip1, $ip2), -1);
|
||||
is(esmith::util::network::cmpIP($ip2, $ip1), 1);
|
||||
is(esmith::util::network::cmpIP($ip1, $ip1), 0);
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub cmpIP($$)
|
||||
{
|
||||
my $ip1 = ipv4_chkip(shift);
|
||||
my $ip2 = ipv4_chkip(shift);
|
||||
|
||||
die "The first argument is not a valid IP address.\n" if not $ip1;
|
||||
die "The second argument is not a valid IP address.\n" if not $ip2;
|
||||
|
||||
my @ip1cmps = split /\./, $ip1;
|
||||
my @ip2cmps = split /\./, $ip2;
|
||||
|
||||
while (@ip1cmps)
|
||||
{
|
||||
my $cmp1 = shift @ip1cmps;
|
||||
my $cmp2 = shift @ip2cmps;
|
||||
|
||||
my $cmp = $cmp1 <=> $cmp2;
|
||||
return $cmp if $cmp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
=item I<isValidHostname>
|
||||
|
||||
This function returns true if it is passed a valid RFC 921 hostname,
|
||||
false otherwise.
|
||||
|
||||
=cut
|
||||
|
||||
sub isValidHostname
|
||||
{
|
||||
my $host_or_ip = shift;
|
||||
|
||||
unless (isValidIP($host_or_ip))
|
||||
{
|
||||
# It's not an IP address. Does it look like a hostname?
|
||||
# FIXME: We could do a DNS lookup to be sure.
|
||||
# (See RFC 921, "Domain Name System Implementation Schedule,"
|
||||
# FIXME: Put this in a library.
|
||||
unless ($host_or_ip =~ m{
|
||||
# Must begin with an alphabetical character...
|
||||
^[a-z]
|
||||
# optionally followed by zero or more alphabetic characters,
|
||||
# hyphens, periods and numbers...
|
||||
[-a-z.0-9]*
|
||||
(
|
||||
# followed by one period...
|
||||
\.
|
||||
# and a repeat of the first pattern
|
||||
[a-z]
|
||||
[-a-z.0-9]*
|
||||
)+
|
||||
# which we can repeat one or more times, to the end of the
|
||||
# string.
|
||||
$
|
||||
# Case insensitive.
|
||||
}ix)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
=item I<isValidEmail>
|
||||
|
||||
This validation function validates an email address, using the
|
||||
Mail::RFC822::Address module. Additionally, by default, it permits a local
|
||||
address instead of a fully-qualified remote address, even checking the
|
||||
existence of said user in the accounts db.
|
||||
|
||||
If you don't wish to permit local addresses, pass the permitlocal option as
|
||||
false.
|
||||
|
||||
ie. esmith::util::isValidEmail($address, { permitlocal => 0 })
|
||||
|
||||
=cut
|
||||
|
||||
sub isValidEmail
|
||||
{
|
||||
my $address = shift;
|
||||
my $hashref = shift || {};
|
||||
my %defaults = ( permitlocal => 1 );
|
||||
my %options = (%defaults, %$hashref);
|
||||
|
||||
if (Mail::RFC822::Address::valid($address))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
# Permit a local address.
|
||||
if ($address =~ /^[a-zA-Z][a-zA-Z0-9\._\-]*$/)
|
||||
{
|
||||
# Exception for 'admin' user. FIXME - I'd rather not hardcode this,
|
||||
# but we can't permit email to all system users.
|
||||
return TRUE if $address eq 'admin';
|
||||
# Make sure the user exists.
|
||||
my $accountsdb = esmith::AccountsDB->open_ro;
|
||||
my $user = $accountsdb->get($address) || '';
|
||||
unless (($user) && ($user->prop('type') eq 'user'))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Mitel Networks Corp.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
215
root/usr/share/perl5/vendor_perl/esmith/util/system.pm
Normal file
215
root/usr/share/perl5/vendor_perl/esmith/util/system.pm
Normal file
@ -0,0 +1,215 @@
|
||||
#----------------------------------------------------------------------
|
||||
# Copyright 1999-2003 Mitel Networks Corporation
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the same terms as Perl itself.
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::util::system;
|
||||
|
||||
use strict;
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
|
||||
our @EXPORT_OK = qw(killall rsync rsync_ssh);
|
||||
|
||||
=for testing
|
||||
use_ok('esmith::util::system', 'killall', 'rsync', 'rsync_ssh');
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::util::system - replacements/wrappers for system() commands
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::util::system qw(killall rsync rsync_ssh);
|
||||
|
||||
killall($signal, @commands);
|
||||
rsync($src, $dest, @options);
|
||||
rsync_ssh($src, $dest, $user, $ident, \@rsync_opts, \@ssh_opts);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is for common functions that would normally require a system(...)
|
||||
command. Makes things easier to document, test and upgrade.
|
||||
|
||||
If you find yourself writing a system() command, consider putting it
|
||||
in here.
|
||||
|
||||
|
||||
=head2 Functions
|
||||
|
||||
These may be pure Perl functions or they may well just be wrappers
|
||||
around system() commands.
|
||||
|
||||
Each can be imported on request.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<killall>
|
||||
|
||||
my $killed_something = killall($signal, @commands);
|
||||
|
||||
Sends a $signal to all of the named @commands. $signal can be
|
||||
specified by name or number (so 1 or HUP for example, names are
|
||||
prefered).
|
||||
|
||||
Returns true if something was killed, false otherwise.
|
||||
|
||||
=begin testing
|
||||
|
||||
open(SCRATCH, ">scratch.exe") || die $!;
|
||||
|
||||
# XXX Irritating perl bug ends POD processing if it sees /^#!.*perl/
|
||||
print SCRATCH sprintf <<'ENDING', '/usr/bin/perl';
|
||||
#!%s -w
|
||||
|
||||
sleep 99;
|
||||
ENDING
|
||||
|
||||
close SCRATCH;
|
||||
|
||||
END { unlink 'scratch.exe', 'scratch.out' }
|
||||
|
||||
chmod 0755, 'scratch.exe' || die $!;
|
||||
my $pid = open(SCRATCH, "./scratch.exe |");
|
||||
ok( $pid, 'scratch program started ok' );
|
||||
|
||||
ok( killall('USR1', 'scratch.exe'), 'killall returned properly' );
|
||||
close SCRATCH; # so scratch.exe responds to the signal and exits
|
||||
|
||||
is( kill(9, $pid), 0, 'killall worked' );
|
||||
|
||||
# I can't actually think of a way to explicitly check this but it
|
||||
# will make noise if it doesn't work.
|
||||
ok( !killall('USR1', 'I_dont_exist_nope'),
|
||||
'returned properly for killing nothing' );
|
||||
ok( 1, 'killall is quiet when nothing is killed' );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
sub killall {
|
||||
my($signal, @commands) = @_;
|
||||
|
||||
warn "You don't need a - on the signal" if $signal =~ /^-/;
|
||||
|
||||
my $killed_something =
|
||||
system('/usr/bin/killall', '-q', "-$signal", @commands);
|
||||
|
||||
return !$killed_something;
|
||||
}
|
||||
|
||||
=back
|
||||
|
||||
=item B<rsync>
|
||||
|
||||
my $success = rsync($source, $destination, @options);
|
||||
|
||||
rsyncs the $source file or directory to the $destination. Any
|
||||
@options are direct options to the rsync command.
|
||||
|
||||
rsync will be run --quiet by default.
|
||||
|
||||
Returns true if the rsync succeeds, false otherwise.
|
||||
|
||||
=begin testing
|
||||
|
||||
use File::Compare;
|
||||
my $src = '10e-smith-lib/db.t';
|
||||
my $dest = '10e-smith-lib/db.t.copy';
|
||||
rsync($src, $dest);
|
||||
END { unlink $dest }
|
||||
|
||||
ok( -e $dest );
|
||||
ok( compare($src, $dest) == 0, 'basic rsync copy' );
|
||||
|
||||
open(DEST, ">$dest" ) || die $!;
|
||||
print DEST "Fooble\n";
|
||||
close DEST;
|
||||
|
||||
# rsync in update-only mode. $dest is newer than $src and shouldn't
|
||||
# be updated.
|
||||
rsync($src, $dest, qw(--update));
|
||||
|
||||
ok( compare($src, $dest) == 1, 'rsync, update only' );
|
||||
|
||||
open(DEST, "$dest") || die $!;
|
||||
my $data = join '', <DEST>;
|
||||
close DEST;
|
||||
|
||||
is( $data, "Fooble\n" );
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
our $RSYNC_CMD = '/usr/bin/rsync';
|
||||
sub rsync {
|
||||
my($src, $dest, @options) = @_;
|
||||
|
||||
push @options, '--quiet';
|
||||
return !system($RSYNC_CMD, @options, $src, $dest);
|
||||
}
|
||||
|
||||
=item B<rsync_ssh>
|
||||
|
||||
my $success = rsync_ssh($src, $dest, $user, $ident, \@rsync_opts,
|
||||
\@ssh_opts);
|
||||
|
||||
Like rsync() except it uses ssh. A typical call might be:
|
||||
|
||||
rsync_ssh('some.host:', 'some/file', 'someuser', 'some/.ssh/identity',
|
||||
[qw(--archive --delete)]);
|
||||
|
||||
=begin testing
|
||||
|
||||
use File::Compare;
|
||||
my $src = '10e-smith-lib/db.t';
|
||||
my $dest = '10e-smith-lib/db.t.copy';
|
||||
|
||||
unlink $dest;
|
||||
END { unlink $dest }
|
||||
|
||||
no warnings 'once';
|
||||
my @args;
|
||||
my $real_rsync = \&esmith::util::system::rsync;
|
||||
local *esmith::util::system::rsync = sub {
|
||||
@args = @_;
|
||||
|
||||
pop @_;
|
||||
$real_rsync->(@_);
|
||||
};
|
||||
|
||||
rsync_ssh($src, $dest, 'someone', 'some/ident', [qw(--update)], [qw(-C)]);
|
||||
ok( -e $dest );
|
||||
ok( compare($src, $dest) == 0 );
|
||||
|
||||
is($args[0], $src );
|
||||
is($args[1], $dest );
|
||||
is($args[2], '--update' );
|
||||
is($args[3], "-e $esmith::util::system::SSH_CMD -l someone -i some/ident -C");
|
||||
|
||||
=end testing
|
||||
|
||||
=cut
|
||||
|
||||
our $SSH_CMD = '/usr/bin/ssh';
|
||||
sub rsync_ssh {
|
||||
my($src, $dest, $user, $ident, $rsync_opts, $ssh_opts) = @_;
|
||||
|
||||
$ssh_opts ||= [];
|
||||
my $ssh_opt = join ' ', ('-e', $SSH_CMD, '-l', $user, '-i', $ident,
|
||||
@$ssh_opts);
|
||||
|
||||
return rsync($src, $dest, @$rsync_opts, $ssh_opt);
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Mitel Networks Corporation
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
Loading…
Reference in New Issue
Block a user