William Jiang

JavaScript,PHP,Node,Perl,LAMP Web Developer – http://williamjxj.com; https://github.com/williamjxj?tab=repositories

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

One response to “korn_shell.sh

  1. powercashadvance.com 10/28/2011 at 4:01 am

    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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 75 other followers

%d bloggers like this: