korn_shell.sh
#!/usr/bin/ksh
# William Jiang in Solaris.
# This file creates package according to original user programs.
#*******************************************************************
# Notice:
# 1. I can't suppose the following type could be inserted:
# block special file(b),character special file(c),
# symbolic link(l), fifo (named pipe)(p).
# So, if you have this type file, just modify it manually in
# 'prototype' file after creation.
# 2. .file(.profile..) couldn't be distinguished by this script.
# 3. All directories are the default setting 0755, it's nail-biting
# when the directory has different mask.
# 4. Some special file name, such as u_'$*2', maybe not recognised
#
# All above will be improved on further version.
# However, it can fluently and flexible generate package.
#
#*******************************************************************
#--------------------------
# Define some macros.
#--------------------------
# Define return logical value.
TRUE=0
FALSE=1
# Define macro commands.
CMD=`basename $0`
#PKGINFO=pkginfo
PKGMK=pkgmk
READMEFILE=README
TMPPROTOTYPE="/tmp/prototype$RANDOM"
TMPFILE="/tmp/tmp$SECONDS"
# Define user values.
PERM_EXEC=0755
PERM_RDWR=0644
# Define these macros to null firstly, they can get real values
# from command line or from script execution.
PKGNAME=
USERNAME=
USERGROUP=
BASEDIRECTORY=
#LOGFILE=${BASEDIRECTORY}/${CMD}.log
LOGFILE=/usr/william/${CMD}.log
#----------------------------------
# Now the functions definations.
#----------------------------------
# Usage of this shell script.
Usage() {
echo "usage:
$CMD [-d directory] [-u username] [-g group] [-h|-?] [-v] [PackageName]
where:
-d user directory
-h print this message
-g user group
-u user name
-v version of this script
Package Name is the package's name you want to create.
You may not choose them from command line. Instead, you will meet them
during the execution proceed, and can refer by recommending values."
}
# Inform the user to input y(es) or n(o) to continue.
Getyn() {
while echo "$*(y/n) (y) \c"
do read yn
case $yn in
""|Y|y) return $TRUE
;;
N|n) return $FALSE
;;
*) echo "Please answer y or n"
;;
esac
done
}
# Prompt user to confirm.
Prompt() {
echo "\n$*\n \c"
verify=`line`
[ ! -z "$verify" ] && return $TRUE || return $FAIL
}
# Print Readme file.
ShowReadme() {
[ -r "${READMEFILE}" ] && more -c ${READMEFILE}
}
Pkgappinfo() {
echo "\n
The Package ${PKGNAME} has been successfully created.
You can use the following commands to manage it.
*********************************************************************
pkgadd pkgadd (1m) - transfer software packages to the system
pkgask pkgask (1m) - stores answers to a request script
pkgchk pkgchk (1m) - check package installation accuracy
pkginfo pkginfo (1) - display software package information
pkginfo pkginfo (4) - package characteristics file
pkgmap pkgmap (4) - package contents description file
pkgmk pkgmk (1) - produce an installable package
pkgparam pkgparam (1) - display package parameter values
pkgproto pkgproto (1) - generate prototype file entries for input to pkgmk command
pkgrm pkgrm (1m) - remove a package from the system
pkgtrans pkgtrans (1) - translate package format
*********************************************************************
"
}
# Input Information about user and user's directory.
InputInfo() {
echo "
You must confirm the user name and the directory which
sub-directories and files rely on or exist."
if [ -z "${USERNAME}" ]; then
echo "
Input the user you want the package holding. All package contents
will be by way of using it. Directly enter to use default."
echo "
user[ Default is `id | sed -e 's/)\{1\}.*//' -e 's/.*(//'` ]: \c"
read USERNAME1
USERNAME=${USERNAME1:=`id | sed -e 's/)\{1\}.*//' -e 's/.*(//'`}
# USERNAME=${USERNAME1:=${LOGNAME}}
else
echo "\n"You choose user name: ${USERNAME}
fi
if [ -z "${USERGROUP}" ]; then
# Next two expression are all right.
# USERGROUP=`id ${USERNAME} | cut -d \) -f2 | cut -d \( -f2`
USERGROUP=`id ${USERNAME} | sed -e 's/.*(//' -e 's/)//'`
else
echo "\n"You choose user group: ${USERGROUP}
fi
if [ -z "${BASEDIRECTORY}" ]; then
while echo "
Which directory all your source sub-directories and files are located?
directory[Default is `pwd`]: \c"
do read BASEDIRECTORY
BASEDIRECTORY=${BASEDIRECTORY:=`pwd`}
if [ ! -d "${BASEDIRECTORY}" ]; then
Prompt "directory \"$BASEDIRECTORY\" doesn't exist!"
continue
else break
fi
done
else
echo "\n"You choose directory: ${BASEDIRECTORY}
fi
# This step is important
PKGINFO=${BASEDIRECTORY}/pkginfo
PROTOTYPE=${BASEDIRECTORY}/prototype
# Clear 'pkginfo' file.
[ -f "${PKGINFO}" ] && cat /dev/null > ${PKGINFO}
# Clear 'prototype' file.
[ -f "${PROTOTYPE}" ] && cat /dev/null > ${PROTOTYPE}
return ${TRUE}
}
# Create 'pkginfo' file.
Mk_pkginfo() {
Getyn "\n"Do you want to configure \"pkginfo\" file?
if [ "$?" != 0 ]; then
return ${FALSE};
fi
echo "
Now configure 'pkginfo' file. Initial values have been given.
You can modify them, or just use the default, as you like.
"
# echo "[ CLASSES = none ]? \c"
# read Choose
# case ${Choose} in
# ""|Y|y) echo CLASSES=none >>${PKGINFO};;
# N|n) continue;;
# *) echo CLASSES=${Choose} >>${PKGINFO};;
# esac
echo CLASSES=none >>${PKGINFO}
echo BASEDIR=/ >>${PKGINFO}
# echo OAMBASE=/ >>${PKGINFO}
# echo PATH=${PATH} >> ${PKGINFO}
echo TZ=PRC >>${PKGINFO}
echo 'PATH=/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin' >>${PKGINFO}
echo 'OAMBASE=/usr/sadm/sysadm' >>${PKGINFO}
# Here ${PKGNAME} MUST add double quotation marks!
# if [ "X${PKGNAME}" != "X" ]; then
if [ -n "${PKGNAME}" ]; then
echo PKG=${PKGNAME} >>${PKGINFO}
else
echo "Package Name max 8 chars, if exceeding this limit, maybe error."
echo "[ Package Name(default is MyPackage) ]: \c"
read Choose
case ${Choose} in
""|Y|y) echo PKG=MyPackage >>${PKGINFO};;
N|n) continue;;
*) echo PKG=${Choose} >>${PKGINFO};;
esac
fi
echo "[ VERSION = 1.0.0 ]? \c"
read Choose
case ${Choose} in
""|Y|y) echo VERSION=1.0.0 >>${PKGINFO};;
N|n) continue;;
*) echo VERSION=${Choose} >>${PKGINFO};;
esac
echo "[ NAME(simple description) ]: \t"
read Choose
case ${Choose} in
""|Y|y) echo NAME=$(uname -s -n -m -r) >>${PKGINFO};;
N|n) continue;;
*) echo NAME=${Choose} >>${PKGINFO};;
esac
echo ARCH=`uname -p` >>${PKGINFO}
echo "[ CATEGORY = utility ]? \c"
read Choose
case ${Choose} in
""|Y|y) echo CATEGORY=utility >>${PKGINFO};;
N|n) continue;;
*) echo CATEGORY=${Choose} >>${PKGINFO};;
esac
echo "[ VENDOR = ${USERNAME} ]? \c"
read Choose
case ${Choose} in
""|Y|y) echo VENDOR=${USERNAME} >>${PKGINFO};;
N|n) continue;;
*) echo VENDOR=${Choose} >>${PKGINFO};;
esac
set `date`
echo PSTAMP=$(echo $3th$2$6) >>${PKGINFO}
echo "[ EMAIL ]: \c"
read Choose
case ${Choose} in
""|Y|y) echo EMAIL= >>${PKGINFO};;
N|n) continue;;
*) echo EMAIL=${Choose} >>${PKGINFO};;
esac
echo ISTATES=S >>${PKGINFO}
echo RSTATES='S s 1 2 3' >>${PKGINFO}
#echo "PKGINST=GNUzip" >>${PKGINFO}
#echo 'PKGSAV=/var/sadm/pkg/GNUzip/save' >>${PKGINFO}
echo INSTDATE=`date` >>${PKGINFO}
echo UPDATE=yes >>${PKGINFO}
echo "[ Descriptions (detailed description) ]: \t"
read Choose
case ${Choose} in
""|Y|y) echo DESC='' >>${PKGINFO};;
N|n) continue;;
*) echo DESC=${Choose} >>${PKGINFO};;
esac
echo Successfully configure 'pkginfo' file!
# sleep 1;
}
# Adding all directories to 'prototype' file.
AddDirectory() {
find ${BASEDIRECTORY} -type d > ${TMPFILE}
# add 'd none ' except null line and '^!' line.
# $ and s can not be connected together, as: 1,$s...
# to prevent blank line, I write them continously, as Oi...
ksh -c "vi - ${TMPFILE} <&5
# Finally, add the file in the 'prototype' file
cat ${TMPFILE} >> ${TMPPROTOTYPE}
unlink ${TMPFILE}
}
# Adding all files under a certain directory to 'prototype' file.
AddFile() {
cd ${BASEDIRECTORY}
find ${BASEDIRECTORY} -type d | while read Directory
do
cd $Directory
# 'find' command is effctice to .file.
# find .${Directory -type f >${TMPFILE}
# It is helpless to .file. such as ..base, .profile.
ls -d -p ${Directory}/*
# Next statement judges and omit blank directory.
[ "$?" != "0" ] && continue;
ls -d -p ${Directory}/* | sed '/\/$/d' > ${TMPFILE}
# add 'd none ' except null line and '^!' line.
ksh -c "vi - ${TMPFILE} <&5
# add execution rights to relative files.
ls -ld *|grep '^[^d]'|awk '$1~/[x]+/{print $9}'|while read FileStr
do
if [ -n "${FileStr}" ]; then
ksh -c "ed - ${TMPFILE} <&5
else
echo "${FileStr} is null string."
fi
done
# Finally, put the file to prototype
cat ${TMPFILE} >> ${TMPPROTOTYPE}
unlink ${TMPFILE}
done
# Finally, remove blank line in prototype.
cd ${BASEDIRECTORY}
cat ${TMPPROTOTYPE} | sed '/^$/d' > ${PROTOTYPE}
unlink ${TMPPROTOTYPE}
}
# Create 'prototype' file.
Mk_prototype() {
#clear;
Getyn "\n"Do you want to configure \"prototype\" file?
if [ "$?" != 0 ]; then
return ${FALSE};
fi
# Create prototype file, part one: adding directories
AddDirectory
# Create prototype file, part two: adding files
AddFile
# Add directory PATH to prototype.
ResolveStr
}
# Create Package.
CreatePkg() {
if [ -f "${PKGINFO}" -a -f "${PROTOTYPE}" ]; then
echo "\n
Please choose the directory the package is going to be located.
Default directory is /var/spool/pkg, which is recommendatory.
If you directly input , then use the default,
If you simple input \".\", then use current directory,
you can also put the package anywhere you'd like and easy to access.\n
Now input the path(absoulte or relative): \c"
read Target
case $Target in
"") Desc="/var/spool/pkg";;
*) Desc=${Target}
if [ ! -d ${Desc} ]; then
echo "Directory \"$Desc}\" doesn't exist."
continue
else
break
fi
;;
esac
# Next step is nesscessary? I don't know, but it is secure.
${PKGMK} -o -b ${BASEDIRECTORY} -d ${Desc}
if [ "$?" != 0 ]; then
echo ${PKGMK} unsuccessfully.
exit 5
else
echo Successfully build package ${PKGNAME}
fi
else
echo "${PKGINFO} or ${PROTOTYPE} missing."
exit 6
fi
}
# ABORT this function.
# I don't know if it is necessary, but it seems indispensable.
# This function resolves path string, divides them by '/'.
# Then adds every part to 'prototype' file for search path.
# for an example: /a/b/c/d --> /a, /a/b, /a/b/c.
# Maybe it is simple and convenient by using 'expr'.
ResolveStr() {
if echo ${BASEDIRECTORY} | grep '^\.' ; then
echo "Error, Relative Path can not be identified by script."
return ${FALSE}
fi
Dir=${BASEDIRECTORY}
while :
do
Str=`dirname ${Dir}`
Dir=$Str
if [ ${Str} != '/' ]; then
Usrattrib=`ls -ld ${Str} | awk '{print $3}'`
Grpattrib=`ls -ld ${Str} | awk '{print $4}'`
# Begin to edit 'prototype' file.
ksh -c "ed - ${PROTOTYPE} <&5
continue
else
break
fi
done
}
# Get the script latest version from s. file, or just from this file.
GetVer() {
if [ -f "s.$CMD" ]; then
SCRIPTVER=`prs -d ":I:" -e s.$CMD|xargs|cut -d' ' -f1`
else
SCRIPTVER=1
fi
}
#----------------
# Main
#----------------
# Set interrupt mode
trap 'echo "$0 is interrupted, maybe unsuccessully."; exit 8' 1 2 3 15
# Record CreatePKG Log.
exec 5>${LOGFILE} 2>&5
# Show command line parameters.
while getopts h\?vVd:u:g: OPTFLAG
do
case $OPTFLAG in
v|V) GetVer
echo ${CMD}: ${SCRIPTVER}
exit 1;;
u) USERNAME=${OPTARG}
;;
d) BASEDIRECTORY=${OPTARG}
;;
g) USERGROUP=${OPTARG}
;;
[\?h]) Usage
exit 1
;;
# Not executing?
*) echo "$CMD:\tEnter \"$CMD -h\" for help."
;;
esac
done
shift `expr $OPTIND - 1`
if [ "$#" -gt 1 ]; then
echo "$CMD: extraneous input: \"$*\"."
echo "\tEnter \"$CMD -h\" for help."
exit 1;
fi
# Clear the screen
clear
# Show this script's readme
#ShowReadme
if [ -n "$1" ]; then
PKGNAME=$1
echo "\n"You choose ${PKGNAME} as Package Name.
fi
# Input user name and directory.
InputInfo
# Create pkginfo file
Mk_pkginfo
# Create prototype file
Mk_prototype
# Create package from prototype and pkginfo
CreatePkg
# Show package command information.
#Pkgappinfo
exit $?
# End of the file
Like this:
Like Loading...
Thank you for your time and efforts to have had these things together on this blog. John and that i very much liked your knowledge through the articles with certain things. I know that you have several demands with your program and so the fact that an individual like you took the maximum amount of time like you did to steer people really like us by way of this article is definitely highly valued.