#!/bin/bash #set -n # read but do not execute commands (check on syntax errors) # # File: /usr/local/bin/untar # # Extract files from a compressed archive. # # Copyright (C) 2008 Juergen Kaesmann (JK) # ############################################################################## # GPL NOTICE # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################## # FIND # ############################################################################## # FILTER # ############################################################################## # AWK # ############################################################################## # SED # ############################################################################## # XARGS # ############################################################################## # REPLACE STRINGS # ############################################################################## # RSYNC # ############################################################################## # DIALOG # ############################################################################## # EXIT CODES ############################################################################## # File: /usr/local/lib/sh/libfuncerr-sh-4.0.0 # # Functions and constans for error purposes. # We need a call to the logger (implemented as cmd variable debuglog) like: # debuglog="/bin/logger -p user.debug -t $scriptname -- DEBUG:" # # Copyright © 2020 Juergen Kaesmann (JK) # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Return codes: # Depends on the functions ############################################################################## # DECLARATION OF CONSTANTS # STRINGS #readonly samplestring=x # NUMBERS # ERROR CODES RANGE 0 - 127 # error codes 0 - 79 readonly _ERR_OK_=0 readonly _ERR_GENERAL_=1 readonly _ERR_WRONG_PAR_COUNT_=2 readonly _ERR_UNKNOWN_CMD_=3 readonly _ERR_UNKNOWN_OPT_=4 readonly _ERR_FILE_NOT_FOUND_=5 readonly _ERR_SUB_CMD_NOT_FOUND_=6 readonly _ERR_MISSING_SUB_CMD_=7 readonly _ERR_MISSING_ARG_FOR_OPT_=8 readonly _ERR_VAL_OUT_OF_RANGE_=9 readonly _ERR_VAR_IS_EMPTY_=10 readonly _ERR_TYPE_MISMATCH_=11 readonly _ERR_WRONG_VER_OF_CONF_FILE_=12 readonly _ERR_OPT_NOT_ALLOWED_=13 readonly _ERR_MISSING_PAR_=14 readonly _ERR_WRONG_PERMS_FOR_ACTION_=15 readonly _ERR_CANNOT_READ_FROM_FILE_=16 readonly _ERR_CANNOT_WRITE_TO_FILE_=17 readonly _ERR_NO_FREE_FD_=18 readonly _ERR_START_LINE_OUT_OF_RANGE_=19 readonly _ERR_LAST_LINE_OUT_OF_RANGE_=20 readonly _ERR_LAST_LINE_BEFORE_START_LINE_=21 # not really error codes but function results 80 - 95 readonly _ERR_VAL1_EQ_VAL2_=80 readonly _ERR_VAL1_NE_VAL2_=81 readonly _ERR_VAL1_LT_VAL2_=82 readonly _ERR_VAL1_GT_VAL2_=83 readonly _ERR_VAL1_LE_VAL2_=84 readonly _ERR_VAR1_GE_VAL2_=85 # error codes 96 - 99 readonly _ERR_USER_ABORT_=98 readonly _ERR_UNKNOWN_ERR_=99 ############################################################################## # DECLARATION OF VARIABLES # STRINGS # NUMBERS # ARRAYS declare -a ErrMsg # type is array of strings # output of ErrMsg[] codes 0 - 79 ErrMsg[0]="OK" # all time goody :-) ErrMsg[1]="Error - " ErrMsg[2]="Error - Wrong parameter count!" ErrMsg[3]="Error - Unknown command!" ErrMsg[4]="Error - Unknown option!" ErrMsg[5]="Error - File not found!" ErrMsg[6]="Error - Sub command not found!" ErrMsg[7]="Error - Missing sub command!" ErrMsg[8]="Error - Missing argument for option!" ErrMsg[9]="Error - Value out of range!" ErrMsg[10]="Error - Variable is empty!" ErrMsg[11]="Error - Type mismatch!" ErrMsg[12]="Error - Wrong version of config files!" ErrMsg[13]="Error - Option not allowed!" ErrMsg[14]="Error - Missing parameter!" ErrMsg[15]="Error - Wrong permissions for action!" ErrMsg[16]="Error - Cannot read from file!" ErrMsg[17]="Error - Cannot write to file!" ErrMsg[18]="Error - No free FD!" ErrMsg[19]="Error - Start line out of range!" ErrMsg[20]="Error - Last line out of range!" ErrMsg[21]="Error - Last line before start line!" # output of ErrMsg[] 80 - 95. not really error codes but function results ErrMsg[80]="1. Value == 2. Value" ErrMsg[81]="1. Value != 2. Value" ErrMsg[82]="1. Value < 2. Value" ErrMsg[83]="1. Value > 2. Value" ErrMsg[84]="1. Value <= 2. Value" ErrMsg[85]="1. Value >= 2. Value" # output of ErrMsg[] codes 96 - 99 ErrMsg[98]="User abort." ErrMsg[99]="Error - Unknown error!" ############################################################################## # File: /usr/local/lib/sh/libfuncstd-sh-5.0.0 # # Functions for general use. # We need a call to the logger (implemented as cmd variable debuglog) like: # debuglog="/bin/logger -p user.debug -t $scriptname -- DEBUG:" # # Copyright (c) 2008 Juergen Kaesmann (JK) # ############################################################################## # LGPL NOTICE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################## # EXIT CODES ############################################################################## # DECLARATION OF CONSTANTS ############################################################################## # DECLARATION OF VARIABLES # STRINGS _DEBUG_=no # _DEBUG_=yes/no _OPTNAME_='' # used from GetOpt _OPTVAL_='' # used from GetOpt # NUMBERS _OPTIDX_=0 # used from GetOpt intern. _OPTPOS_=0 # used from GetOpt intern. declare -i _STACKPOINTER_=0 # integer, used from Push Pop # ARRAYS # Indexed arrays are always zero based string arrays. # If index starts with 1 and all members are assigned then # count of members of array = last index of array #declare -a arr #maxarr="${#arr[@]}" # get number of elements in arr #unset arr[@] # remove the entire array declare -a _STACK_ # type is array of strings ############################################################################## # DECLARATION OF FUNCTIONS # function Push (string) # Push the given STRING onto Stack[]. Increment StackPointer. # par1 = STRING to push # Use: Push "$mystring" # Uses echo # Return codes: # Standard # function Pop (string-variable) # Pop the actual string from Stack[]. Decrement StackPointer. # par1 = NAME of string-variable to get the stack value # Use: Pop mystring # Uses echo # Return codes: # Standard # function Show_Err (errcode string) # Show the error text. # par1 = errcode # par2 = additional errtext # Uses echo, logger # Return codes: # Standard # function Find_Substr (mainstr substr) # find 1. substr in mainstr # par1 = mainstr # par2 = substr # If substr found then push result (rel. position 0 - [n-1]) on stack # Return codes: # 0 = substr found # 1 = substr not found # 2 = substr is longer than mainstr # function GetOpt (posixoptstr gnuoptstr $@) # Check and get options. # POSIX OPTION: # a) Single option without arg (-d -q -v). # b) Single option with arg (-i[ ]). # c) Option group without arg (-dqv). # d) Option group with arg (-dqi[ ]). # GNU STYLE LONG OPTION: # a) Option without arg (--output). # a) Option with arg (--infile=). # par1 = All possible POSIX options ('dqi:'). # ':' means option before ':' needs arg. # par2 = All possible Gnu style long options ('output infile='). # '=' means option needs arg. # par3 = All pars from cmdline (including par1 and par2). # Global vars: # _OPTNAME_ : Name of option. # _OPTVAL_ : Value of option. # _OPTIDX_ : Points to next cmdline arg (1 - n) (internal). # _OPTPOS_ : Index in actual posix group_of_args (0 - n-1) (internal). # Uses echo, logger # Return codes: # Standard # function Get_PID (pathname transfer [argument]) # Get PID of 1. found filename with associated pathname [and argument]. # Supply pathname [and argument]. # Values are transferred to and from this function via given variable names. # Additional normal values can be supplied. The calling function should not # use '_' - surrounded variable names as parameter. # Local variables should surrounded by '_' ( ret --> _ret_ ). # Call: Get_PID $myvar mytransfer [$myarg] # # We use 1 returned value in its transfer variable: # par1 = Pathname. a normal string (fix or given by a variable) # par2 = Name of transfer variable (content = something or nothing) # par3 = Optional arg. A normal string (fix or given by a variable) # Uses cut, echo, grep, logger, ps, sed # Return codes: # Standard # function Get_Path_PID (PID transfer) # Get pathname from a proc with PID. Supply PID. # Values are transferred to and from this function via given variable names. # Additional normal values can be supplied. The calling function should not # use '_' - surrounded variable names as parameter. # Local variables should surrounded by '_' ( ret --> _ret_ ). # Call: Get_Path_From_PID $myvar mytransfer # # We use 1 returned value in its transfer variable: # par1 = PID. A normal string (fix or given by a variable) # par2 = Name of transfer variable (content = something or nothing) # Uses cut, echo, logger, ps, tr # Return codes: # Standard # function Str (length char) # Build a string of chars to specified length. # par1 = length to build # par2 = build char for string # If no error then push result on stack (1 string) # Return codes: # Standard # function LSet (length string) # Set a string at the left side in a string of given length. # par1 = length of resulting string # par2 = string # If no error then push result on stack (1 string) # Return codes: # Standard # function RSet (length string) # Set a string at the right side in a string of given length. # par1 = length of resulting string # par2 = string # If no error then push result on stack (1 string) # Return codes: # Standard # function CSet (length string) # Center a string in a string of given length. # par1 = length of resulting string # par2 = string # Uses echo, logger # If no error then push result on stack (1 string) # Return codes: # Standard # function Change_German_Chars (string) # Changes all german special chars in a string # CONVERSIONS: # Ä to AE ä to ae # Ö to OE ö to oe # Ü to UE ü to ue ß to ss # par1 = string to change # Push result on stack (1 string) # Return codes: # Standard # function Check_Digits (str) # Checks wether a string contain digits and/or alpha # par1 = string # Return codes: # 0 = String contains only digits # 1 = String contains digits and alpha # 2 = String contains only alpha # function Permissions_To_Value (string) # Gives a numerical value for a permissins string e.g. -rwxrwxrwx = 0777 # par1 = permissions string # BITVALUES # 421421421 # "-rwxrwxrwx" 777 normal file # "drwxrwxrwx" 777 normal dir # "-rwsrwsrwt" 7777 all special bits set # "-rwSrwSrwx" 6667 error by special bits - because exec bits not set # "drwxrwxrwT" 1776 error by special bits - because exec bit not set # If no error then Push result on stack (1 string) # Return codes: # Standard # function Compare_Version_No (needed actual) # Compare 2 version numbers. # par1 = needed version # par2 = actual version # Version numbers in the form x.y.z where only numbers are allowed. # The count of numbers has to be equal in both version numbers. # Return codes: # Standard # 80 = Needed version equal actual version # 82 = Needed version lower than actual version # 83 = Needed version greater than actual version # function Check_Package_Name (pkgname) # Check the name of a package. # par1 = pkgname # # Package name: NAME[-VERSION[-RELEASE]][.ARCH][.delta].PKGTYP # NAME : String, can contain several minus, no point inside # VERSION : Digits separated with points, no minus inside # RELEASE : Digits and string separated with points, no minus inside # ARCH : i386 i486 i586 i686 noarch src # delta : the word "delta" # PKGTYP : rpm or tgz # # Sample : sample-package-1.2.3-ksm.4.5.6.noarch.rpm # # If no error then push results on stack in following order (6 strings): # .pkgtyp .delta .arch -release -version name # Return codes: # Standard # function Leap_Year (year) # Check if given year is a leap-year. # par1 = year (long form, 4 digits) # Return codes: # Standard # 0 = is leap-year # 1 = is no leap-year # function Inc_Date_Day (date) # Inc day of date with respect to month and year. # Leap-year/Intercalary day will not be recognized. # par1 = date (german short form, eg. 31.12.99) # If no error then push result on stack (1 string) # Return codes: # Standard # function Dec_Date_Day (date) # Dec day of date with respect to month and year. # Leap-year/Intercalary day will not be recognized. # par1 = date (german short form, eg. 31.12.99) # If no error then push result on stack (1 string) # Return codes: # Standard # function Compare_Dates (date1 date2) # compare date1 with date2 (german short form, eg. 31.12.99). # par1 = date1 # par2 = date2 # Return codes: # Standard # function Inc_LDate_Day (date) # Inc day of date with respect to month and year. # Leap-year/Intercalary day will be recognized. # par1 = date (german long form e.g. 31.12.2000) # If no error then push result on stack (1 string) # Return codes: # Standard # function Dec_LDate_Day (date) # Dec day of date with respect to month and year. # Leap-year/Intercalary day will be recognized. # par1 = date (german long form e.g. 31.12.2000) # If no error then push result on stack (1 string) # Return codes: # Standard # function Compare_LDates (date1 date2) # compare date1 with date2 (german long form, eg. 31.12.2000). # par1 = date1 # par2 = date2 # Return codes: # Standard # function Calc_Date_Diff (date1 date2) # Calc diff of days (date = German short form, eg.: 31.12.99) # Leap-year/Intercalary day will not be recognized. # par1 = date1 # par2 = date2 # date1 must be lower or equal then date2 # Push result on stack (1 string) # Return codes: # Standard # function Calc_Time_Diff (first_time last_time) # calc time difference between 2 times (t2 - t1). # par1 = first time t1 # par2 = last time t2 # timeformat is hh:mm:ss # push result on stack (1 string) # Return codes: # Standard # function Sum_Times (first_time second_time) # Sum 2 times. # par1 = first time # par2 = second time # timeformat is hh:mm:ss # push result on stack (1 string) # Return codes: # Standard # function Get_Lines (file first last) # get lines from a file from first till last line. # par1 = filename # par2 = first line # par3 = last line # Output goes to STDOUT # Return codes: # 0 = OK # 2 = Error in parameter count # 5 = File not found # 19 = Start line out of range (file to short or start line <= 0) # 20 = Last line out of range (file to short) # 21 = Last line before start line # function Insert_Line (file line_number string) # insert a line in a file after specified line number. # par1 = filename # par2 = line number (0 - n) # par3 = line to insert # Output goes to STDOUT # Return codes: # 0 = OK # 2 = Error in parameter count # 5 = File not found # 19 = Start line out of range (file to short or start line <= 0) # function Replace_Line (file line_number string) # replace a line in a file. # par1 = filename # par2 = line number (1 - n) # par3 = replacement line # Output goes to STDOUT # Return codes: # 0 = OK # 2 = Error in parameter count # 5 = File not found # 19 = Start line out of range (file to short or start line <= 0) # function Remove_Lines (file first last) # rm lines from a file from first till last line. # par1 = filename # par2 = first line # par3 = last line # Output goes to STDOUT # Return codes: # 0 = OK # 2 = Error in parameter count # 5 = File not found # 19 = Start line out of range (file to short or start line <= 0) # 20 = Last line out of range (file to short) # 21 = Last line before start line ############################################################################## # FUNCTIONS #============================================================================= function _Local_X_mod_Y_ () { # This is the modulo function. Both vars have to be integers. # Computing is done like following: X-(X/Y)*Y # Values are transferred to and from this function via given variable names. # Call: X_mod_Y $value_X $value_Y mytransfer # # We use 1 returned value in its transfer variable: # par1 = 1. value # par2 = 2. value # par3 = name of transfer variable (content = something) # Uses bc, echo, logger # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG _Local_X_mod_Y_: $# $@" >&2 $debuglog _Local_X_mod_Y_: $# $@ fi # n=name v=value local _n1_="$3" _v1_="${!3}" local _scale_="0" _x_="$1" _y_="$2" _r_='' local _ret_=0 # do the stuff _r_=$(echo "scale=${_scale_}; ${_x_} % ${_y_}" | bc) _ret_=$? # return values eval ${_n1_}="\"${_r_}\"" return ${_ret_} } #============================================================================= function Push () { # Push the given STRING onto Stack[]. Increment StackPointer. # par1 = STRING to push # Call: Push "$mystring" # Uses echo # Exit on error. # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Push: $# $@" >&2 $debuglog Push: $# $@ fi if [ "$#" -eq 1 ]; then let ++_STACKPOINTER_ _STACK_[$_STACKPOINTER_]="$1" else if [ "$verbose" != no ]; then echo "Function Push - ${ErrMsg[2]}" >&2 else $errlog "libfuncstd-sh function Push, ${ErrMsg[2]}" fi exit 2 fi return 0 } #============================================================================= function Pop () { # Pop the actual string from Stack[]. Decrement StackPointer. # par1 = NAME of string-variable to get the stack value # Call: Pop mystring # Uses echo # Exit on error. # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Pop: $# $@" >&2 $debuglog Pop: $# $@ fi if [ "$#" -eq 1 ]; then if [ "$_STACKPOINTER_" -gt 0 ]; then eval $1="\"${_STACK_[$_STACKPOINTER_]}\"" let --_STACKPOINTER_ else if [ "$verbose" != no ]; then echo "Error in function Pop - _STACKPOINTER_ = 0!" >&2 else $errlog "libfuncstd-sh function Pop, _STACKPOINTER_ = 0" fi exit 1 fi else if [ "$verbose" != no ]; then echo "Function Pop - ${ErrMsg[2]}" >&2 else $errlog "libfuncstd-sh function Pop, ${ErrMsg[2]}" fi exit 2 fi return 0 } #============================================================================= function Show_Err () { # Show the error text. # par1 = errcode # par2 = additional errtext # Uses echo, logger # Return codes: # Standard if [ "$debug" == "yes" ]; then # DEBUG echo "DEBUG Show_Err: $# $@" >&2 $debuglog Show_Err: $# $@ fi local msgtxt="${ErrMsg[$1]} $2" local ret=0 if [ "$verbose" != no ]; then echo "${msgtxt}" >&2 else $errlog ${msgtxt} fi ret=$? return $ret } #============================================================================= function Find_Substr () { # find 1. substr in mainstr # par1 = mainstr # par2 = substr # If substr found then push result (rel. position 0 - [n-1]) on stack # Return codes: # 0 = substr found # 1 = substr not found # 2 = substr is longer than mainstr if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Find_Substr: $# $@" >&2 $debuglog Find_Substr: $# $@ fi local p1="$1" p2="$2" s1='' found=no l1 l2 wl1 i=0 ret=0 l1=${#p1} l2=${#p2} wl1=$[${l1}-${l2}+1] if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "p1=$p1 p2=$p2 l1=$l1 l2=$l2 wl1=$wl1" fi if [ $l1 -ge $l2 ]; then # str >= substr while [ "$i" -lt $wl1 ]; do # pos <= diff l1-l2 if [ "${p1:$i:1}" == "${p2:0:1}" ]; then # str(pos) == substr(0) s1="${p1:$i:$l2}" # s1 = get str(pos:len(substr)) if [ "$s1" == "$p2" ]; then # s1 == substr found=yes # found break # end loop fi fi let ++i # inc pos done else # str < substr found=mm fi case $found in yes) ret=0; Push "$i";; no) ret=1;; mm) ret=2;; esac return $ret } #============================================================================= function GetOpt () { # Check and get options. # POSIX OPTION: # a) Single option without arg (-d -q -v). # b) Single option with arg (-i[ ]). # c) Option group without arg (-dqv). # d) Option group with arg (-dqi[ ]). # GNU STYLE LONG OPTION: # a) Option without arg (--output). # a) Option with arg (--infile=). # par1 = All possible POSIX options ('dqi:'). # ':' means option before ':' needs arg. # par2 = All possible Gnu style long options ('output infile='). # '=' means option needs arg. # par3 = All pars from cmdline (including par1 and par2). # Global vars: # _OPTNAME_ : Name of option. # _OPTVAL_ : Value of option. # _OPTIDX_ : Points to next cmdline arg (1 - n) (internal). # _OPTPOS_ : Index in actual posix group_of_args (0 - n-1) (internal). # Uses echo, logger # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG GetOpt: $# $@" >&2 $debuglog GetOpt: $# $@ fi local optsposix="$1" optsgnu="$2" local arg='' s='' optname='' optval='' ofound=no needarg=no local lop="${#optsposix}" i=0 larg=0 optlen=0 p=0 ret=0 shift 2 if [ $_OPTIDX_ -gt 0 ]; then shift $_OPTIDX_ # shift to start arg fi arg="$1" if [ "$arg" == "--" ]; then # option -- _OPTNAME_="--" _OPTVAL_='' let ++_OPTIDX_ _OPTPOS_=0 elif [ "${#arg}" -gt 2 ] && [ "${arg:0:2}" == "--" ]; then # gnuopt --* arg="${arg#--}" # --inf=xx --> inf=xx larg=${#arg} # len of arg 'inf=xx' Find_Substr $arg '=' # look for optarg ret=$? if [ $ret -eq 0 ]; then # arg has option Pop p # p = rel. pos (3) optname="${arg:0:$p}" # optname = 'inf' let ++p optval="${arg:$p}" # get optval else # no optarg p=0 optname="$arg" # optname = arg ret=0 fi # is option allowed? for s in $optsgnu; do # for all poss.gnu opts if [ "${s%=}" == "$optname" ]; then # optname is allowed ofound=yes break fi done if [ "$ofound" == yes ]; then # option is allowed if [ $p -gt 0 ]; then # optname has arg _OPTNAME_="${optname}" _OPTVAL_="${optval}" if [ -z "$_OPTVAL_" ]; then # error missing arg _OPTVAL_="$_OPTNAME_" _OPTNAME_=':' fi else # optname has no arg _OPTNAME_="${arg}" _OPTVAL_='' fi else # option not allowed _OPTNAME_='?' _OPTVAL_="$optname" fi let ++_OPTIDX_ _OPTPOS_=0 elif [ "${#arg}" -gt 1 ] && [ "${arg:0:1}" == "-" ]; then # posixopt -* arg=${arg#-} # d, i, i larg=${#arg} # len of arg optname="${arg:$_OPTPOS_:1}" let ++_OPTPOS_ # is option allowed? Find_Substr "$optsposix" "$optname" # look for option ret=$? if [ "$ret" -eq 0 ]; then # optname allowed Pop p ofound=yes fi ret=0 if [ "$ofound" == yes ]; then # option is allowed # need optname an arg? look for : let ++p if [ $p -eq $lop ]; then # we are last char needarg=no else # we are not last char s=${optsposix:$p:1} # get next char if [ "$s" == ':' ]; then # need optarg needarg=yes else needarg=no fi fi if [ "$needarg" == no ]; then _OPTNAME_="${optname}" _OPTVAL_='' if [ $_OPTPOS_ -eq $larg ]; then # behind last pos let ++_OPTIDX_ _OPTPOS_=0 fi else if [ $_OPTPOS_ -eq $larg ]; then # no optarg suppl. _OPTNAME_="${optname}" _OPTVAL_="${2}" if [ -z "$2" ]; then # error missing optarg _OPTVAL_="$_OPTNAME_" _OPTNAME_=':' fi let ++_OPTIDX_ _OPTPOS_=0 else #get suppl. optarg _OPTNAME_="${optname}" optlen=$(($larg - $_OPTPOS_)) _OPTVAL_="${arg:$_OPTPOS_:$optlen}" fi let ++_OPTIDX_ _OPTPOS_=0 fi else # option not allowed _OPTNAME_='?' _OPTVAL_="$arg" fi else # is normal argument ret=98 fi return $ret } #============================================================================= function Get_PID () { # Get PID of 1. found filename with associated pathname [and argument]. # Supply pathname [and argument]. # Values are transferred to and from this function via given variable names. # Additional normal values can be supplied. The calling function should not # use '_' - surrounded variable names as parameter. # Local variables should surrounded by '_' ( ret --> _ret_ ). # Call: Get_PID $myvar mytransfer [$myarg] # # We use 1 returned value in its transfer variable: # par1 = Pathname. a normal string (fix or given by a variable) # par2 = Name of transfer variable (content = something or nothing) # par3 = Optional arg. A normal string (fix or given by a variable) # Uses cut, echo, grep, logger, ps, sed # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Get_PID: $# $@" >&2 $debuglog Get_PID: $# $@ fi # n=name v=value local _pn_="$1" _value_return_n2_="$2" _value_return_v2_="${!2}" local _arg_="$3" _fn_='' local _pid_=0 _ret_=0 _fn_=$(basename $_pn_) if [ -z "$_arg_" ]; then _pid_=$(/bin/ps -C $_fn_ -o pid=,args= | /bin/grep -m 1 $_pn_ | /usr/bin/sed -e "s/^[[:space:]]*//" | /usr/bin/cut -d ' ' -f 1) else _pid_=$(/bin/ps -C $_fn_ -o pid=,args= | /bin/grep -m 1 $_pn_ | /bin/grep $_arg_ | /usr/bin/sed -e "s/^[[:space:]]*//" | /usr/bin/cut -d ' ' -f 1) fi if [ -z "$_pid_" ]; then _ret_=5 else _ret_=0 fi # return values eval ${_value_return_n2_}="\"${_pid_}\"" return ${_ret_} } #============================================================================= function Get_Path_PID () { # Get pathname from a proc with PID. Supply PID. # Values are transferred to and from this function via given variable names. # Additional normal values can be supplied. The calling function should not # use '_' - surrounded variable names as parameter. # Local variables should surrounded by '_' ( ret --> _ret_ ). # Call: Get_Path_From_PID $myvar mytransfer # # We use 1 returned value in its transfer variable: # par1 = PID. A normal string (fix or given by a variable) # par2 = Name of transfer variable (content = something or nothing) # Uses cut, echo, logger, ps, tr # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Get_Path_From_PID: $# $@" >&2 $debuglog Get_Path_From_PID: $# $@ fi # n=name v=value local _pid_="$1" _value_return_n2_="$2" _value_return_v2_="${!2}" local _pn_='' local _ret_=0 _pn_=$(/bin/ps -p $_pid_ -o ucmd=,args= | /usr/bin/tr -s ' ' | /usr/bin/cut -d ' ' -f 2) if [ -z "$_pn_" ]; then _ret_=5 else _ret_=0 fi # return values eval ${_value_return_n2_}="\"${_pn_}\"" return ${_ret_} } #============================================================================= function Str () { # Build a string of chars to specified length. # par1 = length to build # par2 = build char for string # If no error then push result on stack (1 string) # Uses echo # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Str: $# $@" >&2 $debuglog Str: $# $@ fi local p1="$1" p2="$2" s='' local i=0 ret=0 if [ "$#" -eq 2 ]; then # 2 pars if [ "$p1" -ge 0 ]; then # len = positive or 0 s='' i=0 while [ "$i" -lt "$p1" ]; do let ++i s="${p2}${s}" done Push "$s" ret=0 else # error negative len ret=9 fi else # error in paramcnt ret=2 fi return $ret } #============================================================================= function LSet () { # Set a string at the left side in a string of given length. # par1 = length of resulting string # par2 = string # If no error then push result on stack (1 string) # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG LSet: $# $@" >&2 $debuglog LSet: $# $@ fi local p1="$1" p2="$2" s='' i=0 ret=0 if [ "$#" -eq 2 ]; then # 2 pars if [ "$p1" -gt 0 ]; then # len = positive s="$p2" i=${#p2} if [ "$i" -le $p1 ]; then while [ "$i" -lt "$p1" ]; do let ++i s="${s} " done Push "$s" ret=0 else ret=9 fi else # error negative len ret=9 fi else # error in paramcnt ret=2 fi return $ret } #============================================================================= function RSet () { # Set a string at the right side in a string of given length. # par1 = length of resulting string # par2 = string # If no error then push result on stack (1 string) # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG RSet: $# $@" >&2 $debuglog RSet: $# $@ fi local p1="$1" p2="$2" s='' i=0 ret=0 if [ "$#" -eq 2 ]; then # 2 pars if [ "$p1" -gt 0 ]; then # len = positive s="$p2" i=${#p2} if [ "$i" -le $p1 ]; then while [ "$i" -lt "$p1" ]; do let ++i s=" ${s}" done Push "$s" ret=0 else ret=9 fi else # error negative len ret=9 fi else # error in paramcnt ret=2 fi return $ret } #============================================================================= function CSet () { # Center a string in a string of given length. # par1 = length of resulting string # par2 = string # Uses echo, logger # If no error then push result on stack (1 string) # Return codes: # Standard if [ "$debug" == "yes" ]; then # DEBUG echo "DEBUG CSet: $# $@" >&2 $debuglog CSet: $# $@ fi local s="" is="$2" sl="" sr="" local l="$1" n=0 nl=0 nr=0 ret=0 if [ ${#is} -le $l ]; then n=$[$l-${#is}] nl=$[$n/2] nr=$[$n-$nl] Str $nl ' ' ret=$? if [ $ret -eq 0 ]; then Pop sl fi Str $nr ' ' ret=$? if [ $ret -eq 0 ]; then Pop sr fi s="${sl}${is}${sr}" Push "$s" ret=$? else ret=82 fi return $ret } #============================================================================= function Change_German_Chars () { # Changes all german special chars in a string # CONVERSIONS: # Ä to AE ä to ae # Ö to OE ö to oe # Ü to UE ü to ue ß to ss # par1 = string to change # Push result on stack (1 string) # Uses echo # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG change_german_chars: $# $@" >&2 $debuglog change_german_chars: $# $@ fi local s="$1" ret=0 s=${s//Ä/AE} # Ä to AE s=${s//Ö/OE} # Ö to OE s=${s//Ü/UE} # Ü to UE s=${s//ä/ae} # ä to ae s=${s//ö/oe} # ö to oe s=${s//ü/ue} # ü to ue s=${s//ß/ss} # ß to ss Push "$s" return $ret } #============================================================================= function Check_Digits () { # Checks wether a string contain digits and/or alpha # par1 = string # Uses echo # Return codes: # 0 = String contains only digits # 1 = String contains digits and alpha # 2 = String contains only alpha # 10 = Variable is empty if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Check_Digits: $# $@" >&2 $debuglog Check_Digits: $# $@ fi local dfound=no afound=no s='' str="$1" i=0 n=0 ret=0 if [ "$str" != "" ]; then n=${#str} i=0 while [ "$i" -lt $n ]; do s=${str:$i:1} let ++i case "$s" in 0|1|2|3|4|5|6|7|8|9) dfound=yes;; *) afound=yes;; esac done else echo "${ErrMsg[10]}" >&2 ret=10 fi if [ "$dfound" == yes ] && [ "$afound" == yes ]; then ret=1 elif [ "$dfound" == yes ]; then ret=0 elif [ "$afound" == yes ]; then ret=2 fi return $ret } #============================================================================= function Permissions_To_Value () { # Gives a numerical value for a permissins string e.g. -rwxrwxrwx = 0777 # par1 = permissions string # BITVALUES # 421421421 # "-rwxrwxrwx" 777 normal file # "drwxrwxrwx" 777 normal dir # "-rwsrwsrwt" 7777 all special bits set # "-rwSrwSrwx" 6667 error by special bits - because exec bits not set # "drwxrwxrwT" 1776 error by special bits - because exec bit not set # If no error then Push result on stack (1 string) # Uses echo # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Permissions_To_Value: $# $@" >&2 $debuglog Permissions_To_Value: $# $@ fi local mod="$1" ocg='' oco='' ocu='' perm='' s='' i=0 mg=0 mo=0 ms=0 mu=0 ret=0 # modes for user ocu=${mod:1:3} mu=0 for i in {0..2}; do s=${ocu:$i:1} case "$s" in r) mu=$(($mu+4));; w) mu=$(($mu+2));; x) mu=$(($mu+1));; s) ms=$(($ms+4)) mu=$(($mu+1));; -) :;; *) ret=1;; esac done # modes for group ocg=${mod:4:3} mg=0 for i in {0..2}; do s=${ocg:$i:1} case "$s" in r) mg=$(($mg+4));; w) mg=$(($mg+2));; x) mg=$(($mg+1));; s) ms=$(($ms+2)) mg=$(($mg+1));; -) :;; *) ret=1;; esac done # modes for other oco=${mod:7:3} mo=0 for i in {0..2}; do s=${oco:$i:1} case "$s" in r) mo=$(($mo+4));; w) mo=$(($mo+2));; x) mo=$(($mo+1));; t) ms=$(($ms+1)) mo=$(($mo+1));; -) :;; *) ret=1;; esac done if [ "$ret" -eq 0 ]; then perm="${ms}${mu}${mg}${mo}" Push "$perm" fi return $ret } #============================================================================= function Compare_Version_No () { # Compare 2 version numbers. # par1 = needed version # par2 = actual version # Version numbers in the form x.y.z where only numbers are allowed. # The count of numbers has to be equal in both version numbers. # Return codes: # Standard # 80 = Needed version equal actual version # 82 = Needed version lower than actual version # 83 = Needed version greater than actual version if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Compare_Version_No: $# $@" >&2 $debuglog Compare_Version_No: $# $@ fi local ra="$2" rn="$1" va='' vn='' fin=no n=0 resa=0 resn=0 ret=0 # ra = rest actual # rn = rest needed # va = left part of ra till . # vn = left part of rn till . # n = dummy var for Pop # resa = exit code Find_Substr ra . # resn = exit code Find_Substr rn . ra=${ra#-} rn=${rn#-} while [ "$fin" == no ]; do if [ "${#rn}" -gt 0 ] && [ "${#ra}" -gt 0 ]; then # both have numbers # get parts of version-numbers to vn va Find_Substr "$rn" "." resn=$? if [ "$resn" -eq 0 ]; then # rn has . Pop n fi Find_Substr "$ra" "." resa=$? if [ "$resa" -eq 0 ]; then # ra has . Pop n fi if [ "$resn" -eq 0 ] && [ "$resa" -eq 0 ]; then # both have . vn=${rn%%.*} # vn = left part rn rn=${rn#${vn}.} # rn = rest va=${ra%%.*} # va = left part ra ra=${ra#${va}.} # ra = rest elif [ "$resn" -ne 0 ] && [ "$resa" -ne 0 ]; then # both don't have . vn=$rn # vn = whole rn rn='' va=$ra # va = whole ra ra='' else if [ "$verbose" != no ]; then echo "Error - version numbers differ in count of number parts!" >&2 else $errlog "libfuncstd-sh: Compare_Version_No - version numbers differ in count of number parts" fi fin=yes ret=1 fi # compare parts vn va if [ "$fin" == no ]; then Check_Digits "$vn" resn=$? Check_Digits "$va" resa=$? if [ "$resn" -eq 0 ] && [ "$resa" -eq 0 ]; then # both only digits if [ "$vn" -gt "$va" ]; then # needed > actual fin=yes ret=83 elif [ "$vn" -lt "$va" ]; then # needed < actual fin=yes ret=82 fi elif [ "$vn" != "$va" ]; then # text both differ if [ "$verbose" != no ]; then echo "Error - releases differ!" >&2 else $errlog "libfuncstd-sh: Compare_Version_No - releases differ" fi fin=yes ret=1 fi fi elif [ "${#rn}" -eq 0 ] && [ "${#ra}" -eq 0 ]; then # both have finish fin=yes ret=80 # numbers are equal else # uneqal cnt of parts if [ "$verbose" != no ]; then echo "Error - version numbers differ in count of number parts!" >&2 else $errlog "libfuncstd-sh: Compare_Version_No - version numbers differ in count of number parts" fi fin=yes ret=1 fi done return $ret } #============================================================================= function Check_Package_Name () { # Check the name of a package. # par1 = pkgname # # Package name: NAME[-VERSION[-RELEASE]][.ARCH][.delta].PKGTYP # NAME : String, can contain several minus, no point inside # VERSION : Digits separated with points, no minus inside # RELEASE : Digits and string separated with points, no minus inside # ARCH : i386 i486 i586 i686 noarch src # delta : the word "delta" # PKGTYP : rpm or tgz # # Sample : sample-package-1.2.3-4.5.6.noarch.rpm # # If no error then push results on stack in following order (6 strings): # .pkgtyp .delta .arch -release -version name # Uses echo # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Check_Package_Name: $# $@" >&2 $debuglog Check_Package_Name: $# $@ fi local name="$1" atyp="i386 i486 i586 i686 noarch src" dtyp="delta" local ptyp="rpm tgz" found='' pn='' pv='' pr='' pa='' pd='' pt='' s='' rest='' local n=0 res=0 ret=0 if [ -n "$name" ]; then # name <> "" rest=${name} # rest = full pkg name # get name pn=${rest%.rpm} # rm .rpm pn=${pn%.tgz} # rm .tgz pn=${pn%.$dtyp} # rm .delta for s in $atyp; do pn=${pn%.$s} # rm all atyp done Find_Substr "$pn" "." res=$? if [ "$res" -eq 0 ]; then # pn contains . => ver exist Pop n pn=${pn%%.*} # rm all .* from end pn=${pn%-*} # rm -* from end fi rest=${rest#${pn}} # rm pn from pkg begin if [ -z "$pn" ]; then # pn = '' if [ "$verbose" != no ]; then echo "Error - PKGNAME expected!" >&2 else $errlog "libfuncstd-sh: Check_Package_Name - PKGNAME expected" fi ret=1 # else # pn is ok fi # get type if [ "$ret" -eq 0 ]; then # pn is ok if [ -n "$rest" ]; then # rest <> "" pt=${rest%.rpm} # rm .rpm from end pt=${pt%.tgz} # rm .tgz from end pt=${rest#$pt} # rm pt from begin rest=${rest%${pt}} # rm pt from pkg end if [ -z "$pt" ]; then # pt = '' if [ "$verbose" != no ]; then echo "Error - PKGTYP expected!" >&2 else $errlog "libfuncstd-sh: Check_Package_Name - PKGTYP expected" fi ret=1 # else # pt is ok fi else if [ "$verbose" != no ]; then echo "Error - PKGTYP expected!" >&2 else $errlog "libfuncstd-sh: Check_Package_Name - PKGTYP expected" fi ret=1 fi fi # get delta if [ "$ret" -eq 0 ] && [ -n "$rest" ]; then # pkg rest <> "" pd=${rest%.$dtyp} # rm .delta from pkg end pd=${rest#$pd} # rm first part from pkg begin rest=${rest%${pd}} # rm pd from pkg end fi # delta is ok # get arch if [ "$ret" -eq 0 ] && [ -n "$rest" ]; then # rest <> "" pa=${rest##*.} # rm all *. from pkg begin found=no for s in $atyp; do if [ "$pa" == "$s" ]; then found=yes fi done if [ "$found" == "yes" ]; then pa=".${pa}" rest=${rest%${pa}} # rm pa from pkg end #if [ "$pa" == "src" ] && [ "$pd" == "delta" ]; then # if [ "$verbose" != no ]; then # echo "Error - no delta src package allowed!" >&2 # else # $errlog "libfuncstd-sh: Check_Package_Name - no delta src package allowed" # fi # ret=1 #fi else pa='' fi fi # arch is ok # get version and release if [ "$ret" -eq 0 ] && [ -n "$rest" ]; then # rest <> "" pv=${rest%-*} # rm -* from pkg end if [ "$pv" == "" ]; then # version, no release pv=${rest} pr='' else # version + release pr=${rest#$pv} fi fi # version and release are ok else # no full pkgname given if [ "$verbose" != no ]; then echo "Error - no package name given!" >&2 else $errlog "libfuncstd-sh function Check_Package_Name, no package name given" fi ret=2 fi # push results on stack if [ "$ret" -eq 0 ]; then Push "$pt" Push "$pd" Push "$pa" Push "$pr" Push "$pv" Push "$pn" fi return $ret } #============================================================================= function Leap_Year () { # Check if given year is a leap-year. # par1 = year (long form, 4 digits) # Return codes: # Standard # 0 = is leap-year # 1 = is no leap-year if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Leap_Year: $# $@" >&2 $debuglog Leap_Year: $# $@ fi local ly=no local p1="$1" mytf=0 ret=0 if [ ${#p1} -ne 4 ]; then # unequal 4 digits if [ "$verbose" != no ]; then echo "${ErrMsg[9]}" >&2 else $errlog ${ErrMsg[9]} fi exit 9 fi _Local_X_mod_Y_ "$p1" 4 mytf ret=$? if [ "$ret" -eq 0 ] && [ "$mytf" -eq 0 ]; then # is leap year ly=yes _Local_X_mod_Y_ "$p1" 100 mytf ret=$? if [ "$ret" -eq 0 ] && [ "$mytf" -eq 0 ]; then # is no leap year ly=no _Local_X_mod_Y_ "$p1" 400 mytf ret=$? if [ "$ret" -eq 0 ] && [ "$mytf" -eq 0 ]; then # is leap year ly=yes fi fi fi if [ "$ret" -ne 0 ]; then # error if [ "$verbose" != no ]; then echo "${ErrMsg[1]} From function _Local_X_mod_Y_ $ret" >&2 else $errlog ${ErrMsg[1]} From function _Local_X_mod_Y_ $ret fi exit 1 fi if [ "$ly" == yes ]; then ret=0 else ret=1 fi return $ret } #============================================================================= function Inc_Date_Day () { # Inc day of date with respect to month and year. # Leap-year/Intercalary day will not be recognized. # par1 = date (german short form, eg. 31.12.99) # If no error then push result on stack (1 string) # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Inc_Date_Day: $# $@" >&2 $debuglog Inc_Date_Day: $# $@ fi local p1="$1" dem d=0 m=0 y=0 dom=0 ret=0 # dom = days of sel. month dem="312831303130313130313031" # days each month if [ "$#" -eq 1 ]; then # 1 par d=${p1:0:2} d=${d#0} # rm leading 0 m=${p1:3:2} m=${m#0} # rm leading 0 y=${p1:6:2} dom=${dem:($m-1)*2:2} # days of month in date let ++d if [ "$d" -gt $dom ]; then # day wrap around d=1 let ++m if [ "$m" -gt 12 ]; then # month wrap around m=1 let ++y if [ "$y" -gt 99 ]; then # year wrap around y=0 fi fi fi # beautify d m y if [ "${#d}" -lt 2 ]; then d="0$d" fi if [ "${#m}" -lt 2 ]; then m="0$m" fi if [ "${#y}" -lt 2 ]; then y="0$y" fi # output date Push "$d.$m.$y" else ret=2 fi return $ret } #============================================================================= function Dec_Date_Day () { # Dec day of date with respect to month and year. # Leap-year/Intercalary day will not be recognized. # par1 = date (german short form, eg. 31.12.99) # If no error then push result on stack (1 string) # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Dec_Date_Day: $# $@" >&2 $debuglog Dec_Date_Day: $# $@ fi local p1="$1" dem d=0 m=0 y=0 dom=0 ret=0 # dom = days of sel. month dem="312831303130313130313031" # days each month if [ "$#" -eq 1 ]; then # 1 par d=${p1:0:2} d=${d#0} # rm leading 0 m=${p1:3:2} m=${m#0} # rm leading 0 y=${p1:6:2} let --d if [ "$d" -eq 0 ]; then # day wrap around let --m if [ "$m" -eq 0 ]; then # prev mon wrap around m=12 let --y if [ "$y" -lt 0 ]; then # year wrap around y=99 fi fi dom=${dem:($m-1)*2:2} d=$dom fi # beautify d m y if [ "${#d}" -lt 2 ]; then d="0$d" fi if [ "${#m}" -lt 2 ]; then m="0$m" fi if [ "${#y}" -lt 2 ]; then y="0$y" fi # output date Push "$d.$m.$y" else ret=2 fi return $ret } #============================================================================= function Compare_Dates () { # compare date1 with date2 (german short form, eg. 31.12.99). # par1 = date1 # par2 = date2 # Return codes: # Standard # 80 = If date1 = date2 # 82 = If date1 < date2 # 83 = If date1 > date2 if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Compare_Dates: $# $@" >&2 $debuglog Compare_Dates: $# $@ fi local p1="$1" p2="$2" d1='' d2='' ret=0 if [ "$#" -eq 2 ]; then # 2 pars d1=${p1:6:2}${p1:3:2}${p1:0:2} d2=${p2:6:2}${p2:3:2}${p2:0:2} if [ "$d1" \> "$d2" ]; then ret=83 elif [ "$d1" == "$d2" ]; then ret=80 else ret=82 fi else ret=2 fi return $ret } #============================================================================= function Inc_LDate_Day () { # Inc day of date with respect to month and year. # Leap-year/Intercalary day will be recognized. # par1 = date (german long form e.g. 31.12.2000) # If no error then push result on stack (1 string) # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Inc_LDate_Day: $# $@" >&2 $debuglog Inc_LDate_Day: $# $@ fi local p1="$1" dem="312831303130313130313031" # dem = days each month local d=0 dom=0 m=0 y=0 ret=0 # dom = days of sel. month if [ "$#" -eq 1 ]; then # 1 par d=${p1:0:2} d=${d#0} # rm leading 0 m=${p1:3:2} m=${m#0} # rm leading 0 y=${p1:6:4} dom=${dem:($m-1)*2:2} # days of month in date if [ "$m" -eq 2 ]; then # is FEB Leap_Year $y ret=$? if [ "$ret" -eq 0 ]; then # is leap year let ++dom else ret=0 fi fi let ++d if [ "$d" -gt $dom ]; then # day wrap around d=1 let ++m if [ "$m" -gt 12 ]; then # month wrap around m=1 # rm leading 0s while [ "${y:0:1}" == 0 ]; do y="${y#0}" done if [ -z "$y" ]; then y=0 fi let ++y fi fi # beautify d m y if [ "${#d}" -lt 2 ]; then d="0$d" fi if [ "${#m}" -lt 2 ]; then m="0$m" fi case ${#y} in 1) y="000$y";; 2) y="00$y";; 3) y="0$y";; esac # output date Push "$d.$m.$y" else ret=2 fi return $ret } #============================================================================= function Dec_LDate_Day () { # Dec day of date with respect to month and year. # Leap-year/Intercalary day will be recognized. # par1 = date (german long form e.g. 31.12.2000) # If no error then push result on stack (1 string) # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Dec_LDate_Day: $# $@" >&2 $debuglog Dec_LDate_Day: $# $@ fi local p1="$1" dem="312831303130313130313031" # days each month local d=0 m=0 y=0 dom=0 ret=0 # dom = days of sel. month if [ "$#" -eq 1 ]; then # 1 par d=${p1:0:2} d=${d#0} # rm leading 0 m=${p1:3:2} m=${m#0} # rm leading 0 y=${p1:6:4} let --d if [ "$d" -eq 0 ]; then # day wrap around let --m if [ "$m" -eq 0 ]; then # prev mon wrap around m=12 # rm leading 0s while [ "${y:0:1}" == 0 ]; do y=${y#0} done if [ -z "$y" ]; then y=0 fi let --y fi dom=${dem:($m-1)*2:2} if [ "$m" -eq 2 ]; then Leap_Year $y ret=$? if [ "$ret" -eq 0 ]; then # is leap-year let ++dom else ret=0 fi fi d=$dom fi # beautify d m y if [ "${#d}" -lt 2 ]; then d="0$d" fi if [ "${#m}" -lt 2 ]; then m="0$m" fi case ${#y} in 1) y="000$y";; 2) y="00$y";; 3) y="0$y";; esac # output date Push "$d.$m.$y" else ret=2 fi return $ret } #============================================================================= function Compare_LDates () { # compare date1 with date2 (german long form, eg. 31.12.2000). # par1 = date1 # par2 = date2 # Return codes: # Standard # 80 = If date1 = date2 # 82 = If date1 < date2 # 83 = If date1 > date2 if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Compare_LDates: $# $@" >&2 $debuglog Compare_LDates: $# $@ fi local p1="$1" p2="$2" d1='' d2='' ret=0 if [ "$#" -eq 2 ]; then # 2 pars d1=${p1:6:4}${p1:3:2}${p1:0:2} d2=${p2:6:4}${p2:3:2}${p2:0:2} if [ "$d1" \> "$d2" ]; then ret=83 elif [ "$d1" == "$d2" ]; then ret=80 else ret=82 fi else ret=2 fi return $ret } #============================================================================= function Calc_Date_Diff () { # Calc diff of days (date = German short form, eg.: 31.12.99) # Leap-year/Intercalary day will not be recognized. # par1 = date1 # par2 = date2 # date1 must be lower or equal then date2 # Push result on stack (1 string) # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Calc_Date_Diff: $# $@" >&2 $debuglog Calc_Date_Diff: $# $@ fi local p1="$1" p2="$2" p2s='' dem d='' m='' y='' dom=0 i=0 ret=0 # dom = days of month dem="312831303130313130313031" # days each month if [ "$#" -eq 2 ]; then # 2 pars d=${p1:0:2} m=${p1:3:2} y=${p1:6:2} p2s="${p2:6:2}${p2:3:2}${p2:0:2}" if [ ! "$y$m$d" \> "$p2s" ]; then i=0 while [ "$y$m$d" \< "$p2s" ]; do let ++i d=${d#0} # rm leading 0 m=${m#0} # rm leading 0 dom=${dem:($m-1)*2:2} # days of month in date let ++d if [ "$d" -gt $dom ]; then # day wrap around d=1 let ++m if [ "$m" -gt 12 ]; then # month wrap around m=1 let ++y if [ "$y" -gt 99 ]; then # year wrap around y=0 fi fi fi # beautify d m y if [ "${#d}" -lt 2 ]; then d="0$d" fi if [ "${#m}" -lt 2 ]; then m="0$m" fi if [ "${#y}" -lt 2 ]; then y="0$y" fi done # output diff Push "$i" else if [ "$verbose" != no ]; then echo "${ErrMsg[83]}" >&2 else $errlog ${ErrMsg[83]} fi ret=83 fi else if [ "$verbose" != no ]; then echo "${ErrMsg[2]}" >&2 else $errlog ${ErrMsg[2]} fi ret=2 fi return $ret } #============================================================================= function Calc_Time_Diff () { # calc time difference between 2 times (t2 - t1). # par1 = first time t1 # par2 = last time t2 # timeformat is hh:mm:ss # push result on stack (1 string) # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Calc_Time_Diff: $# $@" >&2 $debuglog Calc_Time_Diff: $# $@ fi local p1="$1" p2="$2" t1h=0 t1m=0 t1s=0 t1sec=0 t2h=0 t2m=0 t2s=0 t2sec=0 \ dsec=0 tr=0 ret=0 if [ "$#" -eq 2 ]; then # 2 pars # change p1 to secs t1h=${p1:0:2} t1m=${p1:3:2} t1s=${p1:6:2} t1h=${t1h#0} t1m=${t1m#0} t1s=${t1s#0} t1sec=$[(${t1h}*3600)+(${t1m}*60)+${t1s}] # change p2 to secs t2h=${p2:0:2} t2m=${p2:3:2} t2s=${p2:6:2} t2h=${t2h#0} t2m=${t2m#0} t2s=${t2s#0} t2sec=$[(${t2h}*3600)+(${t2m}*60)+${t2s}] # correct day overflow if [ "$t1sec" -gt "$t2sec" ]; then t2sec=$[$t2sec+86400] fi # diff secs = t2 - t1 dsec=$[${t2sec}-${t1sec}] # change diff of secs to timeformat t1h=$[${dsec}/3600] tr=$[${dsec}-(${t1h}*3600)] t1m=$[${tr}/60] t1s=$[${tr}-(${t1m}*60)] # trim numbers if [ "${#t1h}" -lt 2 ]; then t1h="0${t1h}" fi if [ "${#t1m}" -lt 2 ]; then t1m="0${t1m}" fi if [ "${#t1s}" -lt 2 ]; then t1s="0${t1s}" fi Push "${t1h}:${t1m}:${t1s}" else # error in paramcnt ret=2 fi return $ret } #============================================================================= function Sum_Times () { # Sum 2 times. # par1 = first time # par2 = second time # timeformat is hh:mm:ss # push result on stack (1 string) # Return codes: # Standard if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Sum_Times: $# $@" >&2 $debuglog Sum_Times: $# $@ fi local p1="$1" p2="$2" t1h=0 t1m=0 t1s=0 t1sec=0 t2h=0 t2m=0 t2s=0 t2sec=0 \ ssec=0 tr=0 ret=0 if [ "$#" -eq 2 ]; then # 2 pars # change p1 to secs t1h=${p1:0:2} t1m=${p1:3:2} t1s=${p1:6:2} t1h=${t1h#0} t1m=${t1m#0} t1s=${t1s#0} t1sec=$[(${t1h}*3600)+(${t1m}*60)+${t1s}] # change p2 to secs t2h=${p2:0:2} t2m=${p2:3:2} t2s=${p2:6:2} t2h=${t2h#0} t2m=${t2m#0} t2s=${t2s#0} t2sec=$[(${t2h}*3600)+(${t2m}*60)+${t2s}] # sum secs = t1 + t2 ssec=$[${t1sec}+${t2sec}] # change sum of secs to timeformat t1h=$[${ssec}/3600] tr=$[${ssec}-(${t1h}*3600)] t1m=$[${tr}/60] t1s=$[${tr}-(${t1m}*60)] # trim numbers if [ "${#t1h}" -lt 2 ]; then t1h="0${t1h}" fi if [ "${#t1m}" -lt 2 ]; then t1m="0${t1m}" fi if [ "${#t1s}" -lt 2 ]; then t1s="0${t1s}" fi Push "${t1h}:${t1m}:${t1s}" else # error in paramcnt ret=2 fi return $ret } #============================================================================= function Get_Lines () { # get lines from a file from first till last line. # par1 = filename # par2 = first line # par3 = last line # Output goes to STDOUT # Return codes: # 0 = OK # 2 = Error in parameter count # 5 = File not found # 19 = Start line out of range (file to short or start line <= 0) # 20 = Last line out of range (file to short) # 21 = Last line before start line if [ "$_DEBUG_" == "yes" ]; then # DEBUG #echo "DEBUG Get_Lines: $# $@" >&2 $debuglog Get_Lines: $# $@ fi local inf="$1" ifs='' s='' local i=0 n=0 sl="$2" el="$3" ret=0 if [ "$#" -ne 3 ];then # error in paramcount ret=2 elif ! [ -e "$inf" ]; then # file not found ret=5 else n=$(cat $inf | wc -l) # file length if [ "$sl" -gt $n ] || [ "$sl" -le 0 ]; then # sl out of range ret=19 elif [ "$el" -lt $sl ]; then # error el before sl ret=21 elif [ "$el" -gt $n ]; then # error el out of range ret=20 else # OK ifs="$IFS" # save IFS IFS='' i=0 # counter while read -rs s; do # read line let ++i # line number if [ "$i" -ge $sl ] && [ "$i" -le $el ]; then echo "$s" # output line fi done<$inf IFS="$ifs" # restore IFS fi fi return $ret } #============================================================================= function Insert_Line () { # insert a line in a file after specified line number. # par1 = filename # par2 = line number (0 - n) # par3 = line to insert # Output goes to STDOUT # Return codes: # 0 = OK # 2 = Error in parameter count # 5 = File not found # 19 = Start line out of range (file to short or start line <= 0) if [ "$_DEBUG_" == "yes" ]; then # DEBUG echo "DEBUG Insert_Line: $# $@" >&2 # $debuglog Insert_Line: $# $@ fi local inf="$1" si="$3" ifs='' s='' local i=0 n=0 sl="$2" ret=0 if [ "$#" -ne 3 ];then # error in paramcount ret=2 elif ! [ -e "$inf" ]; then # file not found ret=5 else n=`cat $inf | wc -l` # file length if [ "$sl" -gt $n ] || [ "$sl" -lt 0 ]; then # sl out of range ret=19 else # OK ifs="$IFS" # save IFS IFS='' i=0 # counter if [ "$i" -eq $sl ]; then echo "$si" # output specif. line fi while read -rs s; do # read line let ++i # line number echo "$s" # output line if [ "$i" -eq $sl ]; then echo "$si" # output specif. line fi done<$inf IFS="$ifs" # restore IFS fi fi return $ret } #============================================================================= function Replace_Line () { # replace a line in a file. # par1 = filename # par2 = line number (1 - n) # par3 = replacement line # Output goes to STDOUT # Return codes: # 0 = OK # 2 = Error in parameter count # 5 = File not found # 19 = Start line out of range (file to short or start line <= 0) if [ "$_DEBUG_" == "yes" ]; then # DEBUG #echo "DEBUG Replace_Line: $# $@" >&2 $debuglog Replace_Line: $# $@ fi local inf="$1" sr="$3" ifs='' s='' local i=0 n=0 sl="$2" ret=0 if [ "$#" -ne 3 ];then # error in paramcount ret=2 elif ! [ -e "$inf" ]; then # file not found ret=5 else n=$(cat $inf | wc -l) # file length if [ "$sl" -gt $n ] || [ "$sl" -lt 1 ]; then # sl out of range ret=19 else # OK ifs="$IFS" # save IFS IFS='' i=0 # counter while read -rs s; do # read line let ++i # line number if [ "$i" -eq $sl ]; then echo "$sr" # output replacement else echo "$s" # output read line fi done<$inf IFS="$ifs" # restore IFS fi fi return $ret } #============================================================================= function Remove_Lines () { # rm lines from a file from first till last line. # par1 = filename # par2 = first line # par3 = last line # Output goes to STDOUT # Return codes: # 0 = OK # 2 = Error in parameter count # 5 = File not found # 19 = Start line out of range (file to short or start line <= 0) # 20 = Last line out of range (file to short) # 21 = Last line before start line if [ "$_DEBUG_" == "yes" ]; then # DEBUG #echo "DEBUG Remove_Lines: $# $@" >&2 $debuglog Remove_Lines: $# $@ fi local inf="$1" ifs='' s='' local i=0 n=0 sl="$2" el="$3" ret=0 if [ "$#" -ne 3 ];then # error in paramcount ret=2 elif ! [ -e "$inf" ]; then # file not found ret=5 else n=`cat $inf | wc -l` # file length if [ "$sl" -gt $n ] || [ "$sl" -le 0 ]; then # sl out of range ret=19 elif [ "$el" -lt $sl ]; then # error el before sl ret=21 elif [ "$el" -gt $n ]; then # error el out of range ret=20 else # OK ifs="$IFS" # save IFS IFS='' i=0 # counter while read -rs s; do # read line let ++i # line number if [ "$i" -lt $sl ] || [ "$i" -gt $el ]; then echo "$s" # output line fi done<$inf IFS="$ifs" # restore IFS fi fi return $ret } ############################################################################## # SOURCE FILES # #. /usr/local/etc/main.conf # config main #. $LLIBDIR/libfuncerr-sh # functions error #. $LLIBDIR/libfuncstd-sh # functions standard #. $LLIBDIR/libfuncmath-sh # functions math #. $LLIBDIR/libfuncmath2-sh # functions math2 #. $LLIBDIR/libfuncip-sh # functions IP #. $LLIBDIR/libfunchart-sh # functions chart #. $LLIBDIR/libfunccddvd-sh # functions cd-dvd ############################################################################## # DECLARATION OF STANDARD CONSTANTS AND VARIABLES # readonly package=Utils # package name readonly package_file=ksm-utils # package file name #readonly vinfopath="/usr/local/share/$package_file" # path to package dir readonly version=1.0.4 # package version readonly release=37.1.0 # package release readonly scriptname=$(basename $0) # name of script #readonly tempfile=$TEMPDIR/$scriptname.$UID.tmp # temporary file name #readonly tempfile=$(mktemp -u $TEMPDIR/$scriptname.$UID.XXXXXX) # temporary file name #readonly lockfile=$TEMPDIR/lock/$scriptname.$UID.lock # lock file name readonly debuglog="/usr/bin/logger -p user.debug -t $scriptname -- DEBUG:" # log dbg msg readonly errlog="/usr/bin/logger -p user.err -t $scriptname -- ERROR:" # log err msg readonly infolog="/usr/bin/logger -p user.info -t $scriptname -- INFO:" # log inf msg cmd='' # sub command debug=no # debug=yes/no verbose='' # verbose=yes/''/no err=${_ERR_OK_} # error code ############################################################################## # USER FILL IN AT FIRST RUN ############################################################################## # SYSTEM ############################################################################## # USER-CONSTANTS ############################################################################## # USER-VARIABLES # # STRINGS args='' # all args from cmdline arg1='' # 1. arg from cmdline #opt_o='' # option -o (yes) # option --output (yes) #opt_i='' # option -i (arg) # option --infile (arg) #opt_o='' # option -o (arg) # option --outfile (arg) #opt_p='' # option -p (arg) # option --pages (arg) opt_r='' # option -r (yes) cmod='' # compress. mode flag # NUMBERS #p_first=0 # first page #p_last=0 # last page # ARRAYS # Indexed arrays are always zero based string arrays. # If index starts with 1 and all members are assigned then # count of members of array = last index of array #declare -a arr #maxarr="${#arr[@]}" # get number of elements in arr #unset arr[@] # remove the entire array ############################################################################## # SIGNAL HANDLING ############################################################################## # FUNCTIONS # ############################################################################## # HELP # #============================================================================= function helptext () { # Output helptext # Uses cat, echo, logger # Return codes: # Standard if [ "$debug" == "yes" ]; then # DEBUG echo "DEBUG helptext: $# $@" >&2 $debuglog helptext: $# $@ fi cat < EOT # -o|--output = Output to STDOUT. # -i f = Input from file . # --infile=f = Input from file . # -o f = Output to file . # --outfile=f = Output to file . # -p s,e = Pages s=START e=END. # --pages=s,e = Pages s=START e=END. #FILES #Used directories and files: # # Config Global = /usr/local/etc/sample.conf # Config User = ~/.samplerc return } #============================================================================= function Show_Err () { # Show the error text. # par1 = errcode # par2 = additional errtext # Uses echo, logger # Return codes: # Standard if [ "$debug" == "yes" ]; then # DEBUG echo "DEBUG Show_Err: $# $@" >&2 $debuglog Show_Err: $# $@ fi local msgtxt="${ErrMsg[$1]} $2" local ret=0 if [ "$verbose" != no ]; then echo "${msgtxt}" >&2 else $errlog ${msgtxt} fi ret=$? return $ret } #============================================================================= function uncompress () { # Detect archive format from cmd and untar the compressed archive. # par1 = # Uses echo, logger, tar # Return codes: # Standard if [ "$debug" == "yes" ]; then # DEBUG echo "DEBUG uncompress: $# $@" >&2 $debuglog uncompress: $# $@ fi local ret=0 # set compression mode from subcmd case "$cmd" in -g) cmod="-z";; # gzip -b) cmod="-j";; # bzip2 -x) cmod="-J";; # xz -l) cmod="--lzma";; # lzma *);; esac if [ -z "$opt_r" ]; then # option -r not given tar --wildcards -xp ${cmod} -f $arg1 $args err=$? else # option -r if [ "$EUID" -eq 0 ]; then tar --no-same-owner --wildcards -xp ${cmod} -f $arg1 $args err=$? else Show_Err 13 "-r Only root can do this." err=13 fi fi return $ret } #============================================================================= function mainproc () { # Autodetect archive format and untar the compressed archive. # par1 = # Uses echo, logger, tar # Return codes: # Standard if [ "$debug" == "yes" ]; then # DEBUG echo "DEBUG mainproc: $# $@" >&2 $debuglog mainproc: $# $@ fi local lext='' local ret=0 #local -a arr #maxarr="${#arr[@]}" # get number of elements in arr #unset arr[@] # remove the entire array # set compression mode from file extension lext=${arg1##*.} case "$lext" in tgz|gz) cmod="-z";; # gzip tbz2|bz2) cmod="-j";; # bzip2 txz|xz) cmod="-J";; # xz tlz|lzma) cmod="--lzma";; # lzma *) Show_Err 1 "Cannot autodetect compression format, give subcmd." ret=1;; esac if [ "$ret" -eq 0 ]; then # ext known if [ -z "$opt_r" ]; then # option -r not given tar --wildcards -xp ${cmod} -f $arg1 $args ret=$? else # option -r if [ "$EUID" -eq 0 ]; then tar --no-same-owner --wildcards -xp ${cmod} -f $arg1 $args ret=$? else Show_Err 13 "-r Only root can do this." ret=13 fi fi fi return $ret } ############################################################################## # GET OPTIONS ############################################################################## # Give 2 strings and all cmdline_args to func GetOpt # (POSIX_options Gnu_long_options cmdline_args): # GetOpt 'hVdqvi:m:' 'help version debug quiet verbose infile= myval=' $@ # # A ':' after a POSIX option means this option needs an arg. # A '=' after a Gnu long option means this option needs an arg. # # All cmd/options have to be initialised to ''! # # POSIX options are classified in 2 categories: # a) cmds (mutually exclusive). All cmds are given to var 'cmd'. # b) options (as many as you like). Each option is given to it's own var. # As a general rule: If cmds/options are given multiple then last given wins. # # Options can take 1 argument (no whitespace in arg). If you want to give more # than 1 arg or want to use multiple strings as 1 arg then concatenate them # together with a delimiter like ',' or ';' or '.' # Use a delimiter which will not be part of the arg: # sampleprog -m val1,val2 # sampleprog --myval=val1,val2 # It's at the programmers responsibility to do meaningfull things with the # content of the options. # # If err != 0 then all args are processed, else continue to look for options. # When GetOpt finishes then all options are removed from cmdline. # if [ "$debug" == "yes" ]; then # DEBUG echo "DEBUG Parse Commandline: $# $@" >&2 $debuglog Parse Commandline: $# $@ fi # err=${_ERR_OK_} while [ "$err" -eq 0 ]; do GetOpt 'hVdqvbglxr' 'help version debug quiet verbose' $@ err=$? #echo "DEBUG GET OPTIONS: err=${err} _OPTNAME_=${_OPTNAME_} _OPTVAL_=${_OPTVAL_} _OPTPOS_=${_OPTPOS_} _OPTIDX_=${_OPTIDX_}" >&2 if [ $err -eq 0 ]; then case "$_OPTNAME_" in h|help) cmd="-h";; V|version) cmd="-V";; b) cmd="-${_OPTNAME_}";; g) cmd="-${_OPTNAME_}";; l) cmd="-${_OPTNAME_}";; x) cmd="-${_OPTNAME_}";; d|debug) debug=yes;; q|quiet) verbose=no;; v|verbose) verbose=yes;; r) opt_r=yes;; # o|output) opt_o=yes;; # i|infile) opt_i="${_OPTVAL_}";; # o|outfile) opt_o="${_OPTVAL_}";; # p|pages) opt_p="${_OPTVAL_}";; --) break;; :) Show_Err ${_ERR_MISSING_ARG_FOR_OPT_} "-${_OPTVAL_}" exit ${_ERR_MISSING_ARG_FOR_OPT_};; ?) Show_Err ${_ERR_UNKNOWN_OPT_} "-${_OPTVAL_}" exit ${_ERR_UNKNOWN_OPT_};; *) Show_Err ${_ERR_UNKNOWN_ERR_} "_OPTNAME_=${_OPTNAME_} _OPTVAL_=${_OPTVAL_}" exit ${_ERR_UNKNOWN_ERR_};; esac fi done err=${_ERR_OK_} shift ${_OPTIDX_} # rm all opts from cmdline # # Uncomment if giving a cmd is mandatory #if [ -z "$cmd" ]; then # error no cmd given # Show_Err ${_ERR_MISSING_SUB_CMD_} "" # exit ${_ERR_MISSING_SUB_CMD_} #fi ############################################################################## # CHECK LINK NAMES ############################################################################## # CHECK OPTIONS ############################################################################## # CHECK VERSION ############################################################################## # CHECK ARGUMENTS # case "$cmd" in ''|-b|-g|-l|-x) if [ "$#" -ge 1 ]; then # parameter count ok arg1="$1" shift args="$@" shift $# else # error in param count Show_Err ${_ERR_WRONG_PAR_COUNT_} "" exit ${_ERR_WRONG_PAR_COUNT_} fi ;; *) if [ "$#" -ne 0 ]; then # error in param count Show_Err ${_ERR_WRONG_PAR_COUNT_} "" exit ${_ERR_WRONG_PAR_COUNT_} fi ;; esac ############################################################################## # LOCK ############################################################################## # MAINPROGRAM ############################################################################## # if [ "$debug" == "yes" ]; then # DEBUG echo "DEBUG Main: $# $@" >&2 $debuglog Main: $# $@ fi # Check what to do (sub commands, options and args are removed from cmdline) case "$cmd" in '') mainproc err=$? ;; -h) helptext exit 0 ;; -V) echo "${scriptname}: (${package}) $package_file ${version}-${release}" exit 0 ;; -b|-g|-l|-x) uncompress err=$? ;; *) # error Show_Err ${_ERR_SUB_CMD_NOT_FOUND_} "" err=${_ERR_SUB_CMD_NOT_FOUND_} ;; esac #rm -f $lockfile exit $err