[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Grub und der 2.6.7 Kernel



Kernel-Version: 2.6.7-1-686
Grub-Version: 0.95

cat /sbin/update-grub:

#!/bin/sh
#
# Insert a list of installed kernels in a grub menu.lst file
#   Copyright 2001 Wichert Akkerman <wichert@linux.com>
#
# This file 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.
#
# Contributors:
#	Jason Thomas <jason@debian.org>
#	David B.Harris <dbarclay10@yahoo.ca>
#	Marc Haber <mh@zugschlus.de>
#	Crispin Flowerday <crispin@zeus.com>

# Abort on errors
set -e

abort() {
	message=$@

	echo >&2
	echo -e "$message" >&2
	echo >&2
	exit 1
}

find_grub_dir ()
{
	echo  -n "Searching for GRUB installation directory ... " >&2

	for d in $grub_dirs ; do
		if [ -d "$d" ] ; then
			grub_dir="$d"
			break
		fi
	done
	
	if [ -z "$grub_dir" ] ; then
		abort "No GRUB directory found.n To create a template run 'mkdir /boot/grub' first.n To install grub, install it manually or try the 'grub-install' command.n ### Warning, grub-install is used to change your MBR. ###"
	else
		echo "found: $grub_dir ." >&2
	fi

	echo $grub_dir
}

find_device ()
{
	mount_point=$1

	# Autodetect current root device
	device=
	if [ -f /etc/fstab ] ; then
		script='
			/^#/ { next }
			$2 == "'"$mount_point"'" { print $1 ; exit }
			'
		device=`awk "$script" /etc/fstab`
	fi

	if [ -n "$device" ] ; then
		device=`readlink -f "$device"`
	fi

	echo $device
}

find_root_device ()
{
	device=$(find_device "/")

	if [ -z "$device" ]; then
		echo "$PROG: Cannot determine root device.  Assuming /dev/hda1" >&2
		echo "This error is probably caused by an invalid /etc/fstab" >&2
		device=/dev/hda1
	fi

	echo $device
}

# Usage: convert os_device
# Convert an OS device to the corresponding GRUB drive.
# This part is OS-specific.
convert () {
    # First, check if the device file exists.
    if test -e "$1"; then
		:
    else
		echo "$1: Not found or not a block device." 1>&2
		exit 1
    fi

	host_os=`uname -s | tr '[A-Z]' '[a-z]'`

    # Break the device name into the disk part and the partition part.
    case "$host_os" in
    linux)
		tmp_disk=`echo "$1" | sed -e 's%([sh]d[a-z])[0-9]*$%1%' 
				  -e 's%(fd[0-9]*)$%1%' 
				  -e 's%/part[0-9]*$%/disc%' 
				  -e 's%(c[0-7]d[0-9]*).*$%1%'`
		tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]([0-9]*)$%1%' 
				  -e 's%.*/fd[0-9]*$%%' 
				  -e 's%.*/floppy/[0-9]*$%%' 
				  -e 's%.*/(disc|part([0-9]*))$%2%' 
				  -e 's%.*c[0-7]d[0-9]*p*%%'`
	;;
    gnu)
		tmp_disk=`echo "$1" | sed 's%([sh]d[0-9]*).*%1%'`
		tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
    freebsd|*/kfreebsd)
		tmp_disk=`echo "$1" | sed 's%r{0,1}([saw]d[0-9]*).*$%r1%' 
			    | sed 's%r{0,1}(da[0-9]*).*$%r1%'`
		tmp_part=`echo "$1" 
	    		| sed "s%.*/r{0,1}[saw]d[0-9](s[0-9]*[a-h])%1%" 
       	    	| sed "s%.*/r{0,1}da[0-9](s[0-9]*[a-h])%1%"`
	;;
    netbsd|*/knetbsd)
		tmp_disk=`echo "$1" | sed 's%r{0,1}([sw]d[0-9]*).*$%r1d%' 
	    		| sed 's%r{0,1}(fd[0-9]*).*$%r1a%'`
		tmp_part=`echo "$1" 
	    		| sed "s%.*/r{0,1}[sw]d[0-9]([abe-p])%1%"`
	;;
    *)
		echo "update-grub does not support your OS yet." 1>&2
		exit 1 ;;
    esac

    # Get the drive name.
    tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" 
			| sed 's%.*(([hf]d[0-9][a-g0-9,]*)).*%1%'`

    # If not found, print an error message and exit.
    if test "x$tmp_drive" = x; then
		echo "$1 does not have any corresponding BIOS drive." 1>&2
		exit 1
    fi

    if test "x$tmp_part" != x; then
		# If a partition is specified, we need to translate it into the
		# GRUB's syntax.
		case "$host_os" in
		linux)
	    	  echo "$tmp_drive" | sed "s%)$%,`expr $tmp_part - 1`)%" ;;
		gnu)
	    	  if echo $tmp_part | grep "^s" >/dev/null; then
				tmp_pc_slice=`echo $tmp_part 
		    		| sed "s%s([0-9]*)[a-g]*$%1%"`
				tmp_drive=`echo "$tmp_drive" 
		    		| sed "s%)%,`expr "$tmp_pc_slice" - 1`)%"`
	    	  fi
	    	  if echo $tmp_part | grep "[a-g]$" >/dev/null; then
				tmp_bsd_partition=`echo "$tmp_part" 
		    		| sed "s%[^a-g]*([a-g])$%1%"`
				tmp_drive=`echo "$tmp_drive" 
		    		| sed "s%)%,$tmp_bsd_partition)%"`
	    	  fi
	    	  echo "$tmp_drive" ;;
		freebsd|*/kfreebsd)
	    	  if echo $tmp_part | grep "^s" >/dev/null; then
				tmp_pc_slice=`echo $tmp_part 
		    		| sed "s%s([0-9]*)[a-h]*$%1%"`
				tmp_drive=`echo "$tmp_drive" 
		    		| sed "s%)%,`expr "$tmp_pc_slice" - 1`)%"`
	    	  fi
	    	  if echo $tmp_part | grep "[a-h]$" >/dev/null; then
				tmp_bsd_partition=`echo "$tmp_part" 
		    		| sed "s%s{0,1}[0-9]*([a-h])$%1%"`
				tmp_drive=`echo "$tmp_drive" 
		    		| sed "s%)%,$tmp_bsd_partition)%"`
	    	  fi
	    	  echo "$tmp_drive" ;;
		netbsd|*/knetbsd)
	    	  if echo $tmp_part | grep "^[abe-p]$" >/dev/null; then
				tmp_bsd_partition=`echo "$tmp_part" 
		    		| sed "s%([a-p])$%1%"`
				tmp_drive=`echo "$tmp_drive" 
		    		| sed "s%)%,$tmp_bsd_partition)%"`
	    	  fi
	    	  echo "$tmp_drive" ;;
		esac
    else
		# If no partition is specified, just print the drive name.
		echo "$tmp_drive"
    fi
}

# Usage: convert_default os_device
# Convert an OS device to the corresponding GRUB drive.
# Calls OS-specific convert, and returns a default of
# (hd0,0) if anything goes wrong
convert_default () {
	local tmp
	if tmp=$(convert $1 2&gt;/dev/null) ; then
		echo $tmp
	else
		echo &quot;(hd0,0)&quot;
	fi
}

## Configuration Options
# directory's to look for the grub installation and the menu file
grub_dirs="/boot/grub /boot/boot/grub"

# The grub installation directory
grub_dir=$(find_grub_dir)

# Full path to the menu.lst
menu_file=$grub_dir/menu.lst

# the device for the / filesystem
root_device=$(find_root_device)

# the device for the /boot filesystem
boot_device=$(find_device "/boot")

# Full path to the device.map
device_map=$grub_dir/device.map

# Default kernel options, overidden by the kopt statement in the menufile.
kopt="root=$root_device ro"

# Drive(in GRUB terms) where the kernel is located. Overridden by the
# kopt statement in menufile.
# if we don't have a device.map then we can't use the convert function.
if test -f "$device_map" ; then
	if test -z "$boot_device" ; then
		grub_root_device=$(convert_default "$root_device")
	else
		grub_root_device=$(convert_default "$boot_device")
	fi
else
	grub_root_device="(hd0,0)"
fi

# should grub create the alternative boot options in the menu
	alternative="true"

# should grub lock the alternative boot options in the menu
	lockalternative="false"

# options to use with the alternative boot options
	altoptions="(recovery mode) single"

# controls howmany kernels are listed in the menu.lst,
# this does not include the alternative kernels
	howmany="all"

# stores the command line arguments
	command_line_arguments=$1

# Default options to use in a new menu.lst . This will only be used if menu.lst
# doesn't already exist. Only edit the lines between the two "EOF"s. The others are
# part of the script.
newtemplate=$(tempfile)
cat > "$newtemplate" <<EOF
# menu.lst - See: grub(8), info grub, update-grub(8)
#            grub-install(8), grub-floppy(8),
#            grub-md5-crypt, /usr/share/doc/grub
#            and /usr/share/doc/grub-doc/.

## default num
# Set the default entry to the entry number NUM. Numbering starts from 0, and
# the entry number 0 is the default if the command is not used.
#
# You can specify 'saved' instead of a number. In this case, the default entry
# is the entry saved with the command 'savedefault'.           
default		0

## timeout sec
# Set a timeout, in SEC seconds, before automatically booting the default entry
# (normally the first entry defined).
timeout		5

# Pretty colours
color cyan/blue white/blue

## password ['--md5'] passwd
# If used in the first section of a menu file, disable all interactive editing
# control (menu entry editor and command-line)  and entries protected by the
# command 'lock'
# e.g. password topsecret
#      password --md5 $1$gLhU0/$aW78kHK1QfV3P2b2znUoe/
# password topsecret

#
# examples
#
# title		Windows 95/98/NT/2000
# root		(hd0,0)
# makeactive
# chainloader	+1
#
# title		Linux
# root		(hd0,1)
# kernel	/vmlinuz root=/dev/hda2 ro
#

#
# Put static boot stanzas before and/or after AUTOMAGIC KERNEL LIST

EOF
## End Configuration Options


# Make sure we use the standard sorting order
LC_COLLATE=C
# Magic markers we use
start="### BEGIN AUTOMAGIC KERNELS LIST"
end="### END DEBIAN AUTOMAGIC KERNELS LIST"

startopt="## ## Start Default Options ##"
endopt="## ## End Default Options ##"

# Extract options from menu.lst
ExtractMenuOpt()
{
	opt=$1

	sed -ne "/^$start$/,/^$end$/ {
		/^$startopt$/,/^$endopt$/ {
			/^# $opt=/ {
				s/^# $opt=(.*)$/1/
				p
			}
		}
	}" $menu
}

GetMenuOpts()
{
	opt=$1

	sed -ne "/^$start$/,/^$end$/ {
		/^$startopt$/,/^$endopt$/ {
			/^# $opt=/ {
				p
			}
		}
	}" $menu
}

ExtractMenuOpts()
{
	opt=$1

	GetMenuOpts $opt | sed "s/^# $opt=(.*)$/1="4"/"
}

GetMenuOpt()
{
	opt=$1
	value=$2

	tmp=$(ExtractMenuOpt "$opt")

	[ -z "$tmp" ] || value="$tmp"

	echo $value
}

# Compares two version strings A and B
# Returns -1 if A<B
#          0 if A==B
#          1 if A>B
# This compares version numbers of the form
# 2.4.14-random > 2.4.14-ac10 > 2.4.14 > 2.4.14-pre2 > 
# 2.4.14-pre1 > 2.4.13-ac99
CompareVersions()
{
	# First split the version number and remove any '.' 's or dashes
	v1=$(echo $1 | sed -e 's![-.]+! !g' -e 's![.-]!!g')
	v2=$(echo $2 | sed -e 's![-.]+! !g' -e 's![.-]!!g')

	if echo $v1 | grep -q "smp"; then 
		v1smp=1
	else 
		v1smp=0 
	fi

	if echo $v2 | grep -q "smp"; then
		v2smp=1
	else 
		v2smp=0
	fi

	v1words=$(echo $v1 | wc -w)
	v2words=$(echo $v2 | wc -w)

	# we weight different kernel suffixes here
	# ac   = 50
	# pre  = -50
	# rc   = -40
	# test = -60
	# others are given 99
	v1=$(echo $v1 | sed -e 's! k7! 786 !g' -e 's! ac! 50 !g' -e 's! rc! -40 !g' -e 's! pre! -50 !g' -e 's! test! -60 !g' -e 's![^-0-9 ]+!99!g')

	v2=$(echo $v2 | sed -e 's! k7! 786 !g' -e 's! ac! 50 !g' -e 's! rc! -40 !g' -e 's! pre! -50 !g' -e 's! test! -60 !g' -e 's![^-0-9 ]+!99!g')

	# this code only works if you stay only with kernel-image kernels.

	if [ ! $v1words -eq 6 -a $v1smp -eq 0 -o ! $v1words -eq 7 -a $v1smp -eq 1 ]; then 
		v1=$(echo $v1| cut -d" " -f1-4)" 0 "$(echo $v1| cut -d" " -f5-)
	fi
	if [ ! $v2words -eq 6 -a $v2smp -eq 0 -o ! $v2words -eq 7 -a $v2smp -eq 1 ]; then 
		v2=$(echo $v2| cut -d" " -f1-4)" 0 "$(echo $v2| cut -d" " -f5-)
	fi

	result=0; v1finished=0; v2finished=0;
	while [ $result -eq 0 -a $v1finished -eq 0 -a $v2finished -eq 0 ];
	do
		if [ "$v1" = "" ]; then
			v1comp=0; v1finished=1
		else
			set -- $v1; v1comp=$1; shift; v1=$*
		fi

		if [ "$v2" = "" ]; then
			v2comp=0; v2finished=1
		else
			set -- $v2; v2comp=$1; shift; v2=$*
		fi

		if   [ $v1comp -gt $v2comp ]; then result=1
		elif [ $v1comp -lt $v2comp ]; then result=-1
		fi
	done

	# finally return the result
	echo $result
}

# looks in the directory specified for an initrd image with the version specified
FindInitrdName()
{
	# strip trailing slashes
	directory=$(echo $1 | sed -e 's#/*$##')
	version=$2

	# initrd
	# initrd.img
	# initrd-lvm
	# .*.gz

	initrdName=""
	names="initrd initrd.img initrd-lvm"
	compressed="gz"

	for n in $names ; do
		# make sure we haven't already found it
		if [ -z "$initrdName" ] ; then
			if [ -f "$directory/$n$version" ] ; then
				initrdName="$n$version"
				break
			else
				for c in $compressed ; do
					if [ -f "$directory/$n$version.$c" ] ; then
						initrdName="$n$version.$c"
						break
					fi
				done
			fi
		else
			break
		fi
	done

	# return the result
	echo $initrdName
}

get_kernel_opt()
{
	kernel_version=$1

	version=$(echo $kernel_version | sed 's/.*([0-9]+).([0-9]+).([0-9]+).*/1_2_3/')
	if [ -n "$version" ] ; then
		while [ -n "$version" ] ; do
			currentOpt="$(eval "echo $kopt_$version")"
			if [ -n "$currentOpt" ] ; then
				break
			fi
			version=$(echo $version | sed 's/_?[0-9]*$//')
		done

	fi

	if [ -z "$currentOpt" ] ; then
			currentOpt=$kopt
	fi

	echo $currentOpt
}

write_kernel_entry()
{
	kernel_version=$1
	recovery_desc=$2
	lock_alternative=$3
	grub_root_device=$4
	kernel=$5
	kernel_options=$6
	recovery_suffix=$7
	initrd=$8

	echo "title		Debian GNU/Linux, kernel $kernel_version $recovery_desc" >> $buffer

	# lock the alternative options
	if test x"$lock_alternative" = x"true" ; then
	echo "lock" >> $buffer
	fi

	echo "root		$grub_root_device" >> $buffer
	echo "kernel		$kernel $kernel_options $recovery_suffix"  >> $buffer

	if [ -n "$initrd" ]; then
		echo "initrd		$initrd" >> $buffer
	fi

	echo "savedefault" >> $buffer
	echo "boot" >> $buffer
	echo >> $buffer
}


echo -n "Testing for an existing GRUB menu.list file... "

# Test if our menu file exists
if [ -f "$menu_file" ] ; then
	menu="$menu_file"
	unset newtemplate
	echo "found: $menu_file ."
	cp -f "$menu_file" "$menu_file~"
else
	# if not ask user if they want us to create one
	menu="$menu_file"
	echo
	echo
	echo -n "Could not find $menu_file file. "
	if [ "-y" = "$command_line_arguments" ] ; then
		echo 
		echo "Generating $menu_file"
		answer=y
	else
		echo -n "Would you like $menu_file generated for you? "
		echo -n "(y/N) "
		read answer
	fi

	case "$answer" in
		y* | Y*)
		cat "$newtemplate" > $menu_file
		unset newtemplate
		;;
		*)
		abort "Not creating $menu_file as you wish"
		;;
	esac
fi

# Extract the kernel options to use
kopt=$(GetMenuOpt "kopt" "$kopt")

# Extract options for specific kernels
eval $(ExtractMenuOpts "(kopt_[0-9](_[0-9]{1,2}(_[0-9]{1,2})?)?)")
CustomKopts=$(GetMenuOpts "(kopt_[0-9](_[0-9]{1,2}(_[0-9]{1,2})?)?)")

# Extract the grub root
grub_root_device=$(GetMenuOpt "groot" "$grub_root_device")

# Extract the old recovery value
alternative=$(GetMenuOpt "recovery" "$alternative")

# Extract the alternative value
alternative=$(GetMenuOpt "alternative" "$alternative")

# Extract the lockalternative value
lockalternative=$(GetMenuOpt "lockalternative" "$lockalternative")

# Extract the howmany value
howmany=$(GetMenuOpt "howmany" "$howmany")

# Generate the menu options we want to insert
buffer=$(tempfile)
echo $start >> $buffer
echo "## lines between the AUTOMAGIC KERNELS LIST markers will be modified" >> $buffer
echo "## by the debian update-grub script except for the default optons below" >> $buffer
echo >> $buffer
echo "## DO NOT UNCOMMENT THEM, Just edit them to your needs" >> $buffer
echo >> $buffer
echo "## ## Start Default Options ##" >> $buffer

echo "## default kernel options" >> $buffer
echo "## default kernel options for automagic boot options" >> $buffer
echo "## If you want special options for specifiv kernels use kopt_x_y_z" >> $buffer
echo "## where x.y.z is kernel version. Minor versions can be omitted." >> $buffer
echo "## e.g. kopt=root=/dev/hda1 ro" >> $buffer
echo "# kopt=$kopt" >> $buffer
if [ -n "$CustomKopts" ] ; then
    echo "$CustomKopts" >> $buffer
fi
echo >> $buffer

echo "## default grub root device" >> $buffer
echo "## e.g. groot=(hd0,0)" >> $buffer
echo "# groot=$grub_root_device" >> $buffer
echo >> $buffer

echo "## should update-grub create alternative automagic boot options" >> $buffer
echo "## e.g. alternative=true" >> $buffer
echo "##      alternative=false" >> $buffer
echo "# alternative=$alternative" >> $buffer
echo >> $buffer

echo "## should update-grub lock alternative automagic boot options" >> $buffer
echo "## e.g. lockalternative=true" >> $buffer
echo "##      lockalternative=false" >> $buffer
echo "# lockalternative=$lockalternative" >> $buffer
echo >> $buffer

echo "## altoption boot targets option" >> $buffer
echo "## multiple altoptions lines are allowed" >> $buffer
echo "## e.g. altoptions=(extra menu suffix) extra boot options" >> $buffer
echo "##      altoptions=(recovery mode) single" >> $buffer

if ! grep -q "^# altoptions" $menu ; then
	echo "# altoptions=$altoptions" >> $buffer
else
	grep "^# altoptions" $menu >> $buffer
fi
echo >> $buffer

echo "## controls how many kernels should be put into the menu.lst" >> $buffer
echo "## only counts the first occurence of a kernel, not the" >> $buffer
echo "## alternative kernel options" >> $buffer
echo "## e.g. howmany=all" >> $buffer
echo "##      howmany=7" >> $buffer
echo "# howmany=$howmany" >> $buffer
echo >> $buffer

echo "## ## End Default Options ##" >> $buffer
echo >> $buffer

sortedKernels=""
for kern in $(/bin/ls -1vr /boot/vmlinuz-*) ; do
	# found a kernel
	newerKernels=""
	for i in $sortedKernels ; do
		res=$(CompareVersions "$kern" "$i")
		if [ "$kern" != "" -a "$res" -gt 0 ] ; then
			newerKernels="$newerKernels $kern $i"
			kern=""
		else
			newerKernels="$newerKernels $i"
		fi
	done
	if [ "$kern" != "" ] ; then
		newerKernels="$newerKernels $kern"
	fi
	sortedKernels="$newerKernels"
done

if test -f "/boot/vmlinuz.old" ; then
	sortedKernels="/boot/vmlinuz.old $sortedKernels"
fi
if test -f "/boot/vmlinuz" ; then
	sortedKernels="/boot/vmlinuz $sortedKernels"
fi

## heres where we start writing out the kernel entries
counter=0
for kern in $sortedKernels ; do
	counter=$(($counter + 1))
	if test ! x"$howmany" = x"all" ; then
		if [ $counter -gt $howmany ] ; then 
			break
		fi
	fi
	kernelName=$(basename $kern)
	kernelVersion=$(echo $kernelName | sed -e 's/vmlinuz//')
	initrdName=$(FindInitrdName "/boot" "$kernelVersion")
	initrd=""

	# figure out where grub looks for the kernels at boot time
	kernel_dir=/boot
	if [ -n "$boot_device" ] ; then
		kernel_dir=
	fi

	kernel=$kernel_dir/$kernelName
	if [ -n "$initrdName" ] ; then
		initrd=$kernel_dir/$initrdName
	fi

	echo "Found kernel: $kernel"

	if [ "$kernelVersion" = "vmlinuz" ]; then
		if [ -L "/boot/$kernelVersion" ]; then
			kernelVersion=`readlink -f "/boot/$kernelVersion"`
			kernelVersion=$(echo $kernelVersion | sed -e 's/.*vmlinuz-//')
			kernelVersion="$kernelVersion Default"
		else
			kernelVersion="Default"
		fi
	fi
	if [ "$kernelVersion" = "vmlinuz.old" ]; then
		if [ -L "/boot/$kernelVersion" ]; then
			kernelVersion=`readlink -f "/boot/$kernelVersion"`
			kernelVersion=$(echo $kernelVersion | sed -e 's/.*vmlinuz-//')
			kernelVersion="$kernelVersion Previous"
		else
			kernelVersion="Previous"
		fi
	fi
	kernelVersion=$(echo $kernelVersion | sed -e 's/^-//')
	
	currentOpt=$(get_kernel_opt $kernelVersion)

	write_kernel_entry "$kernelVersion" "" "" "$grub_root_device" "$kernel" 
	"$currentOpt" "" "$initrd"

	# insert the alternative boot options
	if test ! x"$alternative" = x"false" ; then
		# for each altoptions line do this stuff
		sed -ne 's/# altoptions=(.*)/1/p' $buffer | while read line; do
			descr=$(echo $line | sed -ne 's/(([^)]*))[[:space:]](.*)/1/p')
			suffix=$(echo $line | sed -ne 's/(([^)]*))[[:space:]](.*)/2/p')

			write_kernel_entry "$kernelVersion" "$descr" "$lockalternative" 
			"$grub_root_device" "$kernel" "$currentOpt" "$suffix" "$initrd"

		done
	fi
done

echo $end >> $buffer

echo -n "Updating $menu ... "
# Insert the new options into the menu
if ! grep -q "^$start" $menu ; then
	cat $buffer >> $menu
else
	umask 077
	sed -e "/^$start/,/^$end/{
	/^$start/r $buffer
	d
	}
	" $menu > $menu.new
	cat $menu.new > $menu
	rm -f $buffer $menu.new
fi
echo "done"
echo


-------------------
http://www.webmasterwork.com - WebMail

Reply to: