├── .gitignore ├── ACKNOWLEDGEMENTS ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── Makefile ├── NEWS ├── NOTICE ├── README.md ├── TODO ├── build ├── build.sh ├── dist.sh ├── install.sh └── mkspec.sh ├── config.mk ├── specfile.in └── src ├── sf_cfg.sh ├── sf_db.sh ├── sf_disk.sh ├── sf_error.sh ├── sf_file.sh ├── sf_fs.sh ├── sf_ip4.sh ├── sf_kernel.sh ├── sf_lvm.sh ├── sf_misc.sh ├── sf_msg.sh ├── sf_net.sh ├── sf_os.sh ├── sf_pulp.sh ├── sf_save.sh ├── sf_soft.sh ├── sf_svc.sh ├── sf_time.sh ├── sf_tmp.sh ├── sf_tune.sh ├── sf_user.sh ├── sf_vm.sh └── sysfunc.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.sh.ppc 2 | *.tar.gz 3 | *.rpm 4 | specfile 5 | -------------------------------------------------------------------------------- /ACKNOWLEDGEMENTS: -------------------------------------------------------------------------------- 1 | 2 | ============================================================================== 3 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | This software was written by Francois Laupretre 2 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | Changelog information is available at : 2 | 3 | http://sysfunc.hg.sourceforge.net/hgweb/sysfunc/sysfunc/log 4 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Please use the documentation available at : 2 | 3 | http://sysfunc.tekwire.net 4 | 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #===================================== 20 | # For a non-default install directory, run 'make ... INSTALL_DIR=' 21 | #===================================== 22 | 23 | SOFTWARE_NAME = sysfunc 24 | 25 | include config.mk 26 | 27 | TGZ_PREFIX = $(SOFTWARE_NAME)-$(SOFTWARE_VERSION) 28 | TGZ_FILE = $(TGZ_PREFIX).tar.gz 29 | TGZ_PATTERN=$(SOFTWARE_NAME)-*.tar.gz 30 | RPM_PATTERN=$(SOFTWARE_NAME)-*.noarch.rpm 31 | 32 | #===================================== 33 | 34 | all: ppc 35 | 36 | .PHONY: ppc clean tgz install all rpm 37 | 38 | ppc: $(SOFTWARE_NAME).sh.ppc 39 | 40 | $(SOFTWARE_NAME).sh.ppc: 41 | chmod +x build/build.sh 42 | build/build.sh "$(SOFTWARE_VERSION)" "$(INSTALL_DIR)" 43 | 44 | install: $(SOFTWARE_NAME).sh.ppc 45 | chmod +x build/install.sh 46 | build/install.sh $(INSTALL_DIR) 47 | 48 | specfile: specfile.in 49 | chmod +x build/mkspec.sh 50 | build/mkspec.sh "$(SOFTWARE_VERSION)" "$(INSTALL_DIR)" 51 | 52 | tgz: $(TGZ_FILE) 53 | 54 | $(TGZ_FILE): clean 55 | /bin/rm -rf /tmp/$(TGZ_PREFIX) 56 | mkdir /tmp/$(TGZ_PREFIX) 57 | tar cf - . | ( cd /tmp/$(TGZ_PREFIX) ; tar xpf - ) 58 | ( cd /tmp ; rm -rf $(TGZ_PREFIX)/.git ; tar cf - ./$(TGZ_PREFIX) ) | gzip >$(TGZ_FILE) 59 | /bin/rm -rf /tmp/$(TGZ_PREFIX) 60 | 61 | rpm: tgz specfile 62 | chmod +x build/dist.sh 63 | /bin/rm -rf $(HOME)/rpmbuild/RPMS/noarch/$(RPM_PATTERN) 64 | rpmbuild -bb --define="_sourcedir `pwd`" --define="dist `build/dist.sh`" specfile 65 | mv -f $(HOME)/rpmbuild/RPMS/noarch/$(RPM_PATTERN) . 66 | /bin/rm -rf $(HOME)/rpmbuild/BUILD/$(TGZ_PREFIX) 67 | 68 | clean: 69 | /bin/rm -rf $(SOFTWARE_NAME).sh.ppc specfile $(TGZ_PATTERN) $(RPM_PATTERN) 70 | 71 | #============================================================================ 72 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Please use the documentation available at : 2 | 3 | http://sysfunc.tekwire.net 4 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Sysfunc 2 | Copyright 2008-2011 Francois Laupretre 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://stand-with-ukraine.pp.ua) 2 | 3 | **SysFunc** is a shell library primarily intended for Unix sysadmins. 4 | 5 | It provides a set of portable shell functions including features such as : 6 | 7 | - file copy, 8 | - symbolic link management, 9 | - file/directory deletion, 10 | - user/group management, 11 | - data block or line replacement in a file, 12 | - commenting/uncommenting a line, 13 | - service management, 14 | - volume group/logical volume/file system creation 15 | - and much more... 16 | 17 | Up to version 2.2.10, the library was tested on Linux, Solaris, HP-UX, and AIX. Actually, it 18 | should run on any Unix/Linux system. 19 | 20 | Versions 2.2.11 and up were tested on bash only, as I don't use other environments anymore. Anyway, 21 | issues and PR for non-bash shells are still welcome. 22 | 23 | Note that, unfortunately, the code was not developed with the 'set -e' (fail on 1st failing command) 24 | nor 'set -u' (fail on unbound variable) modes activated. I am currently fixing these failures when I 25 | meet them but I cannot guarantee a correct behavior when one of those modes is active. 26 | 27 | The project home page is [http://sysfunc.tekwire.net](http://sysfunc.tekwire.net). 28 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Please use the issue manager at : http://github.com/flaupretre/sysfunc/issues 2 | -------------------------------------------------------------------------------- /build/build.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | 20 | CMD=`basename $0` 21 | cd `dirname $0`/.. 22 | BASE_DIR=`/bin/pwd` 23 | 24 | SOFTWARE_VERSION="$1" 25 | INSTALL_DIR="$2" 26 | 27 | export BASE_DIR SOFTWARE_VERSION INSTALL_DIR 28 | 29 | 30 | #==== MAIN ==== 31 | #-- Aggregate source files to preprocessed file 32 | 33 | cd $BASE_DIR 34 | 35 | ( 36 | cd src 37 | for i in sf_*.sh ; do 38 | echo "#>>==== Entering $i" 39 | cat $i 40 | echo # force newline at EOF 41 | echo "#<<==== Exiting $i" 42 | done 43 | cat sysfunc.sh 44 | cd .. 45 | ) | sed -e "s,%INSTALL_DIR%,$INSTALL_DIR,g" \ 46 | -e "s,%SOFTWARE_VERSION%,$SOFTWARE_VERSION,g" >sysfunc.sh.ppc 47 | -------------------------------------------------------------------------------- /build/dist.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Compute and display the 'dist' variable to transmit to rpm 3 | # 4 | # This script is needed because, unlike RHEL 6, RHEL 4 & 5 don't provide 5 | # this value in their rpm build system 6 | # 7 | #============================================================================ 8 | 9 | . sysfunc 10 | 11 | if [ -f /etc/redhat-release ] ; then 12 | echo ".el`sed 's/^.* release \(.\).*$/\1/' 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | # $INSTALL_ROOT variable can be set by the calling environment and is optional. 20 | # If not set, everything will be installed relative to '/'. 21 | 22 | #---------- 23 | 24 | CMD=`basename $0` 25 | cd `dirname $0`/.. 26 | BASE_DIR=`/bin/pwd` 27 | 28 | INSTALL_TARGET_DIR="$1" 29 | INSTALL_DIR="$INSTALL_ROOT$1" 30 | 31 | export BASE_DIR INSTALL_DIR 32 | 33 | cd $BASE_DIR 34 | 35 | #-- Re-create target tree and copy base files 36 | 37 | [ -d $INSTALL_DIR ] || mkdir -p $INSTALL_DIR 38 | 39 | rm -rf $INSTALL_DIR/* 40 | 41 | cp sysfunc.sh.ppc $INSTALL_DIR/sysfunc.sh 42 | chmod 555 $INSTALL_DIR/sysfunc.sh 43 | 44 | [ -d $INSTALL_ROOT/usr/bin ] || mkdir -p $INSTALL_ROOT/usr/bin 45 | /bin/rm -rf $INSTALL_ROOT/usr/bin/sysfunc 46 | ln -s $INSTALL_TARGET_DIR/sysfunc.sh $INSTALL_ROOT/usr/bin/sysfunc 47 | /bin/rm -rf $INSTALL_ROOT/usr/bin/sysfunc.sh 48 | ln -s $INSTALL_TARGET_DIR/sysfunc.sh $INSTALL_ROOT/usr/bin/sysfunc.sh 49 | 50 | ############################################################################### 51 | -------------------------------------------------------------------------------- /build/mkspec.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | CMD=`basename $0` 20 | cd `dirname $0`/.. 21 | SOFTWARE_VERSION="$1" 22 | INSTALL_DIR="$2" 23 | 24 | export SOFTWARE_VERSION INSTALL_DIR 25 | 26 | sed -e "s,%SOFTWARE_VERSION%,$SOFTWARE_VERSION,g" \ 27 | -e "s,%INSTALL_DIR%,$INSTALL_DIR,g" \ 28 | specfile 29 | 30 | ############################################################################### 31 | -------------------------------------------------------------------------------- /config.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | INSTALL_DIR = /opt/sysfunc 20 | 21 | SOFTWARE_VERSION = 2.2.12 22 | 23 | #============================================================================ 24 | -------------------------------------------------------------------------------- /specfile.in: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | Name: sysfunc 20 | Version: %SOFTWARE_VERSION% 21 | Release: 1%{?dist} 22 | Summary: System utility shell functions 23 | License: GNU LESSER GENERAL PUBLIC LICENSE, Version 3 24 | Group: System Environment/Configuration 25 | Source: %{name}-%{version}.tar.gz 26 | BuildArch: noarch 27 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release} 28 | Prefix: %INSTALL_DIR% 29 | %description 30 | System utility shell functions 31 | 32 | %prep 33 | %setup -q 34 | 35 | %build 36 | make 37 | 38 | %install 39 | INSTALL_ROOT=$RPM_BUILD_ROOT make install INSTALL_DIR=%{prefix} 40 | 41 | %clean 42 | rm -rf $RPM_BUILD_ROOT 43 | 44 | %files 45 | %defattr(-,root,root) 46 | %{prefix} 47 | /usr/bin/sysfunc 48 | /usr/bin/sysfunc.sh 49 | -------------------------------------------------------------------------------- /src/sf_cfg.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | 20 | #============================================================================= 21 | # Section: Configuration parameters 22 | #============================================================================= 23 | 24 | ##---------------------------------------------------------------------------- 25 | # Run an 'sf_db' command on default values 26 | # 27 | # Args: 28 | # $*: An sf_db command along with its arguments 29 | # Returns: 0 30 | # Displays: nothing 31 | #----------------------------------------------------------------------------- 32 | 33 | function _sf_cfg_def_exec 34 | { 35 | cat $SF_CFG_DEF_DIR/* 2>/dev/null | SF_DB_PATH='' $* 36 | } 37 | 38 | ##---------------------------------------------------------------------------- 39 | # Check that the given parameter is a valid one 40 | # 41 | # Actually, parameter is valid if a default value is registered for this param. 42 | # 43 | # Args: 44 | # $1: Parameter 45 | # Returns: 0 if parameter exists, =!0 if not 46 | # Displays: nothing 47 | #----------------------------------------------------------------------------- 48 | 49 | function sf_cfg_exists 50 | { 51 | _sf_cfg_def_exec sf_db_isset "$1" 52 | } 53 | 54 | ##---------------------------------------------------------------------------- 55 | # Check if a parameter is explicitely set (not default) 56 | # 57 | # Args: 58 | # $1: Parameter 59 | # Returns: 0 if parameter is set (not default value), 1 if not set 60 | # Displays: nothing 61 | #----------------------------------------------------------------------------- 62 | 63 | function sf_cfg_isset 64 | { 65 | sf_cfg_check "$1" 66 | sf_db_isset "$1" 67 | } 68 | 69 | ##---------------------------------------------------------------------------- 70 | # Aborts if the given parameter is not a valid one 71 | # 72 | # Args: 73 | # $1: Parameter 74 | # Returns: Only if parameter is valid 75 | # Displays: If parameter is invalid, aborts with error message 76 | #----------------------------------------------------------------------------- 77 | 78 | function sf_cfg_check 79 | { 80 | sf_cfg_exists "$1" || sf_fatal "Invalid configuration parameter: $1" 81 | } 82 | 83 | ##---------------------------------------------------------------------------- 84 | # List defined configuration parameters 85 | # 86 | # Args: None 87 | # Returns: 0 88 | # Displays: Defined parameters, one by line 89 | #----------------------------------------------------------------------------- 90 | 91 | function sf_cfg_list 92 | { 93 | _sf_cfg_def_exec sf_db_list 94 | } 95 | 96 | ##---------------------------------------------------------------------------- 97 | # Get parameter default value 98 | # 99 | # Args: 100 | # $1: Parameter 101 | # Returns: Only if parameter is valid 102 | # Displays: Parameter default value 103 | #----------------------------------------------------------------------------- 104 | 105 | function sf_cfg_get_default 106 | { 107 | _sf_cfg_def_exec sf_db_get "$1" 108 | } 109 | 110 | ##---------------------------------------------------------------------------- 111 | # Get parameter value 112 | # 113 | # If parameter is set, returns set value. Else, returns default value. 114 | # 115 | # Args: 116 | # $1: Parameter 117 | # Returns: Only if parameter is valid 118 | # Displays: Parameter value 119 | #----------------------------------------------------------------------------- 120 | 121 | function sf_cfg_get 122 | { 123 | typeset var 124 | var=$1 125 | sf_cfg_check "$var" 126 | 127 | if sf_db_isset "$var" ; then 128 | sf_db_get "$var" 129 | else 130 | sf_cfg_get_default "$var" 131 | fi 132 | } 133 | 134 | ##---------------------------------------------------------------------------- 135 | # Set an explicit parameter value 136 | # 137 | # To reset a parameter to its default value, see [function:cfg_unset] 138 | # 139 | # Args: 140 | # $1: Parameter 141 | # $2: Value 142 | # Returns: Only if parameter is valid 143 | # Displays: Nothing 144 | #----------------------------------------------------------------------------- 145 | 146 | function sf_cfg_set 147 | { 148 | sf_cfg_check "$1" 149 | sf_db_set "$1" "$2" 150 | } 151 | 152 | ##---------------------------------------------------------------------------- 153 | # Reset a parameter to its default value 154 | # 155 | # Args: 156 | # $1: Parameter 157 | # Returns: Only if parameter is valid 158 | # Displays: Nothing 159 | #----------------------------------------------------------------------------- 160 | 161 | function sf_cfg_unset 162 | { 163 | sf_cfg_check "$1" 164 | sf_db_unset "$1" 165 | } 166 | 167 | ##---------------------------------------------------------------------------- 168 | # Display the parameters along with their default and actual values 169 | # 170 | # Args: None 171 | # Returns: 0 172 | # Displays: Parameters 173 | #----------------------------------------------------------------------------- 174 | 175 | function sf_cfg_display 176 | { 177 | typeset var value enhanced normal prefix 178 | 179 | enhanced="`tput rev`" 180 | normal="`tput sgr0`" 181 | 182 | echo "Name Actual value Default value" 183 | echo "----------------------- -------------------- --------------------" 184 | sf_cfg_list | while read var ; do 185 | value="`sf_cfg_get $var`" 186 | prefix='' 187 | sf_db_isset "$var" && prefix="$enhanced" 188 | printf "%-23s $prefix%-20s$normal %-20s\n" $var "$value" \ 189 | "`sf_cfg_get_default $var`" 190 | done 191 | } 192 | 193 | ##---------------------------------------------------------------------------- 194 | # Display parameters with actual value in raw format 195 | # 196 | # Format of each line : 197 | # 198 | # The output of this function does not allow to say if a value is the default 199 | # one or not. 200 | # 201 | # Args: None 202 | # Returns: 0 203 | # Displays: List of '' lines 204 | #----------------------------------------------------------------------------- 205 | 206 | function sf_cfg_dump 207 | { 208 | typeset var value 209 | 210 | sf_cfg_list | while read var ; do 211 | echo "$var `sf_cfg_get $var`" 212 | done 213 | } 214 | 215 | ##---------------------------------------------------------------------------- 216 | # Display parameter information 217 | # 218 | # Args: 219 | # $*: Optional. List of parameters. If empty, display every defined parameters 220 | # Returns: 0 221 | # Displays: Parameters and related information 222 | #----------------------------------------------------------------------------- 223 | 224 | function sf_cfg_info 225 | { 226 | typeset tmp var 227 | #tmp=`sf_tmpfile` 228 | tmp=/tmp/az 229 | 230 | [ -n "$1" ] || set -- `sf_cfg_list` 231 | for var ; do 232 | >$tmp 233 | #set -x 234 | cat $SF_CFG_DEF_DIR/* 2>/dev/null | awk " 235 | BEGIN { c=0; reset=0; } 236 | /^#/ { 237 | if (reset==1) { 238 | delete a; 239 | c=0; 240 | reset=0; 241 | } 242 | a[c++]=\$0; 243 | next; 244 | } 245 | { 246 | if (\$1==\"$var\") { 247 | print \"*\",\$1; 248 | for (i=0;i 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | 20 | #============================================================================= 21 | # Section: System database 22 | #============================================================================= 23 | 24 | ##---------------------------------------------------------------------------- 25 | # Clear the whole database 26 | # 27 | # Args: None 28 | # Returns: 0 29 | # Displays: nothing 30 | #----------------------------------------------------------------------------- 31 | 32 | function sf_db_clear 33 | { 34 | \rm -rf "$SF_DB_PATH" 35 | } 36 | 37 | ##---------------------------------------------------------------------------- 38 | # Check if the database file exists 39 | # 40 | # Args: None 41 | # Returns: 0 if file exists - <> 0 if not 42 | # Displays: nothing 43 | #----------------------------------------------------------------------------- 44 | 45 | function _sf_db_exists 46 | { 47 | [ -f "$SF_DB_PATH" ] 48 | } 49 | 50 | ##---------------------------------------------------------------------------- 51 | # Filter a name, leaving authorized chars only 52 | # 53 | # Args: 54 | # $1: Variable name 55 | # Returns: 0 56 | # Displays: Normalized name 57 | #---------------------------------------------------------------------------- 58 | 59 | function sf_db_normalize 60 | { 61 | echo "$1" | tr -cd 'a-zA-Z0-9:_./()-' 62 | echo 63 | } 64 | 65 | ##---------------------------------------------------------------------------- 66 | # Build a key (regexp usable in grep) from a variable name 67 | # 68 | # Args: 69 | # $1: Variable name 70 | # Returns: 0 71 | # Displays: Key string 72 | #---------------------------------------------------------------------------- 73 | 74 | function sf_db_key 75 | { 76 | sf_db_normalize "$1" | sed -e 's,\.,\.,g' 77 | } 78 | 79 | ##---------------------------------------------------------------------------- 80 | # Unset a variable 81 | # 82 | # No error if variable was not present in DB 83 | # 84 | # Args: 85 | # $*: Variable names 86 | # Returns: 0 87 | # Displays: nothing 88 | #----------------------------------------------------------------------------- 89 | 90 | function sf_db_unset 91 | { 92 | typeset key name tmp 93 | 94 | _sf_db_exists || return 0 95 | 96 | tmp=`sf_tmpfile` 97 | for name 98 | do 99 | [ -z "$name" ] && break 100 | key=`sf_db_key "$name"` 101 | grep -v "^$key " $SF_DB_PATH >$tmp 102 | cat $tmp >$SF_DB_PATH 103 | done 104 | /bin/rm -f $tmp 105 | } 106 | 107 | ##---------------------------------------------------------------------------- 108 | # Set a variable 109 | # 110 | # Args: 111 | # $1: Variable name 112 | # $2: Value 113 | # Returns: 0 114 | # Displays: nothing 115 | #----------------------------------------------------------------------------- 116 | 117 | function sf_db_set 118 | { 119 | typeset name value 120 | 121 | name=`sf_db_normalize "$1"` 122 | value="$2" 123 | 124 | sf_db_unset "$name" 125 | echo "$name $value" >>$SF_DB_PATH 126 | } 127 | 128 | ##---------------------------------------------------------------------------- 129 | # Duplicate a variable (copy content) 130 | # 131 | # If the source variable is not set, target is created with an empty value 132 | # 133 | # Args: 134 | # $1: Source variable name 135 | # $2: Target variable name 136 | # Returns: 0 137 | # Displays: nothing 138 | #----------------------------------------------------------------------------- 139 | 140 | function sf_db_copy 141 | { 142 | typeset source target 143 | 144 | source=`sf_db_normalize "$1"` 145 | target=`sf_db_normalize "$2"` 146 | 147 | sf_db_set $target "`sf_db_get $source`" 148 | } 149 | 150 | ##---------------------------------------------------------------------------- 151 | # Rename a variable (keep content) 152 | # 153 | # If the source variable is not set, target is created with an empty value 154 | # 155 | # Args: 156 | # $1: Source variable name 157 | # $2: Target variable name 158 | # Returns: 0 159 | # Displays: nothing 160 | #----------------------------------------------------------------------------- 161 | 162 | function sf_db_rename 163 | { 164 | sf_db_copy "$1" "$2" 165 | sf_db_unset "$1" 166 | } 167 | 168 | ##---------------------------------------------------------------------------- 169 | # Set a variable with the value returned by [function:tm_now] 170 | # 171 | # Args: 172 | # $1: Variable name 173 | # Returns: 0 174 | # Displays: nothing 175 | #----------------------------------------------------------------------------- 176 | 177 | function sf_db_set_timestamp 178 | { 179 | sf_db_set "$1" "`sf_tm_now`" 180 | } 181 | 182 | ##---------------------------------------------------------------------------- 183 | # Check if a variable is set 184 | # 185 | # If global variable SF_DB_PATH contains '', DB content is read from 186 | # standard input. 187 | # 188 | # Args: 189 | # $1: Variable name 190 | # Returns: 0 if variable is set, <> 0 if not 191 | # Displays: nothing 192 | #----------------------------------------------------------------------------- 193 | 194 | function sf_db_isset 195 | { 196 | typeset key 197 | 198 | key=`sf_db_key "$1"` 199 | _sf_get_clean_db | grep "^$key " >/dev/null 200 | } 201 | 202 | ##---------------------------------------------------------------------------- 203 | # Get a variable value 204 | # 205 | # If variable is not set, return an empty string (no error) 206 | # 207 | # If global variable SF_DB_PATH contains '', DB content is read from 208 | # standard input. 209 | # 210 | # Args: 211 | # $1: Variable name 212 | # Returns: 0 213 | # Displays: Value or empty string if var not set 214 | #----------------------------------------------------------------------------- 215 | 216 | function sf_db_get 217 | { 218 | typeset key 219 | 220 | key=`sf_db_key "$1"` 221 | 222 | # 'head -1' by security (should never be used) 223 | 224 | _sf_get_clean_db | grep "^$key " | sed 's,^[^ ][^ ]* ,,' | head -1 225 | } 226 | 227 | ##---------------------------------------------------------------------------- 228 | # Provides a database whose comments and empty lines are removed 229 | # 230 | # Exists because sf_db can be used to read from a handcrafted DB file 231 | # (by overriding $SF_DB_PATH) or from standard input. Such content can contain 232 | # comments and empty lines. 233 | # 234 | # Standard input is read when $SF_DB_PATH contains ''. 235 | # 236 | # Args: None 237 | # Returns: 0 238 | # Displays: Input with comments and empty lines removed 239 | #----------------------------------------------------------------------------- 240 | 241 | function _sf_get_clean_db 242 | { 243 | typeset dbpath 244 | 245 | if [ "X$SF_DB_PATH" = 'X' ] ; then 246 | dbpath='' 247 | else 248 | dbpath="$SF_DB_PATH" 249 | _sf_db_exists || return 250 | fi 251 | 252 | sed -e 's/ */ /g' -e 's/ */ /g' -e 's/^ *//g' -e 's/^#.*$//g' \ 253 | $dbpath | grep -v '^$' 254 | } 255 | 256 | ##---------------------------------------------------------------------------- 257 | # Dump the database 258 | # 259 | # Output format (each line) : 260 | # 261 | # The output is sorted alphabetically. 262 | # 263 | # Args: None 264 | # Returns: 0 265 | # Displays: DB content 266 | #----------------------------------------------------------------------------- 267 | 268 | function sf_db_dump 269 | { 270 | _sf_get_clean_db | sort 271 | } 272 | 273 | ##---------------------------------------------------------------------------- 274 | # List DB keys alphabetically, one per line 275 | # 276 | # Args: None 277 | # Returns: 0 278 | # Displays: DB keys 279 | #----------------------------------------------------------------------------- 280 | 281 | function sf_db_list 282 | { 283 | sf_db_dump | awk '{ print $1 }' 284 | } 285 | 286 | ##---------------------------------------------------------------------------- 287 | # Import variables in dump format (one per line) 288 | # 289 | # Lines are read from stdin 290 | # 291 | # Args: None 292 | # Returns: 0 293 | # Displays: nothing 294 | #----------------------------------------------------------------------------- 295 | 296 | function sf_db_import 297 | { 298 | typeset line 299 | 300 | while read line 301 | do 302 | sf_db_set $line 303 | done 304 | return 0 305 | } 306 | 307 | ##---------------------------------------------------------------------------- 308 | # Replaces patterns in the form '{{%%}}' by their value. 309 | # 310 | # Allows nested substitutions (ex: {{%interface{{%hcfg:icount%}}/network%}}). 311 | # 312 | # Patterns which do not correspond to an existing variable are replaced with an 313 | # empty string. 314 | # 315 | # Input: stdin, output: stdout. 316 | # 317 | # Args: 318 | # $1: 319 | # Returns: 0 320 | # Displays: Output 321 | #----------------------------------------------------------------------------- 322 | 323 | function sf_db_expand 324 | { 325 | typeset name value esc_val _tmp1 _tmp2 _tmp 326 | 327 | _tmp1=`sf_tmpfile` 328 | _tmp2=`sf_tmpfile` 329 | _tmp=`sf_tmpfile` 330 | 331 | sf_db_dump | while read name value 332 | do 333 | esc_val=`echo "$value" | sed -e 's!,!\,!g'` 334 | echo "s,{{%$name%}},$esc_val,g" 335 | done >$_tmp 336 | 337 | cat >$_tmp1 338 | 339 | while true 340 | do 341 | sed -f $_tmp <$_tmp1 >$_tmp2 342 | diff $_tmp1 $_tmp2 >/dev/null && break 343 | cp $_tmp2 $_tmp1 344 | done 345 | 346 | sed 's,{{%[^%]*%}},,g' <$_tmp2 # Suppress unresolved patterns 347 | 348 | \rm -rf $_tmp1 $_tmp2 $_tmp 349 | } 350 | 351 | #============================================================================= 352 | 353 | [ -z "${SF_DB_DEF_PATH:+}" ] && SF_DB_DEF_PATH=/etc/sysfunc.db 354 | [ -z "${SF_DB_PATH:+}" ] && SF_DB_PATH="$SF_DB_DEF_PATH" 355 | 356 | export SF_DB_DEF_PATH SF_DB_PATH 357 | 358 | #============================================================================= 359 | -------------------------------------------------------------------------------- /src/sf_disk.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Disk management 21 | #----------------------------------------------------------------------------- 22 | # This section contains functions to manipulate disks and block devices. 23 | #============================================================================= 24 | 25 | ##------------------------------------------------ 26 | # Normalize a disk device name 27 | # 28 | # After being normalized, device names can be compared. 29 | # 30 | # Input can be in the form: 31 | # 32 | # - /dev// 33 | # - /dev/mapper/... 34 | # - /dev/ (as /dev/sda1) 35 | # - LABEL=xxx 36 | # - UUID=xxx 37 | # 38 | # Output is in the form: 39 | # 40 | # - /dev// if LVM logical volume 41 | # - /dev/ if physical disk 42 | # - Copy of input if input was not recognised 43 | # 44 | # Args: 45 | # $1: Device name to normalize 46 | # Returns: 0 if device exists, 1 if not 47 | # Displays: Normalized name if device exists, copy of input if not 48 | #------------------------------------------------ 49 | 50 | function sf_disk_normalize_device 51 | { 52 | typeset dsk ndsk 53 | 54 | dsk="$1" 55 | 56 | case "$dsk" in 57 | /dev/mapper/*) 58 | #Note 1: 'lvs -o path' is not supported in RHEL4 59 | set -- `lvs --noheadings -o 'vg_name,name' $dsk 2>/dev/null` 60 | #Note 2: 'lvs' on a '/dev/mapper/' path is not supported on some 61 | # RHEL 4 versions (at least 4.5) 62 | # On those systems, we just split the string on the first '-'. 63 | [ -z "$1" ] && set -- `echo $dsk | sed -e 's,^/dev/mapper/,,' -e 's/-/ /'` 64 | ndsk="/dev/$1/$2" 65 | ;; 66 | UUID=*|LABEL=*) 67 | if [ `sf_os_version` = 4 ] ; then 68 | ndsk=`blkid -t "$dsk" | awk -F: '{ print $1 }'` 69 | else 70 | ndsk=`blkid -o device -t "$dsk"` 71 | fi 72 | ndsk=`sf_disk_normalize_device $ndsk` 73 | ;; 74 | *) 75 | ndsk=$dsk 76 | ;; 77 | esac 78 | ndsk=`echo $ndsk | sf_txt_cleanup` 79 | # sf_debug "sf_disk_normalize_device: Normalized '$dsk' to '$ndsk'" 80 | echo $ndsk 81 | [ -b "$ndsk" ] # Must remain function's last statement (return code) 82 | } 83 | 84 | ##------------------------------------------------ 85 | # Get the size of a file system (from device name) 86 | # 87 | # File system can be mounted or not. 88 | # 89 | # Note: In order to get the size of a mounted filesystem containing a given 90 | # path, use [function:fs_size]. 91 | # 92 | # Args: 93 | # $1: Device 94 | # Returns: 0 if dev exists and contains a FS, else !=0. 95 | # Displays: FS size in bytes. If the device does not exist or does not contain 96 | # a FS, displays nothing. 97 | #------------------------------------------------ 98 | 99 | function sf_disk_fs_size 100 | { 101 | typeset dev bcount bsize fsize 102 | dev="$1" 103 | fisize='' 104 | 105 | [ "`sf_disk_category $dev`" = fs ] || return 1 106 | 107 | case "`sf_os_family`" in 108 | linux) 109 | bcount=`dumpe2fs $dev 2>/dev/null | grep "^Block count:" | sed 's/^.* //'` 110 | bsize=`dumpe2fs $dev 2>/dev/null | grep "^Block size:" | sed 's/^.* //'` 111 | fsize=`expr $bcount \* $bsize` # FS size 112 | #sf_debug "$dev: Bcount=$bcount, Bsize=$bsize, FS size: $fsize" 113 | ;; 114 | *) 115 | sf_unsupported sf_disk_fs_size 116 | ;; 117 | esac 118 | 119 | echo $fsize 120 | 121 | return 0 122 | } 123 | 124 | ##------------------------------------------------ 125 | # Get category of content for a given disk device 126 | # 127 | # Args: 128 | # $1: Device path 129 | # Returns: Always 0 130 | # Displays: 131 | # 'fs' if it is a filesystem 132 | # 'swap' if it is a swap partition 133 | # else, the type returned by disk_type() 134 | #------------------------------------------------ 135 | 136 | function sf_disk_category 137 | { 138 | typeset disk category 139 | disk=$1 140 | 141 | [ "`sf_os_family`" = linux ] || sf_unsupported sf_disk_category 142 | 143 | if dumpe2fs $disk >/dev/null 2>&1 ; then 144 | category='fs' 145 | else 146 | category=`sf_disk_type "$disk"` 147 | fi 148 | 149 | #sf_debug "sf_disk_category: return category '$category' for $disk" 150 | echo $category 151 | } 152 | 153 | ##------------------------------------------------ 154 | # Returns type of content for a given disk device 155 | # 156 | # Args: 157 | # $1: Device path 158 | # Returns: Always 0 159 | # Displays: type returned by 'blkid' command 160 | #------------------------------------------------ 161 | #Note: 'blkid -o export' is not supported in RHEL4 162 | 163 | function sf_disk_type 164 | { 165 | [ "`sf_os_family`" = linux ] || sf_unsupported sf_disk_type 166 | 167 | blkid "$1" 2>/dev/null | sed -e 's/.*TYPE="//g' -e 's/".*$//g' 168 | return 0 169 | } 170 | 171 | ##------------------------------------------------ 172 | # Scan and discover new SCSI devices 173 | # 174 | # Calling program should wait between 5 and 10 seconds for new devices 175 | # to be discovered. 176 | # 177 | # Args: None 178 | # Returns: Always 0 179 | # Displays: Nothing 180 | #------------------------------------------------ 181 | 182 | function sf_disk_rescan 183 | { 184 | typeset i 185 | 186 | case "`sf_os_family`" in 187 | linux) 188 | # Use two mechanisms because 1st one does not see disk resizes on a 189 | # VM in RHEL 6. 190 | for i in /sys/class/scsi_host/host*/scan ; do 191 | echo "- - -" >$i 192 | done 193 | for i in /sys/class/scsi_device/*/device/rescan ; do 194 | echo 1 >$i 195 | done 196 | ;; 197 | *) 198 | sf_unsupported sf_disk_rescan 199 | ;; 200 | esac 201 | } 202 | 203 | #============================================================================= 204 | -------------------------------------------------------------------------------- /src/sf_error.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Error handling 21 | #============================================================================= 22 | 23 | #----------------------------------------------------------------------------- 24 | # Cleanup error file 25 | # 26 | # Called by [function:finish] 27 | #----------------------------------------------------------------------------- 28 | 29 | function _sf_error_cleanup 30 | { 31 | \rm -rf $_sf_error_list 32 | } 33 | 34 | ##---------------------------------------------------------------------------- 35 | # Displays an error message and aborts execution 36 | # 37 | # Args: 38 | # $1 : message 39 | # $2 : Optional. Exit code. 40 | # Returns: Does not return. Exits with the provided exit code if arg 2 set, 41 | # with 1 if not. 42 | # Displays: Error and abort messages 43 | #----------------------------------------------------------------------------- 44 | 45 | function sf_fatal 46 | { 47 | typeset rc 48 | 49 | rc=1 50 | [ -n "$2" ] && rc=$2 51 | 52 | sf_error "$1" 53 | sf_newline >&2 54 | __msg "************ Fatal error - Aborting ************" >&2 55 | sf_finish $rc 56 | } 57 | 58 | ##---------------------------------------------------------------------------- 59 | # Fatal error on unsupported feature 60 | # 61 | # Call this function when a feature is not available on the current 62 | # operating system (yet ?) 63 | # 64 | # Args: 65 | # $1 : feature name 66 | # Returns: Does not return. Exits with code 2. 67 | # Displays: Error and abort messages 68 | #----------------------------------------------------------------------------- 69 | 70 | function sf_unsupported 71 | { 72 | # $1: feature name 73 | 74 | sf_fatal "$1: Feature not supported in this environment" 2 75 | } 76 | 77 | ##---------------------------------------------------------------------------- 78 | # Displays an error message 79 | # 80 | # If the SF_ERRLOG environment variable is set, it is supposed to contain 81 | # a path. The error message will be appended to the file at this path. If 82 | # the file does not exist, it will be created. 83 | # Args: 84 | # $1 : Message 85 | # Returns: Always 0 86 | # Displays: Error message 87 | #----------------------------------------------------------------------------- 88 | 89 | function sf_error 90 | { 91 | typeset errfile 92 | 93 | sf_msg "***ERROR: $1" >&2 94 | 95 | errfile=$_sf_error_list 96 | [ -n "${SF_ERRLOG:+}" ] && errfile="$SF_ERRLOG" 97 | echo "$1" >>$errfile 98 | } 99 | 100 | ##---------------------------------------------------------------------------- 101 | # Import errors into the error system 102 | # 103 | # This mechanism is generally used in conjunction with the $SF_ERRLOG variable. 104 | # This variable is used to temporarily distract errors from the normal flow. 105 | # Then, this function can be called to reinject errors into the default error 106 | # repository. 107 | # 108 | # Args: 109 | # $1 : Optional. File to import (1 error per line). If not set, takes input 110 | # from stdin. 111 | # Returns: Always 0 112 | # Displays: Nothing 113 | #----------------------------------------------------------------------------- 114 | 115 | function sf_error_import 116 | { 117 | cat $1 >>$_sf_error_list 118 | } 119 | 120 | ##---------------------------------------------------------------------------- 121 | # Display a list of errors detected so far 122 | # 123 | # Args: None 124 | # Returns: Always 0 125 | # Displays: List of error messages, one by line 126 | #----------------------------------------------------------------------------- 127 | 128 | function sf_show_errors 129 | { 130 | sort -u $_sf_error_list 2>/dev/null 131 | } 132 | 133 | ##---------------------------------------------------------------------------- 134 | # Display a count of errors detected so far 135 | # 136 | # Args: None 137 | # Returns: Always 0 138 | # Displays: Error count 139 | #----------------------------------------------------------------------------- 140 | 141 | function sf_error_count 142 | { 143 | sf_show_errors | wc -l 144 | } 145 | 146 | #============================================================================= 147 | 148 | # File containing error messages. Does not exist before first error is raised. 149 | 150 | _sf_error_list=/tmp/._sf.errors.$$ 151 | 152 | export _sf_error_list 153 | -------------------------------------------------------------------------------- /src/sf_file.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: File manipulation 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Recursively deletes a file or a directory 25 | # 26 | # Returns without error if arg is a non-existent path 27 | # 28 | # Args: 29 | # $1 : Path to delete 30 | # Returns: Always 0 31 | # Displays: Info msg 32 | #----------------------------------------------------------------------------- 33 | 34 | function sf_delete 35 | { 36 | typeset i 37 | 38 | for i 39 | do 40 | if ls -d "$i" >/dev/null 2>&1 ; then 41 | sf_msg1 "Deleting $i" 42 | sf_save "$i" 43 | [ -z "$sf_noexec" ] && \rm -rf "$i" 44 | fi 45 | done 46 | } 47 | 48 | ##---------------------------------------------------------------------------- 49 | # Find an executable file 50 | # 51 | # Args: 52 | # $1 : Executable name 53 | # $2 : Optional. List of directories to search (separated by ':' chars). 54 | # If not set, use PATH 55 | # Returns: 0 56 | # Displays: Absolute path if found, nothing if not found 57 | #----------------------------------------------------------------------------- 58 | 59 | function sf_find_executable 60 | { 61 | typeset file dirs dir f 62 | 63 | file="$1" 64 | shift 65 | dirs="$*" 66 | [ -z "$dirs" ] && dirs="$PATH" 67 | dirs="`echo $dirs | sed 's/:/ /g'`" 68 | 69 | for dir in $dirs 70 | do 71 | f="$dir/$file" 72 | if [ -f "$f" -a -x "$f" ] ; then 73 | echo "$f" 74 | break 75 | fi 76 | done 77 | } 78 | 79 | ##---------------------------------------------------------------------------- 80 | # Creates a directory 81 | # 82 | # If the given path argument corresponds to an already existing 83 | # file (any type except directory or symbolic link to a directory), the 84 | # program aborts with a fatal error. If you want to avoid 85 | # this (if you want to create the directory, even if something else is 86 | # already existing in this path), call [function:delete] first. 87 | # If the path given as arg contains a symbolic link pointing to an existing 88 | # directory, it is left as-is. 89 | # 90 | # Args: 91 | # $1 : Path 92 | # $2 : Optional. Directory owner[:group]. Default: root 93 | # $3 : Optional. Directory mode in a format accepted by chmod. Default: 755 94 | # Returns: Always 0 95 | # Displays: Info msg 96 | #----------------------------------------------------------------------------- 97 | 98 | function sf_create_dir 99 | { 100 | 101 | typeset path owner mode 102 | 103 | path=$1 104 | owner=${2:-root} 105 | mode=${3:-755} 106 | 107 | if [ ! -d "$path" ] ; then 108 | sf_msg1 "Creating directory: $path" 109 | sf_save "$path" 110 | if [ -z "$sf_noexec" ] ; then 111 | mkdir -p "$path" 112 | [ -d "$path" ] || sf_fatal "$path: Cannot create directory" 113 | sf_chown $owner $path 114 | sf_chmod $mode "$path" 115 | fi 116 | fi 117 | } 118 | 119 | ##---------------------------------------------------------------------------- 120 | # Renames a file to '/old. 121 | # 122 | # ### This function is deprecated. Please use [function:save] instead. 123 | # 124 | # Args: 125 | # $1 : Path 126 | # Returns: Always 0 127 | # Displays: Info msg 128 | #----------------------------------------------------------------------------- 129 | 130 | function sf_rename_to_old 131 | { 132 | typeset dir base of f 133 | 134 | f="$1" 135 | [ -f "$f" ] || return 136 | dir="`dirname $f`" 137 | base="`basename $f`" 138 | of="$dir/old.$base" 139 | sf_msg1 "Renaming $f to old.$base" 140 | if [ -z "$sf_noexec" ] ; then 141 | sf_delete $of 142 | mv $f $of 143 | fi 144 | } 145 | 146 | ##---------------------------------------------------------------------------- 147 | # Copy a file or the content of function's standard input to a target file 148 | # 149 | # The copy takes place only if the source and target files are different. 150 | # If the target file is already existing, it is saved before being overwritten. 151 | # If the target path directory does not exist, it is created. 152 | # 153 | # Args: 154 | # $1: Source path. Special value: '-' means that data to copy is read from 155 | # stdin, allowing to produce dynamic content without a temp file. 156 | # $2: Target path 157 | # $3: Optional. File creation mode. Default=644 158 | # Returns: Always 0 159 | # Displays: Info msg 160 | #----------------------------------------------------------------------------- 161 | 162 | function sf_check_copy 163 | { 164 | typeset mode source target tmpsource 165 | tmpsource= 166 | source="$1" 167 | 168 | #-- Special case: source='-' => read data from stdin and create temp file 169 | 170 | if [ "X$source" = 'X-' ] ; then 171 | tmpsource=y 172 | source=`sf_tmpfile` 173 | dd of=$source 2>/dev/null 174 | fi 175 | 176 | target="$2" 177 | 178 | mode=${3:-644} 179 | 180 | [ -f "$source" ] || return 181 | 182 | if [ -f "$target" ] ; then 183 | diff "$source" "$target" >/dev/null 2>&1 184 | if [ $? = 0 ] ; then 185 | [ -n "$tmpsource" ] && \rm $source 186 | return 187 | fi 188 | fi 189 | 190 | sf_msg1 "Updating file $target" 191 | 192 | sf_save $target 193 | if [ -z "$sf_noexec" ] ; then 194 | \rm -rf "$target" 195 | sf_create_dir `dirname $target` 196 | cp "$source" "$target" 197 | sf_chmod $mode "$target" 198 | fi 199 | 200 | [ -n "$tmpsource" ] && \rm $source 201 | } 202 | 203 | ##---------------------------------------------------------------------------- 204 | # Replaces or prepends/appends a data block in a file 205 | # 206 | # The block is composed of entire lines and is surrounded by special comment 207 | # lines when inserted in the target file. These comment lines identify the 208 | # data block and allow the function to be called several times on the same 209 | # target file with different data blocks. The block identifier is the 210 | # base name of the source path. 211 | # 212 | # If the given block is not present in the target file, it is appended or 213 | # prepended, depending on the flag argument. If the block is already 214 | # present in the file (was inserted by a previous run of this function), 215 | # its content is compared with the new data, and replaced if different. 216 | # In this case, it is replaced at the exact location where the previous block 217 | # lied. 218 | # 219 | # If the target file exists, it is saved before being overwritten. 220 | # 221 | # If the target path directory does not exist, it is created. 222 | # 223 | # Args: 224 | # $1: If this arg starts with the '-' char, the data is to be read from 225 | # stdin and the string after the '-' is the block identifier. 226 | # If it does not start with '-', it is the path to the source file 227 | # (containing the data to insert). 228 | # $2: Target path 229 | # $3: Optional. Target file mode. 230 | # 231 | # Default=644 232 | # $4: Optional. Flag. Set to 'prepend' to add data at the beginning of 233 | # the file. Default mode: Append. 234 | # Used only if data block is not already present in the file. 235 | # Can be set to '' (empty string) to mean 'default mode'. 236 | # $5: Optional. Comment character. 237 | # This argument, if set, must contain only one character. 238 | # This character will be used as first char when building 239 | # the 'identifier' lines surrounding the data block. 240 | # Default: '#'. 241 | # Returns: Always 0 242 | # Displays: Info msg 243 | #----------------------------------------------------------------------------- 244 | 245 | function sf_check_block 246 | { 247 | typeset mode source target flag comment nstart nend fname tmp_dir action tmp_start tmp_end tmp_2 tmp_block 248 | 249 | source="$1" 250 | target="$2" 251 | mode=${3:-644} 252 | flag=${4:-} 253 | comment=${5:-#} 254 | 255 | # Special case: data read from stdin. Create file in temp dir (id taken from 256 | # the base name) 257 | 258 | echo "X$source" | grep '^X-' >/dev/null 2>&1 259 | if [ $? = 0 ] ; then 260 | fname="`echo "X$source" | sed 's/^..//'`" 261 | fname=`basename $fname` 262 | tmp_dir=`sf_tmpdir` 263 | source=$tmp_dir/$fname 264 | dd of=$source 2>/dev/null 265 | else 266 | fname=`basename $source` 267 | fi 268 | 269 | [ -f "$source" ] || return 270 | 271 | #-- Extrait bloc 272 | 273 | tmp_start=`sf_tmpfile` 274 | tmp_end=`sf_tmpfile` 275 | tmp_2=`sf_tmpfile` 276 | tmp_block=`sf_tmpfile` 277 | 278 | if [ -f "$target" ] ; then 279 | nstart=`grep -n "^.#sysfunc_start/$fname##" "$target" | sed 's!:.*$!!'` 280 | if [ -n "$nstart" ] ; then 281 | ( [ $nstart != 1 ] && head -`expr $nstart - 1` "$target" ) >$tmp_start 282 | tail -n +`expr $nstart + 1` <"$target" >$tmp_2 283 | nend=`grep -n "^.#sysfunc_end/$fname##" "$tmp_2" | sed 's!:.*$!!'` 284 | if [ -z "$nend" ] ; then # Corrupt block 285 | sf_fatal "check_block($1): Corrupt block detected - aborting" 286 | return 287 | fi 288 | ( [ $nend != 1 ] && head -`expr $nend - 1` $tmp_2 ) >$tmp_block 289 | tail -n +`expr $nend + 1` <$tmp_2 >$tmp_end 290 | diff "$source" $tmp_block >/dev/null 2>&1 && return # Same block, no action 291 | action='Replacing' 292 | else 293 | if [ "$flag" = "prepend" ] ; then 294 | >$tmp_start 295 | cp $target $tmp_end 296 | action='Prepending' 297 | else 298 | cp $target $tmp_start 299 | >$tmp_end 300 | action='Appending' 301 | fi 302 | fi 303 | else 304 | action='Creating from' 305 | >$tmp_start 306 | >$tmp_end 307 | fi 308 | 309 | sf_msg1 "$target: $action data block" 310 | 311 | sf_save $target 312 | if [ -z "$sf_noexec" ] ; then 313 | \rm -f "$target" 314 | sf_create_dir `dirname $target` 315 | ( 316 | cat $tmp_start 317 | echo "$comment#sysfunc_start/$fname##------ Don't remove this line" 318 | cat $source 319 | echo "$comment#sysfunc_end/$fname##-------- Don't remove this line" 320 | cat $tmp_end 321 | ) >$target 322 | sf_chmod $mode "$target" 323 | fi 324 | 325 | \rm -rf $tmp_dir $tmp_start $tmp_end $tmp_2 $tmp_block 326 | } 327 | 328 | ##---------------------------------------------------------------------------- 329 | # Checks if a file contains a block inserted by [function:check_block] 330 | # 331 | # 332 | # Args: 333 | # $1: The block identifier or source path 334 | # $2: File path 335 | # Returns: 0 if the block is in the file, !=0 if not. 336 | # Displays: Nothing 337 | #----------------------------------------------------------------------------- 338 | 339 | function sf_contains_block 340 | { 341 | typeset id target 342 | 343 | id="`basename $1`" 344 | target="$2" 345 | 346 | grep "^.#sysfunc_start/$id##" "$target" >/dev/null 2>&1 347 | } 348 | 349 | ##---------------------------------------------------------------------------- 350 | # Change the owner of a set of files/dirs 351 | # 352 | # Args: 353 | # $1: owner[:group] 354 | # $2+: List of paths (may be empty) 355 | # Returns: chown status code 356 | # Displays: Nothing 357 | #----------------------------------------------------------------------------- 358 | 359 | function sf_chown 360 | { 361 | typeset status owner 362 | 363 | status=0 364 | owner=$1 365 | shift 366 | if [ -z "$sf_noexec" -a $# -gt 0 ] ; then 367 | chown "$owner" $* 368 | status=$? 369 | fi 370 | return $status 371 | } 372 | 373 | ##---------------------------------------------------------------------------- 374 | # Change the mode of a set of files/dirs 375 | # 376 | # Args: 377 | # $1: mode as accepted by chmod 378 | # $2+: List of paths (may be empty) 379 | # Returns: chmod status code 380 | # Displays: Nothing 381 | #----------------------------------------------------------------------------- 382 | 383 | function sf_chmod 384 | { 385 | typeset status mode 386 | 387 | status=0 388 | mode=$1 389 | shift 390 | if [ -z "$sf_noexec" -a $# -gt 0 ] ; then 391 | chmod "$mode" $* 392 | status=$? 393 | fi 394 | return $status 395 | } 396 | 397 | ##---------------------------------------------------------------------------- 398 | # Creates or modifies a symbolic link 399 | # 400 | # The target is saved before being modified. 401 | # 402 | # If the target path directory does not exist, it is created. 403 | # 404 | # Args: 405 | # $1: Link target 406 | # $2: Link path 407 | # Returns: Always 0 408 | # Displays: Info msg 409 | #----------------------------------------------------------------------------- 410 | 411 | function sf_check_link 412 | { 413 | typeset link_target 414 | 415 | \ls -ld "$2" >/dev/null 2>&1 416 | if [ $? = 0 ] ; then 417 | if sf_file_is_link "$2" ; then 418 | link_target=`sf_file_readlink "$2"` 419 | [ "$link_target" = "$1" ] && return 420 | fi 421 | fi 422 | 423 | sf_msg1 "$2: Updating symbolic link" 424 | 425 | sf_save "$2" 426 | if [ -z "$sf_noexec" ] ; then 427 | \rm -rf "$2" 428 | sf_create_dir `dirname $2` 429 | ln -s "$1" "$2" 430 | fi 431 | } 432 | 433 | ##---------------------------------------------------------------------------- 434 | # Comment lines in a file 435 | # 436 | # The lines containing the (grep) pattern given in argument will be commented 437 | # out by prefixing them with the comment string. 438 | # If the pattern is not contained in the file, the file is left unchanged. 439 | # 440 | # Args: 441 | # $1: File path 442 | # $2: Pattern to search (grep regex syntax) 443 | # $3: Optional. Comment prefix string. Default='#' 444 | # $4: Optional. Number of lines to comment (''=all). Default: '' 445 | # Returns: Always 0 446 | # Displays: Info msg 447 | #----------------------------------------------------------------------------- 448 | 449 | function sf_comment_out 450 | { 451 | typeset file pattern com cnb tmp lnum line found 452 | file="$1" 453 | pattern="$2" 454 | com=${3:-#} 455 | cnb=${4:-} 456 | 457 | tmp=`sf_tmpfile` 458 | lnum=0 459 | while read line ; do 460 | lnum=`expr $lnum + 1` 461 | if [ "$cnb" != 0 ] ; then 462 | found=y 463 | echo "$line" | grep "$pattern" >/dev/null || found= 464 | if [ -n "$found" ] ; then 465 | sf_msg "$file: Commenting out line $lnum" 466 | line="$com$line" 467 | [ -n "$cnb" ] && cnb=`expr $cnb - 1` || : 468 | fi 469 | fi 470 | echo "$line" >>$tmp 471 | done <$file 472 | 473 | if ! diff $file $tmp >/dev/null 2>&1 ; then 474 | sf_save $file 475 | cp $tmp $file 476 | fi 477 | 478 | /bin/rm -f $tmp 479 | } 480 | 481 | ##---------------------------------------------------------------------------- 482 | # Uncomment lines in a file 483 | # 484 | # The commented lines containing the (grep) pattern given in argument 485 | # will be uncommented by removing the comment string. 486 | # If the pattern is not contained in the file, the file is left unchanged. 487 | # 488 | # Args: 489 | # $1: File path 490 | # $2: Pattern to search (grep regex syntax) 491 | # $3: Optional. Comment prefix string. Default='#' 492 | # $4: Number of lines to uncomment (''=all). Default: '' 493 | # Returns: Always 0 494 | # Displays: Info msg 495 | #----------------------------------------------------------------------------- 496 | 497 | function sf_uncomment 498 | { 499 | typeset file pattern com cnb tmp lnum line l2 found 500 | file="$1" 501 | pattern="$2" 502 | com=${3:-#} 503 | cnb=${4:-} 504 | 505 | tmp=`sf_tmpfile` 506 | lnum=0 507 | while read line ; do 508 | lnum=`expr $lnum + 1` 509 | if [ "$cnb" != 0 ] ; then 510 | found=y 511 | echo "$line" | grep "^[ ]*$com" >/dev/null || found= 512 | if [ -n "$found" ] ; then 513 | l2=`echo "$line" | sed "s,^[ ]*$com,,"` 514 | found=y 515 | echo "$l2" | grep "$pattern" >/dev/null || found= 516 | if [ -n "$found" ] ; then 517 | sf_msg "$file: Uncommenting line $lnum" 518 | line="$l2" 519 | [ -n "$cnb" ] && cnb=`expr $cnb - 1` || : 520 | fi 521 | fi 522 | fi 523 | echo "$line" >>$tmp 524 | done <$file 525 | 526 | if ! diff $file $tmp >/dev/null 2>&1 ; then 527 | sf_save $file 528 | cp $tmp $file 529 | fi 530 | 531 | /bin/rm -f $tmp 532 | } 533 | 534 | ##---------------------------------------------------------------------------- 535 | # Checks if a given line is contained in a file 536 | # 537 | # Takes a pattern and a string as arguments. The first line matching the 538 | # pattern is compared with the string. If they are different, the string 539 | # argument replaces the line in the file. If they are the same, the file 540 | # is left unchanged. 541 | # If the pattern is not found, the string arg is appended to the file. 542 | # If the file does not exist, it is created. 543 | # 544 | # Args: 545 | # $1: File path 546 | # $2: Pattern to search 547 | # $3: Line string 548 | # Returns: Always 0 549 | # Displays: Info msg 550 | #----------------------------------------------------------------------------- 551 | 552 | function sf_check_line 553 | { 554 | typeset file pattern line fline qpattern 555 | 556 | file="$1" 557 | pattern="$2" 558 | line="$3" 559 | 560 | fline=`grep "$pattern" $file 2>/dev/null | head -1 || :` 561 | [ "X$fline" = "X$line" ] && return 562 | sf_save $file 563 | if [ -n "$fline" ] ; then 564 | sf_msg1 "$1: Replacing '$2' line" 565 | qpattern=`echo "$pattern" | sed 's!/!\\\\/!g'` 566 | [ -z "$sf_noexec" ] && ed $file >/dev/null 2>&1 <<-EOF || : 567 | /$qpattern/ 568 | .c 569 | $line 570 | . 571 | w 572 | q 573 | EOF 574 | else 575 | sf_msg1 "$1: Appending '$3' line" 576 | [ -z "$sf_noexec" ] && echo "$line" >>$file 577 | fi 578 | } 579 | 580 | ##------------------------------------------------ 581 | # Sort a file in-place 582 | # 583 | # Args: 584 | # $1: Path 585 | # $2-*: Optional. Sort options 586 | # Returns: Sort return code 587 | # Displays: Info msg 588 | #------------------------------------------------ 589 | 590 | function sf_sort_file 591 | { 592 | typeset file tmp rc 593 | file="$1" 594 | shift 595 | rc=0 596 | 597 | if [ -z "$sf_noexec" ] ; then 598 | tmp=`sf_tmpfile` 599 | cp "$file" $tmp 600 | sf_save "$file" 601 | sort $* <$tmp >"$file" 602 | rc=$? 603 | rm -f $tmp 604 | fi 605 | 606 | return $rc 607 | } 608 | 609 | ##------------------------------------------------ 610 | # Get the type of a file 611 | # 612 | # Args: 613 | # $1: Path 614 | # Returns: 0 if file exists, 1 if not 615 | # Displays: - Nothing if file does not exist, 616 | # - R: Regular file, 617 | # - L: Symbolic link, 618 | # - D: Directory, 619 | # - C: Character device 620 | # - B: Block device 621 | # - P: Named pipe (fifo) 622 | #------------------------------------------------ 623 | 624 | function sf_file_type 625 | { 626 | typeset source 627 | source="$1" 628 | 629 | [ -e "$source" ] || return 1 630 | 631 | [ -b "$source" ] && echo B && return 0 632 | [ -c "$source" ] && echo C && return 0 633 | sf_file_is_link "$source" && echo L && return 0 634 | [ -d "$source" ] && echo D && return 0 635 | [ -p "$source" ] && echo P && return 0 636 | [ -f "$source" ] && echo R && return 0 637 | } 638 | 639 | ##------------------------------------------------ 640 | # Portable way to check if a file is a symbolic link 641 | # 642 | # Note: Don't use 'test -h' (not portable) 643 | # 644 | # Args: 645 | # $1: Path 646 | # Returns: 0 if file exists and is a symbolic link, 1 if not 647 | # Displays: Nothing 648 | #------------------------------------------------ 649 | 650 | function sf_file_is_link 651 | { 652 | typeset source 653 | source="$1" 654 | 655 | \ls -ld "$source" | grep -- '->' >/dev/null 2>&1 656 | } 657 | 658 | ##------------------------------------------------ 659 | # Return age of a file (since last modification) in seconds 660 | # 661 | # Args: 662 | # $1: Path 663 | # Returns: 0 if file exists, 1 if not 664 | # Displays: Time in seconds since last modification of file 665 | #------------------------------------------------ 666 | 667 | function sf_file_age 668 | { 669 | typeset source ftime 670 | source="$1" 671 | 672 | [ -e "$source" ] || return 1 673 | 674 | stat=`sf_find_executable stat` 675 | [ -z "$stat" ] && sf_unsupported sf_file_age 676 | 677 | ftime=`stat -c "%Y" "$source"` 678 | expr `date +%s` - $ftime 679 | 680 | return 0 681 | } 682 | 683 | ##------------------------------------------------ 684 | # Return mode of a file in octal 685 | # 686 | # Args: 687 | # $1: Path 688 | # Returns: 0 if file exists, 1 if not 689 | # Displays: File mode (nothing if file does not exist) 690 | #------------------------------------------------ 691 | 692 | function sf_file_mode 693 | { 694 | typeset source 695 | source="$1" 696 | 697 | [ -e "$source" ] || return 1 698 | 699 | stat=`sf_find_executable stat` 700 | [ -z "$stat" ] && sf_unsupported sf_file_mode 701 | 702 | stat -c "%a" "$source" 703 | return 0 704 | } 705 | 706 | ##------------------------------------------------ 707 | # Return owner of a file (numeric) 708 | # 709 | # Args: 710 | # $1: Path 711 | # Returns: 0 if file exists, 1 if not 712 | # Displays: File owner in numeric form (nothing if file does not exist) 713 | #------------------------------------------------ 714 | 715 | function sf_file_owner 716 | { 717 | typeset source 718 | source="$1" 719 | 720 | [ -e "$source" ] || return 1 721 | 722 | stat=`sf_find_executable stat` 723 | [ -z "$stat" ] && sf_unsupported sf_file_owner 724 | 725 | stat -c "%u" "$source" 726 | return 0 727 | } 728 | 729 | ##------------------------------------------------ 730 | # Return group of a file (numeric) 731 | # 732 | # Args: 733 | # $1: Path 734 | # Returns: 0 if file exists, 1 if not 735 | # Displays: File group in numeric form (nothing if file does not exist) 736 | #------------------------------------------------ 737 | 738 | function sf_file_group 739 | { 740 | typeset source 741 | source="$1" 742 | 743 | [ -e "$source" ] || return 1 744 | 745 | stat=`sf_find_executable stat` 746 | [ -z "$stat" ] && sf_unsupported sf_file_group 747 | 748 | stat -c "%g" "$source" 749 | return 0 750 | } 751 | 752 | ##------------------------------------------------ 753 | # Return last modification time of a file (Unix format) 754 | # 755 | # Args: 756 | # $1: Path 757 | # Returns: 0 if file exists, 1 if not 758 | # Displays: File last modification time in Unix format (Seconds since Epoch), 759 | # nothing if file does not exist. 760 | #------------------------------------------------ 761 | 762 | function sf_file_mtime 763 | { 764 | typeset source 765 | source="$1" 766 | 767 | [ -e "$source" ] || return 1 768 | 769 | stat=`sf_find_executable stat` 770 | [ -z "$stat" ] && sf_unsupported sf_file_mtime 771 | 772 | stat -c "%Y" "$source" 773 | return 0 774 | } 775 | 776 | ##------------------------------------------------ 777 | # Return size of a file (in bytes) 778 | # 779 | # Args: 780 | # $1: Path 781 | # Returns: 0 if file exists, 1 if not 782 | # Displays: File size (in bytes), nothing if file does not exist. 783 | #------------------------------------------------ 784 | 785 | function sf_file_size 786 | { 787 | typeset source 788 | source="$1" 789 | 790 | [ -e "$source" ] || return 1 791 | 792 | stat=`sf_find_executable stat` 793 | [ -z "$stat" ] && sf_unsupported sf_file_size 794 | 795 | stat -c "%s" "$source" 796 | return 0 797 | } 798 | 799 | ##------------------------------------------------ 800 | # Compute the checksum of a file 801 | # 802 | # Computed checksum depends on the OS and software available. It is prefixed 803 | # with a string giving the format, followed by a ':' and the chacksum in 804 | # readable form. 805 | # 806 | # 807 | # Possible format strings, in preference order: SHA1, MD5, CKS, SUM. 808 | # 809 | # 810 | # Generate a fatal error if none of these mechanisms is found. 811 | # 812 | # Args: 813 | # $1: Path 814 | # Returns: 0 if file exists, 1 if not 815 | # Displays: Checksum, nothing if file does not exist. 816 | #------------------------------------------------ 817 | 818 | function sf_file_checksum 819 | { 820 | typeset source 821 | source="$1" 822 | 823 | [ -e "$source" ] || return 1 824 | 825 | sf_find_executable sha1sum >/dev/null \ 826 | && echo SHA1:`sha1sum "$source" | awk '{ print $1 }'` && return 827 | 828 | sf_find_executable openssl >/dev/null \ 829 | && echo SHA1:`openssl dgst -sha1 -hex "$source" | awk '{ print $NF }'` && return 830 | 831 | sf_find_executable md5sum >/dev/null \ 832 | && echo MD5:`md5sum "$source" | awk '{ print $1 }'` && return 833 | 834 | sf_find_executable cksum >/dev/null \ 835 | && echo CKS:`cksum "$source" | awk '{ print $1 }'` && return 836 | 837 | sf_find_executable sum >/dev/null \ 838 | && echo SUM:`sum "$source" | awk '{ print $1 }'` && return 839 | 840 | sf_fatal "Cannot find a way to compute a file checksum" 841 | } 842 | 843 | ##------------------------------------------------ 844 | # Get the link target of a symbolic link 845 | # 846 | # Args: 847 | # $1: Path 848 | # Returns: 0 if file exists and is a symbolic link, 1 if not 849 | # Displays: Link target if file exists and is a symbolic link, nothing otherwise 850 | #------------------------------------------------ 851 | 852 | function sf_file_readlink 853 | { 854 | typeset source 855 | source="$1" 856 | 857 | sf_file_is_link "$source" || return 1 858 | 859 | sf_find_executable readlink >/dev/null && readlink "$source" && return 860 | 861 | # Old way, when readlink is not available 862 | 863 | ls -ld "$source" | sed 's/^.*->[ ]*//' 864 | } 865 | 866 | ##------------------------------------------------ 867 | # Canonicalize a file path 868 | # 869 | # The input path must correspond to an existing item (file or dir, any type) 870 | # Every directories leading to the source item must be readable by the current 871 | # user. 872 | # 873 | # 874 | # This function preserves the current directory. 875 | # 876 | # Args: 877 | # $1: Path 878 | # Returns: 0 if canonical path could be determined, 1 if not 879 | # Displays: Canonical path, nothing if path does not exist or access denied 880 | #------------------------------------------------ 881 | 882 | function sf_file_realpath 883 | { 884 | typeset source dir base swd rc 885 | source="$1" 886 | rc=0 887 | 888 | [ -e "$source" ] || return 1 889 | 890 | swd="`pwd`" 891 | if [ -d "$source" ] ; then 892 | cd "$source" || return 1 893 | /bin/pwd 2>/dev/null || rc=1 894 | else 895 | base="`basename \"$source\"`" 896 | dir="`dirname \"$source\"`" 897 | cd "$dir" || return 1 898 | dir="`/bin/pwd 2>/dev/null`" || rc=1 899 | [ "X$dir" = X/ ] && dir='' 900 | [ $rc = 0 ] && echo "$dir/$base" 901 | fi 902 | cd "$swd" 903 | 904 | return $rc 905 | } 906 | 907 | #============================================================================= 908 | -------------------------------------------------------------------------------- /src/sf_fs.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Filesystems 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Checks if a directory is a file system mount point 25 | # 26 | # ### This function is deprecated. Please use [function:fs_is_mount_point]. 27 | # 28 | # Args: 29 | # $1: Directory to check 30 | # Returns: 0 if true, !=0 if false 31 | # Displays: nothing 32 | #----------------------------------------------------------------------------- 33 | 34 | function sf_has_dedicated_fs 35 | { 36 | sf_fs_is_mount_point $* 37 | } 38 | 39 | ##---------------------------------------------------------------------------- 40 | # Checks if a directory is a file system mount point 41 | # 42 | # A filesystem must be mounted on the directory for it to be 43 | # recognized as a mount point. 44 | # 45 | # Args: 46 | # $1: Directory to check 47 | # Returns: 0 if true, !=0 if false 48 | # Displays: nothing 49 | #----------------------------------------------------------------------------- 50 | 51 | function sf_fs_is_mount_point 52 | { 53 | [ -d "$1" ] || return 1 54 | 55 | [ "`sf_fs_mount_point $1`" = "$1" ] 56 | } 57 | 58 | ##---------------------------------------------------------------------------- 59 | # Gets the mount point of the filesystem containing a given path 60 | # 61 | # ### This function is deprecated. Please use [function:fs_mount_point]. 62 | # 63 | # Args: 64 | # $1: Path (must correspond to an existing element) 65 | # Returns: Always 0 66 | # Displays: The mount directory of the filesystem containing the element 67 | #----------------------------------------------------------------------------- 68 | 69 | function sf_get_fs_mnt 70 | { 71 | sf_fs_mount_point $* 72 | } 73 | 74 | ##---------------------------------------------------------------------------- 75 | # Gets the mount point of the filesystem containing a given path 76 | # 77 | # Args: 78 | # $1: Path (must correspond to an existing element) 79 | # Returns: Always 0 80 | # Displays: The mount directory of the filesystem containing the element 81 | #----------------------------------------------------------------------------- 82 | 83 | function sf_fs_mount_point 84 | { 85 | case "`sf_os_family`" in 86 | linux) 87 | df -kP "$1" | tail -1 | awk '{ print $6 }' 88 | ;; 89 | sunos) 90 | /usr/bin/df -k "$1" | tail -1 | awk '{ print $6 }' 91 | ;; 92 | aix) 93 | df -k "$1" | tail -1 | awk '{ print $7 }' 94 | ;; 95 | *) 96 | sf_unsupported sf_fs_mount_point 97 | ;; 98 | esac 99 | } 100 | 101 | ##---------------------------------------------------------------------------- 102 | # Gets the device of the filesystem containing a given path 103 | # 104 | # ### This function is deprecated. Please use [function:fs_device]. 105 | # 106 | # Args: 107 | # $1: Path (must correspond to an existing element) 108 | # Returns: Always 0 109 | # Displays: The normalized device of the filesystem containing the element 110 | #----------------------------------------------------------------------------- 111 | 112 | function sf_get_fs_device 113 | { 114 | sf_fs_device $* 115 | } 116 | 117 | ##---------------------------------------------------------------------------- 118 | # Gets the device of the filesystem containing a given path 119 | # 120 | # Args: 121 | # $1: Path (must correspond to an existing element) 122 | # Returns: Always 0 123 | # Displays: The normalized device of the filesystem containing the element 124 | #----------------------------------------------------------------------------- 125 | 126 | function sf_fs_device 127 | { 128 | typeset disk 129 | 130 | [ -e "$1" ] || return 131 | 132 | case "`sf_os_family`" in 133 | linux) 134 | disk=`df -kP "$1" | tail -1 | awk '{ print $1 }'` 135 | ;; 136 | *) 137 | sf_unsupported sf_fs_device 138 | ;; 139 | esac 140 | 141 | sf_disk_normalize_device $disk 142 | } 143 | 144 | ##---------------------------------------------------------------------------- 145 | # Get the size of the filesystem containing a given path 146 | # 147 | # ### This function is deprecated. Please use [function:fs_size]. 148 | # 149 | # Args: 150 | # $1: Path (must correspond to an existing element) 151 | # Returns: Always 0 152 | # Displays: FS size in Mbytes 153 | #----------------------------------------------------------------------------- 154 | 155 | function sf_get_fs_size 156 | { 157 | sf_fs_size $* 158 | } 159 | 160 | ##---------------------------------------------------------------------------- 161 | # Get the size of the filesystem containing a given path 162 | # 163 | # Note: This function is to be used for a mounted filesystem. In order to get 164 | # the size of a file system contained in a given device (mounted or not), 165 | # use [function:disk_fs_size]. 166 | # 167 | # Args: 168 | # $1: Path (must correspond to an existing element) 169 | # Returns: Always 0 170 | # Displays: FS size in Mbytes 171 | #----------------------------------------------------------------------------- 172 | 173 | function sf_fs_size 174 | { 175 | # $1=directory 176 | 177 | case "`sf_os_family`" in 178 | linux) 179 | sz=`df -kP "$1" | tail -1 | awk '{ print $2 }'` 180 | ;; 181 | sunos) 182 | sz=`/usr/bin/df -k "$1" | tail -1 | awk '{ print $2 }'` 183 | ;; 184 | aix) 185 | sz=`df -k "$1" | tail -1 | awk '{ print $2 }'` 186 | ;; 187 | *) 188 | sf_unsupported sf_fs_size 189 | ;; 190 | esac 191 | 192 | echo `expr $sz / 1024` 193 | } 194 | 195 | ##---------------------------------------------------------------------------- 196 | # Extend a file system to a given size 197 | # 198 | # ### This function is deprecated. Please use [function:fs_extend]. 199 | # 200 | # Args: 201 | # $1: A path contained in the file system to extend 202 | # $2: The new size in Mbytes, or the size to add if prefixed with a '+' 203 | # Returns: Always 0 204 | # Displays: Info msg 205 | #----------------------------------------------------------------------------- 206 | 207 | function sf_set_fs_space 208 | { 209 | sf_fs_extend $* 210 | } 211 | 212 | ##---------------------------------------------------------------------------- 213 | # Extend a file system to a given size 214 | # 215 | # Args: 216 | # $1: A path contained in the file system to extend 217 | # $2: The new size in Mbytes, or the size to add if prefixed with a '+' 218 | # Returns: Always 0 219 | # Displays: Info msg 220 | #----------------------------------------------------------------------------- 221 | 222 | function sf_fs_extend 223 | { 224 | typeset fs size newsize rc 225 | rc=0 226 | 227 | fs=`sf_fs_mount_point $1` 228 | size=`sf_fs_size $1` 229 | newsize=$2 230 | echo "$newsize" | grep '^+' >/dev/null 2>&1 231 | if [ $? = 0 ] ; then 232 | newsize=`echo $newsize | sed 's/^.//'` 233 | newsize=`expr $size + $newsize` 234 | fi 235 | 236 | if [ "$newsize" -gt "$size" ] ; then 237 | sf_msg1 "Extending $fs filesystem to $newsize Mb" 238 | case "`sf_os_family`" in 239 | aix) 240 | if [ -z "$sf_noexec" ] ; then 241 | chfs -a size=${newsize}M $fs 242 | rc=$? 243 | fi 244 | ;; 245 | *) 246 | sf_unsupported sf_fs_extend 247 | ;; 248 | esac 249 | fi 250 | 251 | return $rc 252 | } 253 | 254 | ##---------------------------------------------------------------------------- 255 | # Create a file system, mount it, and register it (mount at boot) 256 | # 257 | # ### This function is deprecated. Please use [function:fs_create]. 258 | # 259 | # Refuses existing directory as mount point (security) 260 | # 261 | # Args: 262 | # $1: Mount point 263 | # $2: device path 264 | # $3: Optional. FS type (if empty, default FS type for this OS) 265 | # $4: Optional. Mount point directory owner[:group] 266 | # Returns: 0 if no error, 1 on error 267 | # Displays: Info msg 268 | #----------------------------------------------------------------------------- 269 | 270 | function sf_create_fs 271 | { 272 | sf_fs_create $* 273 | } 274 | 275 | ##---------------------------------------------------------------------------- 276 | # Create a file system, mount it, and register it (mount at boot) 277 | # 278 | # Refuses existing directory as mount point (security) 279 | # 280 | # Args: 281 | # $1: Mount point 282 | # $2: device path 283 | # $3: Optional. FS type (if empty, default FS type for this OS) 284 | # $4: Optional. Mount point directory owner[:group]~ 285 | # $5: mkfs additional options 286 | # Returns: 0 if no error, 1 on error 287 | # Displays: Info msg 288 | #----------------------------------------------------------------------------- 289 | 290 | function sf_fs_create 291 | { 292 | typeset mnt dev type owner opts tmp mkfs_opts 293 | 294 | mnt=$1 295 | dev=$2 296 | type=$3 297 | [ -z "$type" ] && type=`sf_fs_default_type` 298 | owner=$4 299 | [ -z "$owner" ] && owner=root 300 | mkfs_opts=$5 301 | 302 | sf_fs_is_mount_point $mnt && return 0 303 | sf_msg1 "$mnt: Creating file system..." 304 | 305 | if [ -d $mnt ] ; then # Securite 306 | sf_error "$mnt: Cannot create FS on an existing directory" 307 | return 1 308 | else 309 | [ -z "$sf_noexec" ] && mkdir -p $mnt 310 | fi 311 | 312 | [ $? = 0 ] || return 1 313 | 314 | case "`sf_os_family`" in 315 | linux) 316 | opts='' 317 | # When supported, set filesystem label 318 | echo $type | grep '^ext' >/dev/null && opts="-L `basename $dev`" 319 | if [ -z "$sf_noexec" ] ; then 320 | tmp=`sf_tmpfile` 321 | mkfs -t $type $opts $mkfs_opts $dev >$tmp 2>&1 322 | if [ $? != 0 ] ; then 323 | echo "mkfs failed with this log :" 324 | cat $tmp 325 | /bin/rm -f $tmp 326 | return 1 327 | else 328 | sf_msg1 "$mnt: File system created" 329 | /bin/rm -f $tmp 330 | fi 331 | sf_check_line /etc/fstab "^$dev " "$dev $mnt $type defaults 1 2" 332 | fi 333 | ;; 334 | *) 335 | sf_unsupported sf_fs_create 336 | ;; 337 | esac 338 | 339 | if [ -z "$sf_noexec" ] ; then 340 | mount $dev $mnt || return 1 341 | sf_chown $owner $mnt || return 1 342 | fi 343 | 344 | return 0 345 | } 346 | 347 | ##---------------------------------------------------------------------------- 348 | # Returns default FS type for current environment 349 | # 350 | # Args: None 351 | # Returns: Always 0 352 | # Displays: Type 353 | #----------------------------------------------------------------------------- 354 | 355 | function sf_fs_default_type 356 | { 357 | typeset type 358 | 359 | case `sf_os_family` in 360 | linux) 361 | for type in xfs ext4 ext3 ext2 ; do 362 | [ -x /sbin/mkfs.$type ] && break 363 | done 364 | ;; 365 | *) sf_unsupported sf_fs_default_type 366 | ;; 367 | esac 368 | 369 | echo $type 370 | } 371 | 372 | ##---------------------------------------------------------------------------- 373 | # Create a logical volume and a filesystem on it 374 | # 375 | # ### This function is deprecated. Please use [function:fs_create_lv_fs] 376 | # ### Warning: Note that superseding function has argument 4 and 5 swapped (size and FS type). 377 | # 378 | # Combines [function:create_lv] and [function:fs_create] 379 | # 380 | # Args: 381 | # $1: Mount point (directory) 382 | # $2: Logical volume name 383 | # $3: Volume group name 384 | # $4: File system type (optional. if empty, defaults to default FS type for this OS) 385 | # $5: Size (Default: megabytes, optional suffixes: [kmgt]. Special value: 'all' 386 | # takes the whole free size in the VG. 387 | # $6: Optional. Directory owner[:group] 388 | # Returns: 0: OK, !=0: Error 389 | # Displays: Info msg 390 | #----------------------------------------------------------------------------- 391 | 392 | function sf_create_lv_fs 393 | { 394 | sf_fs_create_lv_fs "$1" "$2" "$3" "$5" "$4" "$6" 395 | } 396 | 397 | ##---------------------------------------------------------------------------- 398 | # Create a logical volume and a filesystem on it 399 | # 400 | # Combines [function:create_lv] and [function:fs_create] 401 | # 402 | # Args: 403 | # $1: Mount point (directory) 404 | # $2: Logical volume name 405 | # $3: Volume group name 406 | # $4: Size (Default: megabytes, optional suffixes: [kmgt]. Special value: 'all' 407 | # takes the whole free size in the VG. 408 | # $5: Optional. File system type. Defaults to default FS type for this environment 409 | # $6: Optional. Directory owner[:group] 410 | # $7: mkfs additional options 411 | # 412 | # Returns: 0: OK, !=0: Error 413 | # Displays: Info msg 414 | #----------------------------------------------------------------------------- 415 | 416 | function sf_fs_create_lv_fs 417 | { 418 | typeset mnt lv vg type size owner mkfs_opts 419 | 420 | mnt=$1 421 | lv=$2 422 | vg=$3 423 | size=$4 424 | type=$5 425 | owner=$6 426 | mkfs_opts=$7 427 | 428 | sf_create_lv $lv $vg $size || return 1 429 | sf_fs_create $mnt /dev/$vg/$lv "$type" "$owner" "$mkfs_opts" || return 1 430 | return 0 431 | } 432 | 433 | #============================================================================= 434 | -------------------------------------------------------------------------------- /src/sf_ip4.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | 20 | #============================================================================= 21 | # Section: IP V4 addresses 22 | #============================================================================= 23 | 24 | ##---------------------------------------------------------------------------- 25 | # Checks if the input string is a valid IP address 26 | # 27 | # Args: 28 | # $1: IP address to check 29 | # Returns: 0 if address is valid, !=0 if not 30 | # Displays: Nothing 31 | #----------------------------------------------------------------------------- 32 | 33 | function sf_ip4_is_valid_ip 34 | { 35 | typeset ip a bip 36 | 37 | ip="$1" 38 | bip="`echo $ip | sed 's,\., ,g'`" 39 | if [ -n "$BASH" ] ; then 40 | eval 'a=($bip)' # eval needed to avoid syntax error in ksh 41 | else 42 | set -A a $bip 43 | fi 44 | [ ${#a[*]} = 4 ] || return 1 45 | [ -n "`echo $ip | sed 's,[\.0-9],,g'`" ] && return 1 46 | [ "${a[0]}" -eq 0 ] && return 1 47 | return 0 48 | } 49 | 50 | ##---------------------------------------------------------------------------- 51 | # Checks if the input string is a valid IP address and aborts if not 52 | # 53 | # Args: 54 | # $1: IP address to check 55 | # Returns: only if address is valid 56 | # Displays: Nothing if OK. Error if not 57 | #----------------------------------------------------------------------------- 58 | 59 | function sf_ip4_validate_ip 60 | { 61 | sf_ip4_is_valid_ip "$1" || sf_fatal "$1: Invalid IP address" 62 | } 63 | 64 | ##---------------------------------------------------------------------------- 65 | # Compute network from IP and netmask 66 | # 67 | # Args: 68 | # $1: IP 69 | # $2: Netmask 70 | # Returns: 0 71 | # Displays: Network 72 | #----------------------------------------------------------------------------- 73 | 74 | function sf_ip4_network 75 | { 76 | typeset ip aip bip mask amask bmask 77 | 78 | ip="$1" 79 | sf_ip4_validate_ip "$ip" 80 | mask="$2" 81 | sf_ip4_validate_ip "$mask" 82 | 83 | bip="`echo $ip | sed 's,\., ,g'`" 84 | bmask="`echo $mask | sed 's,\., ,g'`" 85 | if [ -n "$BASH" ] ; then 86 | eval 'aip=($bip)' # eval needed to avoid syntax error in ksh 87 | eval 'amask=($bmask)' 88 | else 89 | set -A aip $bip 90 | set -A amask $bmask 91 | fi 92 | 93 | for n in 0 1 2 3 94 | do 95 | net[$n]=$((${aip[$n]} & ${amask[$n]})) 96 | done 97 | echo ${net[*]} | sed 's, ,.,g' 98 | } 99 | 100 | #============================================================================= 101 | -------------------------------------------------------------------------------- /src/sf_kernel.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Kernel 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Check if a kernel module is loaded 25 | # 26 | # Args: 27 | # $1: Module name 28 | # Returns: 0 if module is loaded, 1 if not 29 | # Displays: Nothing 30 | #----------------------------------------------------------------------------- 31 | 32 | function sf_krn_module_is_loaded 33 | { 34 | case "`sf_os_family`" in 35 | linux) 36 | lsmod | awk "(\$1==\"$1\") { exit 1; }" && return 1 37 | ;; 38 | *) 39 | sf_unsupported sf_krn_module_is_loaded 40 | ;; 41 | esac 42 | 43 | return 0 44 | } 45 | 46 | #============================================================================= 47 | -------------------------------------------------------------------------------- /src/sf_lvm.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Logical volume manager 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Checks if a given logical volume exists 25 | # 26 | # Args: 27 | # $1: VG name 28 | # $2: LV name 29 | # Returns: 0 if it exists, 1 if not 30 | # Displays: Nothing 31 | #----------------------------------------------------------------------------- 32 | 33 | function sf_lv_exists 34 | { 35 | typeset vg lv rc 36 | 37 | vg=$1 38 | lv=$2 39 | 40 | case "`sf_os_family`" in 41 | linux) 42 | lvs $vg/$lv >/dev/null 2>&1 43 | rc=$? 44 | ;; 45 | *) 46 | sf_unsupported sf_lv_exists 47 | ;; 48 | esac 49 | 50 | return $rc 51 | } 52 | 53 | ##---------------------------------------------------------------------------- 54 | # Checks if a given volume group exists 55 | # 56 | # Args: 57 | # $1: VG name 58 | # Returns: 0 if it exists, 1 if not 59 | # Displays: Nothing 60 | #----------------------------------------------------------------------------- 61 | 62 | function sf_vg_exists 63 | { 64 | typeset vg rc 65 | 66 | vg=$1 67 | 68 | case "`sf_os_family`" in 69 | linux) 70 | vgs $vg >/dev/null 2>&1 71 | rc=$? 72 | ;; 73 | *) 74 | sf_unsupported sf_lv_exists 75 | ;; 76 | esac 77 | 78 | return $rc 79 | } 80 | 81 | ##---------------------------------------------------------------------------- 82 | # Create a logical volume 83 | # 84 | # Args: 85 | # $1: Logical volume name 86 | # $2: Volume group name 87 | # $3: Size (Default: megabytes, optional suffixes: [kmgt]. Special value: 'all' 88 | # takes the whole free size in the VG. 89 | # Returns: 0: OK, !=0: Error 90 | # Displays: Info msg 91 | #----------------------------------------------------------------------------- 92 | 93 | function sf_create_lv 94 | { 95 | typeset lv vg size sz_opt rc 96 | rc=0 97 | lv=$1 98 | vg=$2 99 | size=$3 100 | 101 | if ! sf_vg_exists $vg ; then 102 | sf_error "VG $vg does not exist" 103 | return 1 104 | fi 105 | 106 | sf_lv_exists $vg $lv && return 0 107 | 108 | sz_opt="--size $size" 109 | [ "$size" = all ] && sz_opt="--extents 100%FREE" 110 | 111 | sf_msg1 "Creating LV $lv on VG $vg" 112 | 113 | case "`sf_os_family`" in 114 | linux) 115 | if [ -z "$sf_noexec" ] ; then 116 | lvcreate $sz_opt -n $lv $vg 117 | rc=$? 118 | fi 119 | ;; 120 | *) 121 | sf_unsupported sf_create_lv 122 | ;; 123 | esac 124 | 125 | return $rc 126 | } 127 | 128 | ##---------------------------------------------------------------------------- 129 | # Create a volume group 130 | # 131 | # Args: 132 | # $1: volume group name 133 | # $2: PE size (including optional unit, default=Mb) 134 | # $3: Device path, without the /dev prefix 135 | # Returns: 0: OK, !=0: Error 136 | # Displays: Info msg 137 | #----------------------------------------------------------------------------- 138 | 139 | function sf_create_vg 140 | { 141 | typeset vg pesize device rc 142 | rc=0 143 | vg=$1 144 | pesize=$2 145 | device=$3 146 | 147 | sf_vg_exists $vg && return 0 148 | 149 | sf_msg1 "Creating VG $vg" 150 | 151 | case "`sf_os_family`" in 152 | linux) 153 | if [ -z "$sf_noexec" ] ; then 154 | vgcreate -s $pesize $vg /dev/$device 155 | rc=$? 156 | fi 157 | ;; 158 | *) 159 | sf_unsupported sf_create_vg 160 | ;; 161 | esac 162 | 163 | return $rc 164 | } 165 | 166 | ##------------------------------------------------ 167 | # Returns the VG containing a given LV 168 | # 169 | # Args: 170 | # $1: LV device path 171 | # Returns: Always 0 172 | # Displays: The containing VG name, or nothing if device is not a valid LV. 173 | #------------------------------------------------ 174 | 175 | function sf_lv_to_vg 176 | { 177 | lvs --noheadings -o vg_name "$1" 2>/dev/null | sed 's/^ *//g' 178 | } 179 | 180 | ##------------------------------------------------ 181 | # Returns the available size in a VG (in Mb) 182 | # 183 | # Args: 184 | # $1: VG name 185 | # Returns: Always 0 186 | # Displays: The available size in Mbytes. Nothing if VG does not exist. 187 | #------------------------------------------------ 188 | 189 | function sf_lvm_vg_free 190 | { 191 | vgs --noheading --nosuffix -o vg_free --units m "$1" 2>/dev/null \ 192 | | sed -e 's/^ *//g' -e 's/\..*$//' 193 | } 194 | 195 | #============================================================================= 196 | -------------------------------------------------------------------------------- /src/sf_misc.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Miscellaneous 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Display help 25 | # 26 | # Args: 27 | # Returns: No return 28 | # Displays: Help message 29 | #----------------------------------------------------------------------------- 30 | 31 | function sf_help 32 | { 33 | _sf_usage 34 | } 35 | 36 | ##---------------------------------------------------------------------------- 37 | # Checks if the library is already loaded 38 | # 39 | # Of course, if it can run, the library is loaded. So, it always returns 0. 40 | # 41 | # Allows to support the 'official' way to load sysfunc : 42 | # 43 | # sf_loaded 2>/dev/null || . sysfunc.sh 44 | # 45 | # Args: none 46 | # Returns: Always 0 47 | # Displays: Nothing 48 | ##---------------------------------------------------------------------------- 49 | 50 | function sf_loaded 51 | { 52 | return 0 53 | } 54 | 55 | ##---------------------------------------------------------------------------- 56 | # Displays library version 57 | # 58 | # Args: none 59 | # Returns: Always 0 60 | # Displays: Library version (string) 61 | #----------------------------------------------------------------------------- 62 | 63 | function sf_version 64 | { 65 | echo "%SOFTWARE_VERSION%" 66 | } 67 | 68 | ##---------------------------------------------------------------------------- 69 | # Retrieves executable data through an URL and executes it. 70 | # 71 | # Supports any URL accepted by wget. 72 | # 73 | # By default, the 'wget' command is used. If the $WGET environment variable 74 | # is set, it is used instead (use, for instance, to specify a proxy or an 75 | # alternate configuration file). 76 | # 77 | # Args: 78 | # $1 : Url 79 | # Returns: the return code of the executed program 80 | # Displays: data displayed by the executed program 81 | #----------------------------------------------------------------------------- 82 | 83 | function sf_exec_url 84 | { 85 | typeset wd tdir status rc 86 | rc=0 87 | [ -n "$WGET" ] || WGET=wget 88 | 89 | wd=`pwd` 90 | 91 | for i ; do 92 | tdir=`sf_tmp_dir` 93 | cd $tdir 94 | 95 | $WGET $i 96 | sf_chmod +x * 97 | if [ -z "$sf_noexec" ] ; then 98 | ./* 99 | status=$? 100 | [ "$rc" = 0 ] && rc=$status 101 | fi 102 | 103 | cd $wd 104 | /bin/rm -rf $tdir 105 | done 106 | 107 | return $rc 108 | } 109 | 110 | ##---------------------------------------------------------------------------- 111 | # Cleanup at exit 112 | # 113 | # This function discards every allocated resources (tmp files,...) 114 | # 115 | # Args: none 116 | # Returns: Always 0 117 | # Displays: nothing 118 | #----------------------------------------------------------------------------- 119 | 120 | function sf_cleanup 121 | { 122 | _sf_tmp_cleanup 123 | _sf_error_cleanup 124 | _sf_save_cleanup 125 | } 126 | 127 | ##---------------------------------------------------------------------------- 128 | # Finish execution 129 | # 130 | # This function discards every allocated resources (tmp files,...) 131 | # 132 | # Args: 133 | # $1: Ooptional. Exit code. Default: 0 134 | # Returns: Never returns. Exits from program. 135 | # Displays: nothing 136 | #----------------------------------------------------------------------------- 137 | 138 | function sf_finish 139 | { 140 | typeset rc 141 | rc=0 142 | [ "$#" != 0 ] && rc="$1" 143 | 144 | sf_cleanup 145 | 146 | exit $rc 147 | } 148 | 149 | ##---------------------------------------------------------------------------- 150 | # Check if a shell function is defined 151 | # 152 | # Args: 153 | # $1: Function name 154 | # Returns: 0 if function is defined, 1 if not 155 | # Displays: Nothing 156 | #----------------------------------------------------------------------------- 157 | 158 | function sf_func_is_defined 159 | { 160 | typeset -f "$1" >/dev/null 2>&1 161 | } 162 | 163 | ##------------------------------------------------ 164 | # Uncomment and cleanup input stream 165 | # 166 | # - changes tabs to spaces, 167 | # - changes multiple blanks to one space, 168 | # - removes leading and trailing blanks, 169 | # - removes comments (starting with '#'), 170 | # - removes blank lines 171 | # 172 | # Args: 173 | # $1: Optional. File to read from. If not set, read from stdin 174 | # Returns: Always 0 175 | # Displays: the cleaned stream 176 | #------------------------------------------------ 177 | 178 | function sf_txt_cleanup 179 | { 180 | typeset input 181 | 182 | input='-' 183 | [ $# -gt 0 ] && input=$1 184 | 185 | sed -e 's/ / /g' -e 's/ */ /g' -e 's/#.*$//g' -e 's/^ *//g' \ 186 | -e 's/ * $//g' $input \ 187 | | grep -v '^$' 188 | return 0 189 | } 190 | 191 | #============================================================================= 192 | -------------------------------------------------------------------------------- /src/sf_msg.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Message display 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Displays a warning message 25 | # 26 | # Args: 27 | # $1 : message 28 | # Returns: Always 0 29 | # Displays: Warning message 30 | #----------------------------------------------------------------------------- 31 | 32 | function sf_warning 33 | { 34 | sf_msg " *===* WARNING *===* : $1" >&2 35 | } 36 | 37 | #---------------------------------------------------------------------------- 38 | # Core message display (internal) 39 | #---------------------------------------------------------------------------- 40 | 41 | function __msg 42 | { 43 | echo "$*" 44 | } 45 | 46 | ##---------------------------------------------------------------------------- 47 | # Displays a message (string) 48 | # 49 | # If the $sf_noexec environment variable is set, prefix the message with '(n)' 50 | # 51 | # Args: 52 | # $1 : message 53 | # Returns: Always 0 54 | # Displays: Message 55 | #----------------------------------------------------------------------------- 56 | 57 | function sf_msg 58 | { 59 | typeset prefix 60 | 61 | prefix='' 62 | [ -n "$sf_noexec" ] && prefix='(n)' 63 | __msg "$prefix$1" 64 | } 65 | 66 | ##---------------------------------------------------------------------------- 67 | # Display trace message 68 | # 69 | # If the $sf_verbose environment variable is set or $sf_verbose_level >= 1, 70 | # displays the message. 71 | # 72 | # Args: 73 | # $1 : message 74 | # Returns: Always 0 75 | # Displays: message if verbose mode is active, nothing if not 76 | #----------------------------------------------------------------------------- 77 | 78 | function sf_trace 79 | { 80 | [ -n "$sf_verbose" -o "$sf_verbose_level" -ge 1 ] && __msg ">>> $*" >&2 81 | } 82 | 83 | ##---------------------------------------------------------------------------- 84 | # Display debug message 85 | # 86 | # If $sf_verbose_level >= 2, displays the message. 87 | # 88 | # Args: 89 | # $1 : message 90 | # Returns: Always 0 91 | # Displays: message if verbose level set to debug (2) or more 92 | #----------------------------------------------------------------------------- 93 | 94 | function sf_debug 95 | { 96 | [ "$sf_verbose_level" -ge 2 ] && __msg "D>> $*" >&2 97 | } 98 | 99 | ##---------------------------------------------------------------------------- 100 | # Displays a message prefixed with spaces 101 | # 102 | # Args: 103 | # $1 : message 104 | # Returns: Always 0 105 | # Displays: message prefixed with spaces 106 | #----------------------------------------------------------------------------- 107 | 108 | function sf_msg1 109 | { 110 | sf_msg " $*" 111 | } 112 | 113 | ##---------------------------------------------------------------------------- 114 | # Displays a 'section' message 115 | # 116 | # This is a message prefixed with a linefeed and some hyphens. 117 | # To be used as paragraph/section title. 118 | # 119 | # Args: 120 | # $1 : message 121 | # Returns: Always 0 122 | # Displays: Message 123 | #----------------------------------------------------------------------------- 124 | 125 | function sf_msg_section 126 | { 127 | sf_msg '' 128 | sf_msg "--- $1" 129 | } 130 | 131 | ##---------------------------------------------------------------------------- 132 | # Displays a separator line 133 | # 134 | # Args: None 135 | # Returns: Always 0 136 | # Displays: separator line 137 | #----------------------------------------------------------------------------- 138 | 139 | function sf_separator 140 | { 141 | __msg "===================================================================" 142 | } 143 | 144 | ##---------------------------------------------------------------------------- 145 | # Display a new line 146 | # 147 | # Args: None 148 | # Returns: Always 0 149 | # Displays: new line 150 | #----------------------------------------------------------------------------- 151 | 152 | function sf_newline 153 | { 154 | __msg 155 | } 156 | 157 | ##---------------------------------------------------------------------------- 158 | # Displays a 'banner' message 159 | # 160 | # The message is displayed with an horizontal separator line above and below 161 | # 162 | # Args: 163 | # $1 : message 164 | # Returns: Always 0 165 | # Displays: message 166 | #----------------------------------------------------------------------------- 167 | 168 | function sf_banner 169 | { 170 | sf_newline 171 | sf_separator 172 | __msg " $1" 173 | sf_separator 174 | sf_newline 175 | } 176 | 177 | #============================================================================= 178 | # Section: User interaction 179 | #============================================================================= 180 | 181 | ##---------------------------------------------------------------------------- 182 | # Ask a question to the user 183 | # 184 | # Args: 185 | # $1 : Question 186 | # Returns: Always 0 187 | # Displays: message to stderr, answer to stdout 188 | #----------------------------------------------------------------------------- 189 | 190 | function sf_ask 191 | { 192 | echo "$SHELL" | grep bash >/dev/null 193 | if [ $? = 0 ] ; then 194 | echo -n "$1 " >&2 195 | else 196 | echo "$1 \c" >&2 197 | fi 198 | 199 | read answer 200 | __msg $answer 201 | } 202 | 203 | ##---------------------------------------------------------------------------- 204 | # Asks a 'yes/no' question, gets answer, and return yes/no code 205 | # 206 | # Works at least for questions in english, french, and german : 207 | # Accepts 'Y', 'O', and 'J' for 'yes' (upper or lowercase), and 208 | # anything different is considered as 'no' 209 | # 210 | # If the $sf_forceyes environment variable is set, the user is not asked 211 | # and the 'yes' code is returned. 212 | # 213 | # Args: 214 | # $1 : Question string 215 | # Returns: 0 for 'yes', 1 for 'no' 216 | # Displays: Question and typed answer if $sf_forceyes not set, nothing if 217 | # $sf_forceyes is set. 218 | #----------------------------------------------------------------------------- 219 | 220 | function sf_yn_question 221 | { 222 | typeset answer 223 | 224 | if [ -n "$sf_forceyes" ] ; then 225 | sf_debug "Forcing answer to 'yes'" 226 | return 0 227 | fi 228 | 229 | answer=`sf_ask "$1"` 230 | 231 | __msg 232 | [ "$answer" != o -a "$answer" != O \ 233 | -a "$answer" != y -a "$answer" != Y \ 234 | -a "$answer" != j -a "$answer" != J ] \ 235 | && return 1 236 | 237 | return 0 238 | } 239 | 240 | #============================================================================= 241 | 242 | # $sf_verbose remains for compatibility. $sf_verbose_level must 243 | # contain a numeric value. 244 | 245 | [ -z "${sf_verbose_level:+}" ] && sf_verbose_level=0 246 | 247 | export sf_verbose_level 248 | -------------------------------------------------------------------------------- /src/sf_net.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Network 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Suppresses the host name part from a FQDN 25 | # 26 | # Displays the input string without the beginning up to and including the 27 | # first '.'. 28 | # 29 | # Args: 30 | # $1: Input FQDN 31 | # Returns: Always 0 32 | # Displays: truncated string 33 | #----------------------------------------------------------------------------- 34 | 35 | function sf_domain_part 36 | { 37 | sed 's/^[^\.]*\.//' 38 | } 39 | 40 | ##---------------------------------------------------------------------------- 41 | # Extracts a hostname from an FQDN 42 | # 43 | # Removes everything from the first dot up to the end of the string 44 | # 45 | # Args: 46 | # $1: Input FQDN 47 | # Returns: Always 0 48 | # Displays: truncated string 49 | #----------------------------------------------------------------------------- 50 | 51 | function sf_host_part 52 | { 53 | sed 's/^\([^\.]*\)\..*$/\1/' 54 | } 55 | 56 | ##---------------------------------------------------------------------------- 57 | # Resolves an IP address through the DNS 58 | # 59 | # If the address cannot be resolved, displays nothing 60 | # 61 | # Args: 62 | # $1: IP address 63 | # $2: Optional. DNS server to ask 64 | # Returns: Always 0 65 | # Displays: Host name as returned by the DNS or nothing if address could 66 | # not be resolved. 67 | #----------------------------------------------------------------------------- 68 | 69 | function sf_dns_addr_to_name 70 | { 71 | ( [ -n "$2" && echo "server $2"; echo "$1" ) \ 72 | | nslookup 2>/dev/null | grep '^Name:' | head -1 \ 73 | | sed -e 's/^Name:[ ]*//g' 74 | } 75 | 76 | ##---------------------------------------------------------------------------- 77 | # Resolves a host name through the DNS 78 | # 79 | # If the name cannot be resolved, displays nothing 80 | # 81 | # Args: 82 | # $1: Host name to resolve 83 | # $2: Optional. DNS server to ask 84 | # Returns: Always 0 85 | # Displays: IP address as returned by the DNS or nothing if name could 86 | # not be resolved. 87 | #----------------------------------------------------------------------------- 88 | 89 | function sf_dns_name_to_addr 90 | { 91 | ( [ -n "$2" && echo "server $2"; echo "$1" ) \ 92 | | nslookup 2>/dev/null \ 93 | | grep '^Address:' | tail -n +2 | head -1 \ 94 | | sed -e 's/^Address:[ ]*//g' 95 | } 96 | 97 | ##---------------------------------------------------------------------------- 98 | # Get the primary address of the system 99 | # 100 | # This is an arbitrary choice, such as the address assigned to the first 101 | # network nterface. 102 | # Feel free to improve ! 103 | # 104 | # Args: none 105 | # Returns: Always 0 106 | # Displays: IP address or nothing if no address was found 107 | #----------------------------------------------------------------------------- 108 | 109 | function sf_primary_ip_address 110 | { 111 | typeset ifname 112 | 113 | case "`sf_os_family`" in 114 | linux) 115 | ifname=`ls -1 /sys/class/net | grep -v '^lo$' | head -1` 116 | [ -z "$ifname" ] && return 117 | if [ /usr/sbin/ip ] ; then 118 | ip -4 addr show dev $ifname | grep inet | sed 's,^.*inet \([^/]*\)/.*$,\1,' 119 | else 120 | ifconfig $ifname | grep 'inet addr:' | sed 's/^.*inet addr:\([^ ]*\) .*$/\1/' 121 | fi 122 | ;; 123 | *) 124 | sf_unsupported primary_ip_address 125 | ;; 126 | esac 127 | } 128 | 129 | ##------------------------------------------------ 130 | # Check connectivity with a host 131 | # 132 | # Args: 133 | # $1: Hostname 134 | # $2: Optional. String to use in error message - host function 135 | # Returns: 0 if OK, 1 if KO 136 | # Displays: Nothing 137 | #------------------------------------------------ 138 | 139 | function sf_net_host_is_reachable 140 | { 141 | typeset host desc 142 | 143 | host="$1" 144 | if [ -z "$host" ] ; then 145 | sf_warning "ms_host_is_reachable: host parameter not set" 146 | return 1 147 | fi 148 | 149 | desc="$2" 150 | [ -z "$desc" ] && desc="$host" 151 | 152 | sf_trace "Checking connectivity with $desc ($host)" 153 | 154 | #--- 155 | 156 | ping -c 1 "$host" >/dev/null 2>&1 157 | if [ $? != 0 ] ; then 158 | sf_warning "Cannot ping $desc ($host)" 159 | return 1 160 | fi 161 | sf_trace "$desc is reachable" 162 | 163 | #--- 164 | 165 | return 0 166 | } 167 | 168 | #============================================================================= 169 | -------------------------------------------------------------------------------- /src/sf_os.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: OS 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Computes and displays a string defining the curent system environment 25 | # 26 | # The displayed string is a combination of the OS name, version, system 27 | # architecture and may also depend on other parameters like, for instance, 28 | # the RedHat ES/AS branches. It is an equivalent of the 'channel' concept 29 | # used by RedHat. I personnally call it 'OS ID' for 'OS IDentifier' and use 30 | # it in every script where I need a single string to identify the system 31 | # environment the script is currently running on. 32 | # 33 | # If the current system is not recognized, the program aborts. 34 | # 35 | # By convention, environments recognized by this function support 36 | # the rest of the library. 37 | # 38 | # **Contributors welcome !** Feel free to enhance this function with additional 39 | # recognized systems, especially with other Linux distros, and send me your 40 | # patches. 41 | # 42 | # Args: None 43 | # Returns: Always 0 44 | # Displays: OS ID string 45 | #----------------------------------------------------------------------------- 46 | 47 | function sf_os_id 48 | { 49 | typeset sub version distrib res 50 | 51 | #-- Recognizes the current environment 52 | 53 | res='' 54 | version=`sf_os_version` 55 | distrib=`sf_os_distrib` 56 | 57 | res="${distrib}_${version}" 58 | 59 | if [ -f /etc/redhat-release ] ; then # Special case for RHEL/CentOS 60 | [ `sf_os_arch` = x86_64 ] && res="${res}_64" 61 | if [ "$version" -lt 5 ] ; then # AS/ES 62 | sub=`sed 's/^.* Linux \(.S\).*$/\1/' 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: File backup 21 | #---------------------------------------------------------------------------- 22 | # This feature is still under development: so far, only regular files and symbolic 23 | # links are supported. Other file types are ignored and not saved. 24 | #============================================================================= 25 | 26 | ##---------------------------------------------------------------------------- 27 | # Ensure save system is operational. 28 | # 29 | # This function must be called before any action upon the save db. 30 | # 31 | # If initialization fails, the program is aborted 32 | # 33 | # Args: None 34 | # Returns: Always 0 35 | # Displays: Nothing 36 | #---------------------------------------------------------------------------- 37 | 38 | function _sf_sav_init 39 | { 40 | if [ ! -d $_sf_save_tree ] ; then 41 | /bin/rm -rf $_sf_save_tree 42 | mkdir -p $_sf_save_tree 43 | chown root $_sf_save_tree 44 | chmod 700 $_sf_save_tree 45 | fi 46 | 47 | [ -d $_sf_save_tree ] \ 48 | || sf_fatal "Sysfunc error - Cannot initialize save system (cannot create file tree)" 49 | 50 | # No need to create $_sf_save_base dir explicitely, as it is done when creating 51 | # $_sf_save_tree. 52 | 53 | if [ ! -f $_sf_save_index ] ; then 54 | touch $_sf_save_index 55 | chown root $_sf_save_index 56 | chmod 600 $_sf_save_index 57 | fi 58 | [ -f $_sf_save_index ] \ 59 | || sf_fatal "Sysfunc error - Cannot initialize save system (cannot create index file)" 60 | 61 | } 62 | 63 | ##---------------------------------------------------------------------------- 64 | # Delete eveything that was saved on this host 65 | # 66 | # Args: None 67 | # Returns: Always 0 68 | # Displays: Nothing 69 | #---------------------------------------------------------------------------- 70 | 71 | function sf_sav_zap 72 | { 73 | [ -z "$sf_noexec" ] && /bin/rm -rf $_sf_save_base 74 | } 75 | 76 | ##---------------------------------------------------------------------------- 77 | # Saves a file 78 | # 79 | # No action if the **$sf_nosave** environment variable is set to a non-empty string. 80 | # 81 | # If the input arg is the path of an existing regular file or symbolic link, 82 | # the file is saved. 83 | # 84 | # If the file cannot be saved (copy or dir creation failure), a fatal error 85 | # is raised and the program is aborted. 86 | # 87 | # Args: 88 | # $1 : Path. Beware! Arg can contain any char (including blanks) 89 | # Returns: Always 0 90 | # Displays: Info msg 91 | #----------------------------------------------------------------------------- 92 | 93 | function sf_save 94 | { 95 | typeset type source tbase target n mode owner group mtime size sum line tpath 96 | typeset tmp1 tmp2 status pattern dir 97 | 98 | source="$1" 99 | 100 | _sf_sav_init 101 | 102 | [ "X$sf_nosave" = X ] || return 0 103 | 104 | type=`sf_file_type "$source"` || return 0 105 | source="`sf_file_realpath \"$source\"`" # Convert $source to absolute path 106 | 107 | #-- Check if path is excluded 108 | 109 | if [ -n "$sf_save_excluded_paths" ] ; then 110 | for pattern in $sf_save_excluded_paths ; do 111 | echo "$source" | grep "$pattern" >/dev/null && return 0 112 | done 113 | fi 114 | 115 | #-- Check if this file was already saved during this session 116 | 117 | tmp1=`sf_tmpfile` 118 | tmp2=`sf_tmpfile` 119 | [ -f "$_sf_saved_list" ] && sort <$_sf_saved_list >$tmp1 120 | echo $source >$tmp2 121 | status="`comm -12 $tmp1 $tmp2 2>&1`" 122 | \rm -rf $tmp1 $tmp2 123 | [ "X$status" = X ] || return 0 124 | echo $source >>$_sf_saved_list 125 | 126 | case "$type" in 127 | R) # Regular file 128 | sf_msg1 "$source: Saving regular file" 129 | tbase="$source" 130 | target="$tbase" 131 | n=0 132 | while true; do 133 | tpath="$_sf_save_tree$target" 134 | if [ -f "$tpath" ] ; then 135 | if diff "$source" "$tpath" >/dev/null 2>&1 ; then 136 | # If same content 137 | break 138 | else 139 | n=`expr $n + 1` 140 | target="$tbase.$n" 141 | fi 142 | else 143 | dir="`dirname \"$tpath\"`" 144 | if [ -z "$sf_noexec" ] ; then 145 | [ -d "$dir" ] || mkdir -p "$dir" 146 | [ -d "$dir" ] || sf_fatal "$source: Cannot save file (directory creation failed)" 147 | cp "$source" "$tpath" || sf_fatal "$source: Cannot save file (copy failed)" 148 | chown root "$tpath" 149 | chmod 600 "$tpath" 150 | fi 151 | break 152 | fi 153 | done 154 | mode=`sf_file_mode "$source"` 155 | owner=`sf_file_owner "$source"` 156 | group=`sf_file_group "$source"` 157 | mtime=`sf_file_mtime "$source"` 158 | size=`sf_file_size "$tpath"` 159 | sum=`sf_file_checksum "$tpath"` 160 | line="$target|$size|$sum|$mode|$owner|$group|$mtime" 161 | ;; 162 | 163 | L) # Symbolic link 164 | sf_msg1 "$source: Saving symbolic link" 165 | target="`sf_file_readlink \"$source\"`" 166 | line="$target" 167 | ;; 168 | 169 | *) return 0;; # Ignore other types 170 | esac 171 | 172 | #-- Record in index file 173 | 174 | [ -z "$sf_noexec" ] && echo "$type|$source|`sf_tm_timestamp`|$line" >>$_sf_save_index 175 | 176 | return 0 177 | } 178 | 179 | ##---------------------------------------------------------------------------- 180 | # Save system cleanup 181 | # 182 | # Called by [function:cleanup] 183 | # 184 | # Args: None 185 | # Returns: Always 0 186 | # Displays: Nothing 187 | #----------------------------------------------------------------------------- 188 | 189 | function _sf_save_cleanup 190 | { 191 | [ -n "$_sf_saved_list" -a -z "$_sf_save_inherited" ] && \rm -rf $_sf_saved_list 192 | } 193 | 194 | #----------------------------------------------------------------------------- 195 | 196 | _sf_save_base=/var/sysfunc.save 197 | _sf_save_index=$_sf_save_base/index.dat 198 | _sf_save_tree=$_sf_save_base/tree 199 | 200 | if [ -n "${sf_save_inherit:+}" -a -n "${_sf_saved_list:+}" -a -f "${_sf_saved_list:-}" ] ; then 201 | _sf_save_inherited=y 202 | else 203 | _sf_save_inherited='' 204 | _sf_saved_list=/tmp/._sf_saved.$$ 205 | fi 206 | 207 | sf_save_excluded_paths=${sf_save_excluded_paths-^/tmp/ ^/var/tmp/} 208 | 209 | export _sf_save_base _sf_save_index _sf_save_tree _sf_save_inherited \ 210 | _sf_saved_list sf_save_excluded_paths 211 | 212 | #============================================================================= 213 | -------------------------------------------------------------------------------- /src/sf_soft.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Software packages 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Check if software exists (installed or available for installation) 25 | # 26 | # Args: 27 | # $1: Software name 28 | # Returns: 0 if software exists, 1 if not 29 | # Displays: Nothing 30 | #----------------------------------------------------------------------------- 31 | 32 | function sf_soft_exists 33 | { 34 | [ -z "$sf_yum" ] && sf_unsupported sf_soft_exists 35 | 36 | $sf_yum list $1 >/dev/null 2>&1 || return 1 37 | return 0 38 | } 39 | 40 | ##---------------------------------------------------------------------------- 41 | # List installed software 42 | # 43 | # Returns a sorted list of installed software 44 | # 45 | # Linux output: (name-version-release.arch) 46 | # 47 | # Args: none 48 | # Returns: Always 0 49 | # Displays: software list 50 | #----------------------------------------------------------------------------- 51 | 52 | function sf_soft_list 53 | { 54 | ( 55 | if [ -n "$sf_rpm" ] ; then 56 | $sf_rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' 57 | fi 58 | ) | sort 59 | } 60 | 61 | ##---------------------------------------------------------------------------- 62 | # Check if a software is installed 63 | # 64 | # Args: 65 | # $1: Software name 66 | # Returns: 0 if software is installed, 1 if not. 67 | # Displays: Nothing 68 | #----------------------------------------------------------------------------- 69 | 70 | function sf_soft_is_installed 71 | { 72 | [ -z "$sf_rpm" ] && sf_unsupported sf_soft_is_installed 73 | 74 | $sf_rpm -q "$1" >/dev/null 2>&1 || return 1 75 | return 0 76 | } 77 | 78 | ##---------------------------------------------------------------------------- 79 | # Check if a newer version of a software is available 80 | # 81 | # Note : if the software is not installed, it is not considered as upgradeable 82 | # 83 | # Args: 84 | # $1: Software name 85 | # Returns: 0 if the software is upgradeable, !=0 if not. 86 | # Displays: Nothing 87 | #----------------------------------------------------------------------------- 88 | 89 | function sf_soft_is_upgradeable 90 | { 91 | sf_soft_available_version "$1" >/dev/null 2>&1 92 | } 93 | 94 | ##---------------------------------------------------------------------------- 95 | # Check if a software is installed and the latest version 96 | # 97 | # Args: 98 | # $1: Software name 99 | # Returns: 0 if software is up-to-date, 1 if not installed, 2 if upgradeable. 100 | # Displays: Nothing 101 | #----------------------------------------------------------------------------- 102 | 103 | function sf_soft_is_up_to_date 104 | { 105 | sf_soft_is_installed $1 || return 1 106 | sf_soft_is_upgradeable $1 && return 2 107 | return 0 108 | } 109 | 110 | ##---------------------------------------------------------------------------- 111 | # Get the available version of an upgradeable package 112 | # 113 | # Args: 114 | # $1: Software name 115 | # Returns: 0 if an update is available, 1 if not installed, 2 if up-to-date 116 | # Displays: Available version if one exists, nothing if not 117 | #----------------------------------------------------------------------------- 118 | 119 | function sf_soft_available_version 120 | { 121 | typeset buf 122 | 123 | [ -z "$sf_yum" ] && sf_unsupported sf_soft_available_version 124 | 125 | sf_soft_is_installed $1 || return 1 126 | buf="`$sf_yum list available $1 2>/dev/null`" 127 | 128 | # We need to check for an 'Available Packages' string because output can contain 129 | # messages issued when reloading metadata. 130 | 131 | echo "$buf" | grep '^Available Packages$' >/dev/null || return 2 132 | echo "$buf" | tail -1 | awk '{ print $2 }' 133 | } 134 | 135 | ##---------------------------------------------------------------------------- 136 | # Install software(s) if not already present on the host 137 | # 138 | # If a software is installed but not up to date, it is not upgraded. 139 | # 140 | # Args: 141 | # $*: Software name(s) 142 | # Returns: Return code from yum command 143 | # Displays: Info msg 144 | #----------------------------------------------------------------------------- 145 | 146 | function sf_soft_install 147 | { 148 | typeset _pkg _to_install ret 149 | 150 | [ -z "$sf_yum" ] && sf_unsupported sf_soft_install 151 | 152 | _to_install='' 153 | 154 | for _pkg 155 | do 156 | if ! sf_soft_is_installed "$_pkg" ; then 157 | _to_install="$_to_install $_pkg" 158 | fi 159 | done 160 | 161 | if [ -n "$_to_install" ] ; then 162 | sf_msg1 "Installing $_to_install ..." 163 | if [ -z "$sf_noexec" ] ; then 164 | $sf_yum install $_to_install 165 | ret=$? 166 | fi 167 | fi 168 | 169 | return $ret 170 | } 171 | 172 | ##---------------------------------------------------------------------------- 173 | # Install or upgrade software(s) 174 | # 175 | # For each of the software names supplied as arguments : 176 | # 177 | # - if the software is not installed, install it, 178 | # - if the software is installed and upgradeable, upgrade it, 179 | # - if the software is up-to-date, do nothing. 180 | # 181 | # Args: 182 | # $*: Software name(s) 183 | # Returns: 0 if OK. !=0 if not 184 | # Displays: Info msg 185 | #----------------------------------------------------------------------------- 186 | 187 | function sf_soft_install_upgrade 188 | { 189 | typeset _pkg _to_install _to_update ret 190 | 191 | [ -z "$sf_yum" ] && sf_unsupported sf_soft_install_upgrade 192 | 193 | _to_install='' 194 | _to_update='' 195 | 196 | for _pkg 197 | do 198 | if ! sf_soft_is_installed "$_pkg" ; then 199 | _to_install="$_to_install $_pkg" 200 | else 201 | if sf_soft_is_upgradeable "$_pkg" ; then 202 | _to_update="$_to_update $_pkg" 203 | fi 204 | fi 205 | done 206 | 207 | if [ -n "$_to_update" ] ; then 208 | sf_msg1 "Upgrading $_to_update ..." 209 | if [ -z "$sf_noexec" ] ; then 210 | $sf_yum upgrade $_to_update 211 | ret=$? 212 | fi 213 | fi 214 | 215 | if [ -n "$_to_install" ] ; then 216 | sf_msg1 "Installing $_to_install ..." 217 | if [ -z "$sf_noexec" ] ; then 218 | $sf_yum install $_to_install 219 | ret=`expr $ret + $?` 220 | fi 221 | fi 222 | 223 | return $ret 224 | } 225 | 226 | ##---------------------------------------------------------------------------- 227 | # Uninstall software(s) (including dependencies) 228 | # 229 | # Nothing is done for softwares which are not present on the host. 230 | # 231 | # Args: 232 | # $*: Software name(s) 233 | # Returns: Return code from yum command 234 | # Displays: Info msg 235 | #----------------------------------------------------------------------------- 236 | 237 | function sf_soft_uninstall 238 | { 239 | typeset _pkg ret 240 | 241 | [ -z "$sf_yum" ] && sf_unsupported sf_soft_uninstall 242 | 243 | for _pkg ; do 244 | if sf_soft_is_installed "$_pkg" ; then 245 | sf_msg1 "Uninstalling $_pkg ..." 246 | if [ -z "$sf_noexec" ] ; then 247 | $sf_yum remove "$_pkg" 248 | ret=$? 249 | fi 250 | fi 251 | done 252 | 253 | return $ret 254 | } 255 | 256 | ##---------------------------------------------------------------------------- 257 | # Uninstall software(s) (ignoring and bypassing dependencies) 258 | # 259 | # Nothing is done for softwares which are not present on the host. 260 | # 261 | # Args: 262 | # $*: Software name(s) 263 | # Returns: Always 0 264 | # Displays: Info msg 265 | #----------------------------------------------------------------------------- 266 | 267 | function sf_soft_remove 268 | { 269 | typeset _pkg 270 | 271 | [ -z "$sf_rpm" ] && sf_unsupported sf_soft_remove 272 | 273 | for _pkg ; do 274 | if sf_soft_is_installed "$_pkg" ; then 275 | sf_msg1 "Uninstalling $_pkg ..." 276 | [ -z "$sf_noexec" ] && $sf_rpm -e --nodeps "$_pkg" 277 | fi 278 | done 279 | 280 | return 0 281 | } 282 | 283 | ##---------------------------------------------------------------------------- 284 | # Reinstall software(s), even at same version 285 | # 286 | # Args: 287 | # $*: Software name(s) 288 | # Returns: Always 0 289 | # Displays: Info msg 290 | #----------------------------------------------------------------------------- 291 | 292 | function sf_soft_reinstall 293 | { 294 | typeset _pkg 295 | 296 | for _pkg ; do 297 | sf_soft_remove "$_pkg" 298 | sf_soft_install_upgrade "$_pkg" 299 | done 300 | 301 | return 0 302 | } 303 | 304 | ##---------------------------------------------------------------------------- 305 | # get version of an installed software 306 | # 307 | # Args: 308 | # $1: Software name 309 | # Returns: 0 if software is installed, 1 otherwise. 310 | # Displays: Software version (nothing if soft is not installed) 311 | #----------------------------------------------------------------------------- 312 | 313 | function sf_soft_version 314 | { 315 | typeset _pkg 316 | _pkg=$1 317 | 318 | [ -z "$sf_rpm" ] && sf_unsupported sf_soft_version 319 | 320 | sf_soft_is_installed "$_pkg" || return 1 321 | 322 | $sf_rpm -q --qf '%{VERSION}-%{RELEASE}\n' $_pkg 2>/dev/null 323 | 324 | return 0 325 | } 326 | 327 | ##---------------------------------------------------------------------------- 328 | # Clean the software installation cache 329 | # 330 | # Args: None 331 | # Returns: Always 0 332 | # Displays: Nothing 333 | #----------------------------------------------------------------------------- 334 | 335 | function sf_soft_clean_cache 336 | { 337 | [ -d /var/cache/yum ] && \rm -rf /var/cache/yum/* 338 | } 339 | 340 | ##---------------------------------------------------------------------------- 341 | # List defined software repository names 342 | # 343 | # Args: None 344 | # Returns: Always 0 345 | # Displays: List of software repositories, one per line 346 | #----------------------------------------------------------------------------- 347 | # Note: we prefer parsing the yum config instead of using the 'repolist' cmd 348 | # because: 1. 'repolist' does not exist in yum v2 (RHEL 4), and 2. repolist 349 | # refreshes the cache, which fails if the repo is not reachable. The '-C' option 350 | # can disable the cache refresh but will cause the cmd to fail if the cache is 351 | # empty. 352 | # So, in short, this is the only way I found to list enabled repositories when 353 | # the cache is empty (after a clean). 354 | #----------------------------------------------------------------------------- 355 | 356 | function sf_soft_repo_list 357 | { 358 | [ -z "$sf_yum" ] && sf_unsupported sf_soft_repo_list 359 | 360 | cat /etc/yum.conf /etc/yum.repos.d/* 2>/dev/null \ 361 | | sf_txt_cleanup \ 362 | | awk ' 363 | BEGIN { repo=""; } 364 | /^enabled=1/ { print repo; } 365 | /^\[/ { repo=substr($1,2,length($1)-2); }' 366 | } 367 | 368 | #============================================================================= 369 | -------------------------------------------------------------------------------- /src/sf_svc.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Services 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Check if the system is running systemd 25 | # 26 | # Args: None 27 | # Returns: 0 if running systemd, 1 if not 28 | # Displays: Nothing 29 | ##---------------------------------------------------------------------------- 30 | 31 | function sf_svc_running_systemd 32 | { 33 | test -d /run/systemd/system 34 | } 35 | 36 | ##---------------------------------------------------------------------------- 37 | # Check if a service is enabled on boot 38 | # 39 | # On Linux, check for current runlevel. 40 | # On Solaris, check for level 3. 41 | # 42 | # Args: 43 | # $1: Service name 44 | # Returns: 0 if enabled, 1 if disabled, 2 if not installed 45 | # Displays: Nothing 46 | ##---------------------------------------------------------------------------- 47 | 48 | function sf_svc_is_enabled 49 | { 50 | typeset _svc _base _script _snum _knum 51 | _svc=$1 52 | 53 | sf_svc_is_installed $_svc || return 2 54 | 55 | case `sf_os_family` in 56 | linux) 57 | if sf_svc_running_systemd ; then 58 | systemctl --quiet is-enabled $_svc || return 1 59 | else 60 | chkconfig $_svc || return 1 61 | fi 62 | ;; 63 | sunos) 64 | # We don't use states as defined on 'chkconfig' line in service 65 | # script, as states do not correspond on Solaris. 66 | _base=`sf_svc_base` 67 | _script=`sf_svc_script $_svc` 68 | grep '^# *chkconfig:' $_script | head -1 \ 69 | | sed 's/^.*: *[^ ][^ ]* *//' | read _snum _knum 70 | [ -f $_base/rc3.d/S$_snum$_svc ] || return 1 71 | ;; 72 | *) 73 | sf_unsupported sf_svc_is_enabled 74 | ;; 75 | esac 76 | return 0 77 | } 78 | 79 | ##---------------------------------------------------------------------------- 80 | # Enable service start/stop at system boot/shutdown 81 | # 82 | # Args: 83 | # $*: Service names 84 | # Returns: Always 0 85 | # Displays: Info msg 86 | #----------------------------------------------------------------------------- 87 | 88 | function sf_svc_enable 89 | { 90 | typeset _svc _base _script _state _snum _knum 91 | 92 | _base=`sf_svc_base` 93 | for _svc in $* 94 | do 95 | if ! sf_svc_is_installed $_svc ; then 96 | sf_error "$_svc: No such service" 97 | continue 98 | fi 99 | 100 | case `sf_os_family` in 101 | linux) 102 | if ! sf_svc_is_enabled $_svc ; then 103 | sf_msg1 "Enabling service $_svc" 104 | if [ -z "$sf_noexec" ] ; then 105 | if sf_svc_running_systemd ; then 106 | systemctl enable $_svc 107 | else 108 | /sbin/chkconfig --add $_svc 109 | /sbin/chkconfig $_svc reset 110 | /sbin/chkconfig $_svc on 111 | fi 112 | fi 113 | fi 114 | ;; 115 | sunos) 116 | # We don't use states as defined on 'chkconfig' line in service 117 | # script, as states do not correspond on Solaris. 118 | _script=`sf_svc_script $_svc` 119 | grep '^# *chkconfig:' $_script | head -1 \ 120 | | sed 's/^.*: *[^ ][^ ]* *//' | read _snum _knum 121 | for _state in 3 # Start 122 | do 123 | sf_check_link ../init.d/$_svc $_base/rc$_state.d/S$_snum$_svc 124 | done 125 | for _state in 0 1 2 S # Kill 126 | do 127 | sf_check_link ../init.d/$_svc $_base/rc$_state.d/K$_knum$_svc 128 | done 129 | ;; 130 | *) 131 | sf_unsupported sf_svc_enable 132 | ;; 133 | esac 134 | done 135 | } 136 | 137 | ##---------------------------------------------------------------------------- 138 | # Disable service start/stop at system boot/shutdown 139 | # 140 | # Args: 141 | # $*: Service names 142 | # Returns: Always 0 143 | # Displays: Info msg 144 | #----------------------------------------------------------------------------- 145 | 146 | function sf_svc_disable 147 | { 148 | typeset _svc _base _script _state _snum _knum _pattern _f 149 | 150 | _base=`sf_svc_base` 151 | for _svc in $* 152 | do 153 | if ! sf_svc_is_installed $_svc ; then 154 | sf_trace "$_svc: No such service" 155 | continue 156 | fi 157 | 158 | case `sf_os_family` in 159 | linux) 160 | if sf_svc_is_enabled $_svc ; then 161 | sf_msg1 "Disabling service $_svc" 162 | if [ -z "$sf_noexec" ] ; then 163 | if sf_svc_running_systemd ; then 164 | systemctl disable $_svc 165 | else 166 | /sbin/chkconfig --del $_svc 167 | fi 168 | fi 169 | fi 170 | ;; 171 | sunos) 172 | _pattern="$_base/rc?.d/[KS]??$_svc" 173 | _f="`ls -l $_pattern | head -1`" 174 | if [ -f "$_f" ] ; then 175 | sf_msg1 "$_svc: Disabling service" 176 | sf_delete $_pattern 177 | fi 178 | ;; 179 | *) 180 | sf_unsupported sf_svc_disable 181 | ;; 182 | esac 183 | done 184 | } 185 | 186 | ##---------------------------------------------------------------------------- 187 | # Install a service script (script to start/stop a service) 188 | # 189 | # Args: 190 | # $1: Source script 191 | # $2: Service name 192 | # Returns: Always 0 193 | # Displays: Info msg 194 | #----------------------------------------------------------------------------- 195 | 196 | function sf_svc_install 197 | { 198 | sf_svc_running_systemd && return 0 199 | 200 | sf_check_copy "$1" `sf_svc_script $2` 755 201 | } 202 | 203 | ##---------------------------------------------------------------------------- 204 | # Uninstall a service script (script to start/stop a service) 205 | # 206 | # Args: 207 | # $1: Service name 208 | # Returns: Always 0 209 | # Displays: Info msg 210 | #----------------------------------------------------------------------------- 211 | 212 | function sf_svc_uninstall 213 | { 214 | sf_svc_stop $1 215 | sf_svc_disable $1 216 | sf_svc_running_systemd && return 0 217 | sf_delete `sf_svc_script $1` 218 | } 219 | 220 | ##---------------------------------------------------------------------------- 221 | # Check if a service is installed 222 | # 223 | # Args: 224 | # $1: Service name 225 | # Returns: 0 is installed, 1 if not 226 | # Displays: Nothing 227 | #----------------------------------------------------------------------------- 228 | 229 | function sf_svc_is_installed 230 | { 231 | if sf_svc_running_systemd ; then 232 | systemctl status $1 2>&1 | grep 'Loaded: not-found' >/dev/null && return 1 233 | return 0 234 | else 235 | [ -x "`sf_svc_script $1`" ] 236 | return $? 237 | fi 238 | } 239 | 240 | ##---------------------------------------------------------------------------- 241 | # Start a service 242 | # 243 | # Note that 'noexec' does not disable starting/stopping services. 244 | # 245 | # Args: 246 | # $1: Service name 247 | # Returns: Return code from script execution 248 | # Displays: Output from service script 249 | #----------------------------------------------------------------------------- 250 | 251 | function sf_svc_start 252 | { 253 | if sf_svc_is_installed "$1" ; then 254 | if sf_svc_running_systemd ; then 255 | systemctl start $1 256 | else 257 | `sf_svc_script $1` start 258 | fi 259 | else 260 | sf_error "$1: Service is not installed" 261 | fi 262 | } 263 | 264 | ##---------------------------------------------------------------------------- 265 | # Stop a service 266 | # 267 | # Note that 'noexec' does not disable starting/stopping services. 268 | # 269 | # Args: 270 | # $1: Service name 271 | # Returns: Return code from script execution 272 | # Displays: Output from service script 273 | #----------------------------------------------------------------------------- 274 | 275 | function sf_svc_stop 276 | { 277 | if sf_svc_is_installed "$1" ; then 278 | if sf_svc_running_systemd ; then 279 | systemctl stop $1 280 | else 281 | `sf_svc_script $1` stop 282 | fi 283 | else 284 | sf_error "$1: Service is not installed" 285 | fi 286 | } 287 | 288 | ##---------------------------------------------------------------------------- 289 | # Restart a service 290 | # 291 | # Note that 'noexec' does not disable starting/stopping services. 292 | # 293 | # Args: 294 | # $1: Service name 295 | # Returns: 0 if OK, return code of failed command if KO 296 | # Displays: Output from service script(s) 297 | #----------------------------------------------------------------------------- 298 | 299 | function sf_svc_restart 300 | { 301 | local ret 302 | 303 | ret=0 304 | if sf_svc_is_installed "$1" ; then 305 | if sf_svc_running_systemd ; then 306 | systemctl restart $1 307 | ret=$? 308 | else 309 | # Cannot rely on a 'restart' action because it is not standard 310 | if sf_svc_is_up "$1" ; then 311 | sf_svc_stop "$1" 312 | ret=$? 313 | fi 314 | if [ $ret = 0 ] ; then 315 | sf_svc_start "$1" 316 | ret=$? 317 | else 318 | sf_error "Won't start service "$1" because stop procedure failed" 319 | fi 320 | fi 321 | else 322 | sf_error "$1: Service is not installed" 323 | fi 324 | 325 | return $ret 326 | } 327 | 328 | ##---------------------------------------------------------------------------- 329 | # Check if a service is running 330 | # 331 | # Args: 332 | # $1: Service name 333 | # Returns: 0 if service is running, 1 if stopped, 2 if not installed 334 | # Displays: Nothing 335 | #----------------------------------------------------------------------------- 336 | 337 | function sf_svc_is_up 338 | { 339 | typeset _svc 340 | _svc=$1 341 | 342 | sf_svc_is_installed $_svc || return 2 343 | 344 | if sf_svc_running_systemd ; then 345 | systemctl --quiet is-active $_svc 346 | [ $? = 0 ] && return 0 347 | return 1 348 | fi 349 | 350 | case `sf_os_family` in 351 | linux) 352 | service $_svc status >/dev/null 2>&1 || return 1 353 | ;; 354 | *) 355 | sf_unsupported sf_svc_is_up 356 | ;; 357 | esac 358 | return 0 359 | } 360 | 361 | ##---------------------------------------------------------------------------- 362 | # Display the base directory of service scripts 363 | # 364 | # Args: None 365 | # Returns: Always 0 366 | # Displays: String 367 | #----------------------------------------------------------------------------- 368 | 369 | function sf_svc_base 370 | { 371 | case `sf_os_family` in 372 | linux) 373 | echo /etc/rc.d ;; 374 | sunos) 375 | echo /etc ;; 376 | hp-ux) 377 | echo /sbin ;; 378 | *) 379 | sf_unsupported sf_svc_base ;; 380 | esac 381 | } 382 | 383 | ##---------------------------------------------------------------------------- 384 | # Display the full path of the script corresponding to a given service 385 | # 386 | # Args: 387 | # $1: Service name 388 | # Returns: Always 0 389 | # Displays: Script path 390 | #----------------------------------------------------------------------------- 391 | 392 | function sf_svc_script 393 | { 394 | echo `sf_svc_base`/init.d/$1 395 | } 396 | 397 | #============================================================================= 398 | -------------------------------------------------------------------------------- /src/sf_time.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | 20 | #============================================================================= 21 | # Section: Time and date 22 | #============================================================================= 23 | 24 | ##---------------------------------------------------------------------------- 25 | # Display normalized time string for current time (local or UTC) 26 | # 27 | # Local time is the default. If the SF_TM_UTC environment variable is set to a 28 | # non empty value, UTC time is displayed. 29 | # 30 | # Default format: DD-Mmm-YYYY HH:MM:SS () 31 | # 32 | # Args: 33 | # $1: Optional. Date format (without the leading '+'). See date(1) man page 34 | # for more details on macros supported in format string. 35 | # Returns: date command return code (!=0 if syntax error in format) 36 | # Displays: Time string 37 | #----------------------------------------------------------------------------- 38 | 39 | function sf_tm_now 40 | { 41 | typeset opt format 42 | 43 | opt='' 44 | [ "X${SF_TM_UTC:-}" = X ] || opt='-u' 45 | 46 | format='%d-%b-%Y %H:%M:%S (%s)' 47 | [ "X$1" = X ] || format="$1" 48 | 49 | date $opt "+$format" 50 | } 51 | 52 | ##---------------------------------------------------------------------------- 53 | # Display Unix current time (Seconds since Epoch) 54 | # 55 | # Args: None 56 | # Returns: 0 57 | # Displays: Time string 58 | #----------------------------------------------------------------------------- 59 | 60 | function sf_tm_timestamp 61 | { 62 | sf_tm_now '%s' 63 | } 64 | 65 | ##---------------------------------------------------------------------------- 66 | # Display current date as 'DD-Mmm-YYYY' 67 | # 68 | # Local time is the default. If the SF_TM_UTC environment variable is set to a 69 | # non empty value, UTC time is displayed. This will change date if time is near 70 | # midnight and local/utc times correspond to different dates. 71 | # 72 | # Args: None 73 | # Returns: 0 74 | # Displays: Time string 75 | #----------------------------------------------------------------------------- 76 | 77 | function sf_tm_date 78 | { 79 | sf_tm_now '%d-%b-%Y' 80 | } 81 | 82 | #============================================================================= 83 | -------------------------------------------------------------------------------- /src/sf_tmp.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Temporary file management 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Deletes every temporary files 25 | # 26 | # This function is automatically called by [function:cleanup] 27 | # 28 | # Args: none 29 | # Returns: Always 0 30 | # Displays: nothing 31 | #----------------------------------------------------------------------------- 32 | 33 | function _sf_tmp_cleanup 34 | { 35 | if [ -f "$_sf_tmpfile_list" ] ; then 36 | \rm -rf `cat $_sf_tmpfile_list` $_sf_tmpfile_list 37 | fi 38 | } 39 | 40 | ##---------------------------------------------------------------------------- 41 | # Returns an unused temporary path 42 | # 43 | # ### This function is deprecated. Please use [function:tmpfile] or [function:tmpdir] instead 44 | # 45 | # The returned path can then be used to create a directory or a file. 46 | # 47 | # Args: none 48 | # Returns: Always 0 49 | # Displays: An unused temporary path 50 | #----------------------------------------------------------------------------- 51 | 52 | function sf_get_tmp 53 | { 54 | typeset n f 55 | 56 | n=0 57 | while true 58 | do 59 | f="$_sf_tmpfile_prefix$n" 60 | [ -e $f ] || break 61 | n=`expr $n + 1` 62 | done 63 | 64 | echo $f 65 | echo $f >>$_sf_tmpfile_list 66 | } 67 | 68 | ##---------------------------------------------------------------------------- 69 | # Creates an empty temporary file and returns its path 70 | # 71 | # Args: none 72 | # Returns: Always 0 73 | # Displays: Temporary file path 74 | #----------------------------------------------------------------------------- 75 | 76 | function sf_tmpfile 77 | { 78 | typeset f 79 | 80 | f=`sf_get_tmp` 81 | touch $f 82 | echo $f 83 | } 84 | 85 | ##---------------------------------------------------------------------------- 86 | # Creates an empty temporary dir and returns its path 87 | # 88 | # Args: none 89 | # Returns: Always 0 90 | # Displays: Temporary dir path 91 | #----------------------------------------------------------------------------- 92 | 93 | function sf_tmpdir 94 | { 95 | typeset f 96 | 97 | f=`sf_get_tmp` 98 | mkdir $f 99 | echo $f 100 | } 101 | 102 | #============================================================================= 103 | # Note: Each process must have its own list and prefix 104 | 105 | _sf_tmpfile_prefix="/tmp/._sf.$$.tmp." 106 | _sf_tmpfile_list="/tmp/._sf.$$.tmplist" 107 | -------------------------------------------------------------------------------- /src/sf_tune.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Performance tuning 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Get active tuning profile 25 | # 26 | # Args: None 27 | # Returns: 0 if an active profile is set, !=0 if not 28 | # Displays: Name of active profile 29 | ##---------------------------------------------------------------------------- 30 | 31 | function sf_tune_active_profile 32 | { 33 | [ -x /usr/sbin/tuned-adm ] || return 1 34 | 35 | /usr/sbin/tuned-adm active | sed 's/^.*: //g' 36 | } 37 | 38 | ##---------------------------------------------------------------------------- 39 | # Activate a tuning profile 40 | # 41 | # Args: 42 | # $1: Profile name 43 | # Returns: Return code from tuned-adm 44 | # Displays: Nothing 45 | ##---------------------------------------------------------------------------- 46 | 47 | function sf_tune_set_profile 48 | { 49 | [ -x /usr/sbin/tuned-adm ] || return 1 50 | 51 | /usr/sbin/tuned-adm profile $1 52 | } 53 | 54 | ##---------------------------------------------------------------------------- 55 | # Activate a tuning profile 56 | # 57 | # Args: None 58 | # Returns: 0 if tuned-adm is present, !=0 if not 59 | # Displays: List of defined profiles, 1 per line 60 | ##---------------------------------------------------------------------------- 61 | 62 | function sf_tune_profile_list 63 | { 64 | [ -x /usr/sbin/tuned-adm ] || return 1 65 | 66 | /usr/sbin/tuned-adm list | grep '^-' | sed 's/^- //' 67 | } 68 | 69 | #============================================================================= 70 | -------------------------------------------------------------------------------- /src/sf_user.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Users and groups 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Change a user's password 25 | # 26 | # Works on HP-UX, Solaris, and Linux. 27 | # 28 | # Replaces an encrypted passwd in /etc/passwd or /etc/shadow. 29 | # 30 | # TODO: Unify with AIX and autodetect the file to use (passwd/shadow) 31 | # 32 | # Args: 33 | # $1: Username 34 | # $2: Encrypted password 35 | # $3: File path 36 | # Returns: Always 0 37 | # Displays: Nothing 38 | #----------------------------------------------------------------------------- 39 | 40 | function sf_set_passwd 41 | { 42 | typeset file user pass qpass 43 | 44 | user="$1" 45 | pass="$2" 46 | file="$3" 47 | 48 | qpass=`echo "$pass" | sed 's!/!\\\\/!g'` 49 | 50 | if [ -z "$sf_noexec" ] ; then 51 | ed $file </dev/null 2>&1 52 | /^$user:/ 53 | s/^$user:[^:]*:/$user:$qpass:/ 54 | w 55 | q 56 | EOF 57 | fi 58 | } 59 | 60 | ##---------------------------------------------------------------------------- 61 | # Set an AIX password 62 | # 63 | # TODO: Unify with other supported OS 64 | # 65 | # Args: 66 | # $1: Username 67 | # $2: Encrypted password 68 | # Returns: Always 0 69 | # Displays: nothing 70 | #----------------------------------------------------------------------------- 71 | 72 | function sf_set_passwd_aix 73 | { 74 | typeset user pass qpass 75 | 76 | user="$1" 77 | pass="$2" 78 | qpass=`echo "$pass" | sed 's!/!\\\\/!g'` 79 | 80 | if [ -z "$sf_noexec" ]; then 81 | pwdadm -f NOCHECK $user # to create the account if needed 82 | 83 | ed /etc/security/passwd <<-EOF >/dev/null 2>&1 84 | /^$user:/ 85 | /password =/ 86 | s/=.*$/= $qpass/ 87 | /flags =/ 88 | s/=.*$/=/ 89 | w 90 | q 91 | EOF 92 | fi 93 | } 94 | 95 | ##---------------------------------------------------------------------------- 96 | # Create a user group 97 | # 98 | # If the group does already exist, nothing is done, even if existing members 99 | # differ from the supplied list. 100 | # 101 | # Args: 102 | # $1: Group name 103 | # $2: Group Id 104 | # $3: Optional. Group members, separated by commas 105 | # Returns: Status from system command 106 | # Displays: Info msg 107 | #----------------------------------------------------------------------------- 108 | 109 | function sf_create_group 110 | { 111 | typeset rc i 112 | rc=0 113 | 114 | case `sf_os_family` in 115 | aix) 116 | if ! lsgroup $1 >/dev/null 2>&1 ; then 117 | sf_msg1 "Creating $1 group" 118 | if [ -z "$sf_noexec" ] ; then 119 | opt="" 120 | [ -n "$3" ] && opt="users=$3" 121 | mkgroup id=$2 $1 $opt 122 | rc=$? 123 | fi 124 | fi 125 | ;; 126 | 127 | *) 128 | if ! grep "^$1:" /etc/group >/dev/null 2>&1 ; then 129 | sf_msg1 "Creating $1 group" 130 | if [ -z "$sf_noexec" ] ; then 131 | groupadd -g $2 $1 132 | rc=$? 133 | fi 134 | if [ -n "$3" ] ; then 135 | for i in `echo $3 | sed 's/,/ /g'` ; do 136 | sf_msg1 "Adding user $i to group $1" 137 | if [ -z "$sf_noexec" ] ; then 138 | usermod -a -G $1 $i 139 | rc=`expr $rc + $?` 140 | fi 141 | done 142 | fi 143 | fi 144 | ;; 145 | esac 146 | return $rc 147 | } 148 | 149 | ##---------------------------------------------------------------------------- 150 | # Remove a group 151 | # 152 | # Args: 153 | # $1: Group name 154 | # Returns: Status from system command 155 | # Displays: nothing 156 | #----------------------------------------------------------------------------- 157 | 158 | function sf_delete_group 159 | { 160 | typeset rc 161 | rc=0 162 | 163 | case `sf_os_family` in 164 | linux|sunos) 165 | if grep "^$1:" /etc/group >/dev/null 2>&1 ; then 166 | sf_msg1 "Deleting $1 group" 167 | if [ -z "$sf_noexec" ] ; then 168 | groupdel "$1" 169 | rc=$? 170 | fi 171 | fi 172 | ;; 173 | 174 | *) 175 | sf_unsupported sf_delete_group 176 | ;; 177 | esac 178 | return $rc 179 | } 180 | 181 | ##---------------------------------------------------------------------------- 182 | # Return an unused group ID 183 | # 184 | # Args: None 185 | # Returns: Always 0 186 | # Displays: nothing 187 | #----------------------------------------------------------------------------- 188 | 189 | function sf_unused_group_id 190 | { 191 | typeset i 192 | 193 | i=1001 194 | while true ; do 195 | grep ":$i:" /etc/group >/dev/null || break 196 | i=`expr $i + 1` 197 | done 198 | 199 | echo $i 200 | } 201 | 202 | ##---------------------------------------------------------------------------- 203 | # Return an unused user ID 204 | # 205 | # Args: None 206 | # Returns: Always 0 207 | # Displays: nothing 208 | #----------------------------------------------------------------------------- 209 | 210 | function sf_unused_user_id 211 | { 212 | typeset i 213 | 214 | i=1001 215 | while true ; do 216 | grep ":$i:" /etc/passwd >/dev/null || break 217 | i=`expr $i + 1` 218 | done 219 | 220 | echo $i 221 | } 222 | 223 | ##---------------------------------------------------------------------------- 224 | # Checks if a given user exists on the system 225 | # 226 | # Args: 227 | # $1: User name to check 228 | # Returns: 0 if user exists; != 0 if not 229 | # Displays: nothing 230 | #----------------------------------------------------------------------------- 231 | 232 | function sf_user_exists 233 | { 234 | typeset status 235 | 236 | case `sf_os_family` in 237 | aix) 238 | lsuser $1 >/dev/null 2>&1 239 | status=$? 240 | ;; 241 | 242 | *) 243 | grep "^$1:" /etc/passwd >/dev/null 2>&1 244 | status=$? 245 | ;; 246 | esac 247 | return $status 248 | } 249 | 250 | ##---------------------------------------------------------------------------- 251 | # Remove a user account 252 | # 253 | # Args: 254 | # $1: User name 255 | # Returns: Status from system command 256 | # Displays: nothing 257 | #----------------------------------------------------------------------------- 258 | 259 | function sf_delete_user 260 | { 261 | typeset rc 262 | rc=0 263 | 264 | if sf_user_exists "$1" ; then 265 | case `sf_os_family` in 266 | linux|sunos) 267 | sf_msg1 "Deleting $1 user" 268 | if [ -z "$sf_noexec" ] ; then 269 | userdel "$1" 270 | rc=$? 271 | fi 272 | ;; 273 | 274 | *) 275 | sf_unsupported sf_delete_user 276 | ;; 277 | esac 278 | fi 279 | 280 | return $rc 281 | } 282 | 283 | ##---------------------------------------------------------------------------- 284 | # Return UID of a given user 285 | # 286 | # Args: 287 | # $1: User name 288 | # Returns: 0 if user exists, 1 if not 289 | # Displays: UID if user exists, nothing if not 290 | #----------------------------------------------------------------------------- 291 | 292 | function sf_user_uid 293 | { 294 | typeset res user 295 | res='' 296 | user=$1 297 | 298 | case `sf_os_family` in 299 | linux) 300 | res=`awk -F: -vUSER=${user} '$1==USER {print $3}' /etc/passwd` 301 | ;; 302 | *) 303 | sf_unsupported sf_user_uid 304 | ;; 305 | esac 306 | [ -z "$res" ] && return 1 307 | echo $res 308 | return 0 309 | } 310 | 311 | ##---------------------------------------------------------------------------- 312 | # Return GID of a given user 313 | # 314 | # Args: 315 | # $1: User name 316 | # Returns: 0 if user exists, 1 if not 317 | # Displays: Primary GID if user exists, nothing if not 318 | #----------------------------------------------------------------------------- 319 | 320 | function sf_user_gid 321 | { 322 | typeset res user 323 | res='' 324 | user=$1 325 | 326 | case `sf_os_family` in 327 | linux) 328 | res=`awk -F: -vUSER=${user} '$1==USER {print $4}' /etc/passwd` 329 | ;; 330 | *) 331 | sf_unsupported sf_user_gid 332 | ;; 333 | esac 334 | [ -z "$res" ] && return 1 335 | echo $res 336 | return 0 337 | } 338 | 339 | ##---------------------------------------------------------------------------- 340 | # Create a user 341 | # 342 | # To set the login shell, initialize the CREATE_USER_SHELL variable before 343 | # calling the function. 344 | # 345 | # For accounts with no access allowed (blocked accounts), $7, $8, and $9 are 346 | # not set. 347 | # 348 | # Args: 349 | # $1: User name 350 | # $2: uid 351 | # $3: gid 352 | # $4: description (gecos) 353 | # $5: home dir (can be '' for '/none') 354 | # $6: Additional groups (separated with ',') 355 | # $7: encrypted password (Linux) 356 | # $8: encrypted password (HP-UX & SunOS) 357 | # $9: encrypted password (AIX) 358 | # Returns: Always 0 359 | # Displays: Info msg 360 | #----------------------------------------------------------------------------- 361 | 362 | function sf_create_user 363 | { 364 | typeset name uid gid gecos home groups locked add_cmd shell passwd_file 365 | 366 | sf_user_exists $1 && return 367 | 368 | name=$1 369 | uid=$2 370 | gid=$3 371 | gecos=$4 372 | 373 | home=$5 374 | [ -z "$home" ] && home='/none' 375 | 376 | groups=$6 377 | 378 | locked='y' 379 | [ $# = 9 ] && locked='' 380 | 381 | sf_msg1 "Creating $1 user" 382 | [ -n "$sf_noexec" ] && return 383 | sf_create_dir `dirname $home` 384 | 385 | add_cmd='' 386 | 387 | case `sf_os_family` in 388 | aix) 389 | [ -n "$groups" ] && add_cmd="$add_cmd groups=$groups" 390 | 391 | [ -n "$locked" ] && add_cmd="$add_cmd login=false" 392 | 393 | mkuser gecos="$gecos" pgrp=$gid id=$uid home=$home $add_cmd $name 394 | 395 | [ -z "$locked" ] && sf_set_passwd_aix $name "$9" 396 | ;; 397 | 398 | linux) 399 | shell=/bin/bash 400 | #[ -n "$locked" ] && shell=/bin/false 401 | [ -n "$CREATE_USER_SHELL" ] && shell="$CREATE_USER_SHELL" 402 | 403 | [ -n "$groups" ] && add_cmd="-G $groups" 404 | 405 | if [ "$home" = /none ] ; then 406 | add_cmd="$add_cmd -M" 407 | else 408 | add_cmd="$add_cmd -m" 409 | fi 410 | 411 | useradd -c "$gecos" -o -g $gid -u $uid -d $home -s $shell $add_cmd $name 412 | 413 | [ -z "$locked" ] && sf_set_passwd $name "$7" /etc/shadow 414 | ;; 415 | 416 | *) 417 | shell=/bin/sh 418 | [ -x /bin/ksh ] && shell=/bin/ksh 419 | #[ -n "$locked" ] && shell=/bin/false 420 | 421 | [ -n "$groups" ] && add_cmd="-G $groups" 422 | 423 | [ "$home" != /none ] && add_cmd="$add_cmd -m" 424 | 425 | useradd -c "$gecos" -g $gid -u $uid -d $home -s $shell $add_cmd $name \ 426 | >/dev/null 427 | 428 | passwd_file=/etc/shadow 429 | [ `sf_os_family` = hp-ux ] && passwd_file=/etc/passwd 430 | [ -z "$locked" ] && sf_set_passwd $name "$8" $passwd_file 431 | ;; 432 | esac 433 | return 0 434 | } 435 | 436 | ##---------------------------------------------------------------------------- 437 | # Check that we run as root 438 | # 439 | # Args: None 440 | # Returns: 0 if OK; 1 if KO 441 | # Displays: Nothing or error message 442 | #----------------------------------------------------------------------------- 443 | 444 | function sf_check_user_is_root 445 | { 446 | [ `id -ur` = 0 ] && return 0 447 | 448 | sf_fatal "This must be executed as 'root'" 449 | return 1 450 | } 451 | 452 | #============================================================================= 453 | -------------------------------------------------------------------------------- /src/sf_vm.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #============================================================================= 20 | # Section: Virtual machine 21 | #============================================================================= 22 | 23 | ##---------------------------------------------------------------------------- 24 | # Check if we are on a VMware host 25 | # 26 | # Args: None 27 | # Returns: 0 if VMware, 1 if not 28 | # Displays: Nothing 29 | ##---------------------------------------------------------------------------- 30 | 31 | function sf_vm_host_is_vmware 32 | { 33 | if [ -x /usr/sbin/virt-what ] ; then 34 | /usr/sbin/virt-what | grep vmware >/dev/null 35 | return $? 36 | else 37 | grep VMware /proc/scsi/scsi >/dev/null 2>&1 38 | return $? 39 | fi 40 | } 41 | 42 | #============================================================================= 43 | -------------------------------------------------------------------------------- /src/sysfunc.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2009-2014 - Francois Laupretre 3 | # 4 | #============================================================================= 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License (LGPL) as 7 | # published by the Free Software Foundation, either version 3 of the License, 8 | # or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License 16 | # along with this program. If not, see . 17 | #============================================================================= 18 | 19 | #----------------------------------------------------------------------------- 20 | # All the functions must have a name starting with '_' (no publicly 21 | # accessible function here). 22 | #----------------------------------------------------------------------------- 23 | 24 | #---------------------------------------------------------------------------- 25 | # Display error message, usage, and exit 26 | # 27 | # Args: 28 | # $*: Error message 29 | # Returns: No return 30 | # Displays: Message 31 | #----------------------------------------------------------------------------- 32 | 33 | function _sf_fatal 34 | { 35 | sf_error "$*" 36 | echo 37 | _sf_usage 38 | exit 1 39 | } 40 | 41 | #---------------------------------------------------------------------------- 42 | # Display usage and defined commands 43 | # 44 | # Args: None 45 | # Returns: No return 46 | # Displays: Message 47 | #----------------------------------------------------------------------------- 48 | 49 | function _sf_usage 50 | { 51 | sf_msg 'Usage: sysfunc [args]' 52 | echo 53 | echo "Defined commands :" 54 | echo 55 | typeset -F | sed 's/^declare -f //' | grep '^sf_' | sed 's/^sf_//' \ 56 | | grep -v '^loaded$' 57 | } 58 | 59 | 60 | #============================================================================= 61 | # MAIN 62 | #============================================================================= 63 | 64 | #-- Clear potentially conflicting f...ing aliases 65 | 66 | for i in cp mv rm 67 | do 68 | unalias $i >/dev/null 2>&1 || : 69 | done 70 | 71 | #-- Path 72 | # Using XPG-compliant commands first is mandatory on Solaris, as the 73 | # default syntax is not always compatible with Linux ('tail -n +' for 74 | # instance). 75 | 76 | for i in /usr/sbin /bin /usr/bin /sbin /etc /usr/ccs/bin /usr/xpg4/bin /usr/xpg6/bin 77 | do 78 | [ -d "$i" ] && PATH="$i:$PATH" 79 | done 80 | export PATH 81 | 82 | #-- Variables (avoir unbound variable error) 83 | 84 | sf_install_dir="${sf_install_dir:=%INSTALL_DIR%}" 85 | 86 | sf_nosave="${sf_nosave:=}" 87 | sf_noexec="${sf_noexec:=}" 88 | 89 | # $sf_verbose remains for compatibility. 90 | sf_verbose="${sf_verbose:=}" 91 | # $sf_verbose_level must contain a numeric value. 92 | sf_verbose_level="${sf_verbose_level:=0}" 93 | 94 | export sf_install_dir sf_nosave sf_noexec sf_verbose sf_verbose_level 95 | 96 | #-- Find utilities 97 | 98 | if [ -z "${sf_yum:+}" ] ; then 99 | sf_yum=`sf_find_executable yum` 100 | [ -n "$sf_yum" ] && sf_yum="$sf_yum -y -t -d 1" 101 | fi 102 | export sf_yum 103 | 104 | if [ -z "${sf_rpm:+}" ] ; then 105 | sf_rpm=`sf_find_executable rpm` 106 | [ -n "$sf_rpm" ] && sf_rpm="$sf_rpm --nosignature" 107 | fi 108 | export sf_rpm 109 | 110 | #-- Check if sourced or executed 111 | 112 | _found= 113 | echo "$0" | grep sysfunc >/dev/null 2>&1 && _found=y 114 | if [ -n "$_found" ] ; then # Executed 115 | _cmd="$1" 116 | [ "$_cmd" = '' ] && _sf_fatal 'No command' 117 | _func="sf_$_cmd" 118 | shift 119 | type "$_func" >/dev/null 2>&1 || _sf_fatal "$_cmd: Unknown command" 120 | cmd="$_func" 121 | for arg ; do # Preserve potential empty strings 122 | cmd="$cmd '$arg'" 123 | done 124 | eval "$cmd ; _rc=\$?" 125 | exit $_rc 126 | fi 127 | 128 | #============================================================================= 129 | --------------------------------------------------------------------------------