aboutsummaryrefslogblamecommitdiffstats
path: root/scripts/pkg
blob: d65a14b262f384f4edbafd7c8808cb1c16360d7c (plain) (tree)
1
2
3
4
5
6
7
8
9
           
 
                                                             
 
                                                      



                                                                              







                                                                                
                           







                                                                
                                               




                               
                                                                   
































                                                                                
 

                    
          
 






















                                                                                                                                                                                                                                                                                                                     






                                                                               

 




                                                                                    

 






                                                                              

 




                                                                                   

 



































































                                                                               

 



























































                                                                             
                                                                   








                                                              
                                               























                                                                     
                                                          










                                                                            
                                                       



                                                                          

                                               
                  

                                               

                                       









                                                                          
                  
                                                          











                                                         




                                                                                  
                   






                                                                                    
            

 






























































































































                                                                                                                   

 



                                                   

 























                                                                                                       


                                                                           

                             

                                          
          


                               





































                                                                                                     


                                                                      
                                                                     

                                                                                     














































































                                                                                                                                                    
                                                                                                

                                                                                           

                                  











                                                                                                                   
                  






                                                    


                 
                

 






                                              

















                                                                                    

















                                                                                




















                                                                                           
                                        










                                                                        



                                                                      

            
 


                                          
             
 
                                   


                                         
                       
                          
                      
                           
                                                                                                                                           
            


            
 




















                                                                        






                                                                                





                                             

 

                                                  
                     

                         
 
                                                    
 

                                              
        
 






                                                                                
        
 





















                                                                                
                                                                                    

              
                                                                                                                                                                        
                                                                                                
                                                                                                                                                                                     




                                                                                     


                                                                            

                

 
                                                         
                                                      
                          




                                                                                                                 

                                                                                              







                                               
              


                         

 

                                                                              
                                                                                  
                                            


                             
 
                                      
                                        
                




                                              
                    
                                                                       


                                     
                                                                                                  









                                                 
                                                                    









                                                                                                             
                                                                     
                          
                                                                  

                                                                                                                                             
                                                             























                                                                                                                                             





                                                             






                                                                
                                                               

                         
                        
 







                                                             
                               



                                                                             
               
 





                                      


                                                           

                                     
                                                         


                                      
                                     
                




                                              

                                                     
                    





















                                                                       
 
                   
                                                                    























                                                 
                                                                    









                                                                                                             
                                                                     
                          
                                                                  

                                                                                                                                             
                                                             








                                                                                                                                             
                                                                                         


                                            









                                                                                       

                

 














                                                                                                      
































                                                                                






















































































                                                                                                                                                  
                                                                                    





                                                       
                


                                                           



                                                      
                                              
                                                                                                             
                                         





                                                                     
                                                                   




                                        

                                                                     










                                                                                     









                                                                                  




                                                              
 



                  

 












                                                                        
                     

                  


                                                                






















































                                                                                    
            

 


                                                  
 



                                                                                
            

 








                                   
         









































                                                                   
                                                     

                        
             













                                                                                 
                                       







                                                                 
                                                      

                         
                                                      

                                                                 







                                                                 





                                                                 
                                                      



                         

                                                                              







                                                 





                                                          





                                              
                                                



                                                                                      

      
                        
 

                                      

      



                                                                        











                                                                  
                                                                              



                                                           

                                                             
















































































                                                                                                               
                

















                                                                                                   







                                                                           
          

 
 
 
 
 
 































                                                                                                             

  






                                                                                       

  























                                                                                                     

      





















































































































                                                                                                       
 














































                                                                                                                                                             
          
 






                                                                                
 



                                           
 















                                                              
 









                                                     

    
                                       
                                                 
                                           

                                
          
 
                                                                   
 






                                                               
  
 
#!/bin/bash

# pkg - Formilux package builder - version 0.5.0 - 2005-03-01
#
# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
#       mailto: benoit@ant-computing.com,willy@ant-computing.com
#
# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )

## WARNING ##
# This version is not compatible with pkg scripts written for pre-0.2.0 versions


# Usage:
#   pkg <action> [ pkg [ pkg2 ] ]
#
#   pkg newpkg [ new_pkg [ old_pkg ] ]
#       [new_pkg]=[old_pkg]
#     ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
#         pkg newpkg apache apache-1.3
#         pkg newpkg bash
#         pkg newpkg gcc gcc-3*flx*.1
#
#   pkg setpkg [ new_pkg ]
#     ex: pkg setpkg openssl-0.9.6g-flx0.1
#
#   pkg { info | cat | edit | unpack } [ pkg ] 
#     ex: pkg info
#         pkg info bash
#         pkg edit modutils-2.4
#         pkg cat gzip-1.3
#
#   pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
#
#   pkg { patch | unpatch } [ patch_name ]
#
#   pkg { any_command } [ any_args ]
#

# don't return stupid names, and we also want dotfiles and use extended globbing
shopt -s nullglob
shopt -s dotglob
shopt -s extglob

# disable pathnames expansion
set -o noglob

# change the default mask to avoid common security problems
umask og-w

# set some constants
KERNDIR=${KERNDIR:-/usr/src/linux}
FLXARCH=${FLXARCH:-$(uname -m)}
DEVROOT=${DEVROOT:-/var/flx-dev}
PKGROOT=${PKGROOT:-/var/flx-pkg}
# use -p1 by default to apply a patch
PATCH_LEVEL=${PATCH_LEVEL:-1}
# the suffix that we use to name different builds. It also matches build
# versions with this name followed by a number (BUILDVER)
BUILDSFX=${BUILDSFX:-flx}
BUILDVER=${BUILDVER:-0}

PKGSUFF="tgz"
CFGSUFF="cfg"
INSTNAME=".flxdisk"
LINKNAME=".flxpkg"

FIND_CMD=pkgfilefind

FILE_LIST=

# all the directories that should be ignored by do_pack
EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )

###### 
###### here are some undertermined type functions
######

# find packageable files (that can't be automaticaly created) and return only
# their relative path to the argument.

function pkgfilefind {
    local start=${1%%/}
    local dir
    local -a exclude_args=( )

    for dir in "${EXCLUDE_LIST[@]}"; do
        exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
    done

   find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
}


######
###### here are some functions for manipulating package names
######

# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
function get_pkg_radix {
    echo ${1%%[-_][0-9]*}
}

# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
function get_pkg_ver {
    local ver=${1#${1%%[_-][0-9]*}[._-]} 
    ver=${ver%-${BUILDSFX}*}
    [ "$ver" = "$1" ] || echo $ver
}

# returns the build number from a package name when appropriate, or empty when
# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
function get_build_num {
    local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}}	# -flx0.12-pkg
    build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}}	# -flx0.12
    build=${build#-}					# flx0.12
    [ "$build" != "$1" ] && echo $build
}

# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
function get_next_build {
    local prefix=${1%%.*}
    local suffix=${1##*.}
    echo $prefix.$[$suffix + 1]
}

# This function accepts a list of versionned names, and returns them sorted by
# version number. The names must NOT contain any '|' or '~' character, or they
# will be discarded. Names that don't have any version are also discarded.
function sortnames {
    local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
    local base version rest filename i t file flist
    local -a list

    # a numeric versions consists in a series of numbers delimited by dots, and
    # optionnally ending with one or several dots, so that strange namings are
    # correctly processed. An alphanumeric version consists in everything that
    # cannot match a numeric version, optionnaly ending with one or more dots.
    IFS=$'\n'
    FIELD='\([^|]*\)'
    NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
    ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
    VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"

    # make the list appear in the form 'package|version|rest|full_name'
    list=($(echo "$*" | grep -v "|~" | sed -e "s/$VERSION/\1|/" \
		    -e "s/^$FIELD|$VERSION/\1|\2|/" \
		    -e "s/^$FIELD|$FIELD|$FIELD$/\1|\2|\3~\1\2\3/" \
		    -e "s/^[^|]*|[^|]*$//"))

    # there's a risk that it doesn't complete for all the list, and that some
    # elements keep a "rest". But what can we do about it ?

    # we loop on the list if there's at least one element
    # this will build alternating series of numeric-only and non-numeric
    # substrings, packed by six.
    while [ "${list[0]}" ] ; do
	# now we add sub-version delimiters ','
	list=( $(for file in ${list[*]} ; do
           IFS="|~" ; set -- $file
	    base=$1 ; version=$2 ; rest=$3 ; filename=$4
	    if [ -z "$rest" ] ; then
		IFS="." ; set -- $version
		# we append a dot to the version for sed below.
		echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
		continue
	    fi
	    IFS="." ; set -- $version
	    echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
	done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
	IFS=$'\n'
	# and we stop once everyone has "|\.|~" (no rest)
	if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
    done

    # now construct a field separator list for 'sort'. Since it's full of bugs,
    # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
    # To match most cases, we'll assume that most of our packages will be
    # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
    IFS=',' ; i=1 ; flist=
    for t in ${list[0]%%|*} ; do
	if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
	    flist="$flist${flist:+ }-k$i,$i"
	else
	    flist="$flist${flist:+ }-k$i,$i"n
	fi
	i=$[$i+1];
    done

    IFS=$'\n'$'\t'' '
    # Do not use '-u' since sort is stupid enough to remove nearly identical
    # lines !
    #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
    echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
}


######
###### here are some "exported" functions used to ease file manipulation
######

#  
# usage: set_perm uid:gid mode file...
function set_perm {
    local own mode
    [ $# -gt 2 ] || return 1
    own=$1 ; shift
    mode=$1 ; shift
    chown $own "$@"
    chmod $mode "$@"
    return 0
}

#  
# usage: set_default_perm $ROOTDIR/start_dir
function set_default_perm {
    local start_dir=$1
    local strip_dir=${ROOTDIR%%/}
    local type executable script

    if [ -z "$1" ]; then
        echo; echo "### ERROR! set_default_perm called without arguments !!!"
        echo "### You must specify the root directory to fix."
	return 1
    fi

    echo
    echo "PKG : Fixing permissions in $1 ... "
    echo "      Please wait..."
    echo "      Fixing directories..."

    # first pass : check directories
    find $start_dir -type d | while read; do
	case "${REPLY##$strip_dir}" in
	    /|/.)
		set_perm root:root 755 "$REPLY"
		;;
	    /sbin|/sbin/init.d|/usr/sbin)
		set_perm root:adm 751 "$REPLY"
		;;
	    /root)
		set_perm root:root 700 "$REPLY"
		;;
	    /etc/formilux|/var/core)
		set_perm root:adm 750 "$REPLY"
		;;
	    *)
		if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
		    set_perm root:root 755 "$REPLY"
		fi
		;;
	esac
    done

    echo "      Fixing special files..."
    # second pass : check special files (block, char, fifo)
    find $start_dir -not -xtype d -a -not -xtype f | while read; do
	if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
	    set_perm root:root 600 "$REPLY"
	fi
    done

    echo "      Fixing regular files..."
    # third pass : check regular files
    find $start_dir -type f | while read; do
	if [ -u "$REPLY" -o -g "$REPLY" ]; then
	    # remove other r/w on setuid/setgid
	    chmod o-rw "$REPLY"
	else
	    type=$(file -z "$REPLY")
	    executable=0
	    script=0

	    if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
		 -z "${type//*ERROR: Corrupt*/}" ]; then
		executable=1
            elif [ -z "${type//*script*/}" ]; then
		script=1
	    fi

	    #echo "processing ${REPLY##$strip_dir}"
	    case "${REPLY##$strip_dir}" in
	    /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
		if [ $executable -gt 0 ]; then
		    set_perm root:adm ug-w,o-rw "$REPLY"
		elif [ $script -gt 0 ]; then
		    set_perm root:adm ugo-w "$REPLY"
		else
		    set_perm root:adm ugo-w "$REPLY"
		fi
		;;
	    /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
		if [ $executable -gt 0 ]; then
		    set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
		elif [ $script -gt 0 ]; then
		    set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
		else
                    # neither an exec nor a script, no need to execute it !
		    set_perm root:adm ug-swx,o-wx "$REPLY"
		fi
		;;
	    /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
	    /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
		set_perm root:adm ug-sw,o-w,+x "$REPLY"
		;;
	    /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
		set_perm root:adm ugo-swx "$REPLY"
		;;
	    /etc/profile.d/*.var)
		set_perm root:adm 0644 "$REPLY"
		;;
	    /etc/profile.d/*)
		set_perm root:adm 0755 "$REPLY"
		;;
	    /boot/*/*|/boot/*|/etc/*/*)
		set_perm root:adm ug-swx,o-rwx "$REPLY"
		;;
	    /etc/*)
		set_perm root:adm ugo-swx "$REPLY"
		;;
	    /*/man/*)
		set_perm root:man ugo-swx "$REPLY"
		;;
	    /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
		set_perm root:man ugo-swx "$REPLY"
		;;
	    /usr/share/examples/*|/usr/share/examples/*/*)
		set_perm root:man ugo-swx "$REPLY"
		;;
	    *)
		# chgrp adm if not setgid and group==root
		# chmod ugo-w if user==root
		;;
	    esac
	fi
    done
    echo "PKG : done fixing permissions."
}

######
###### here are "exported" functions, which can be used and redefined by build.cfg
######

# builds everything from a clean start
function do_build {
    local ACTION
    # ACTION will be inherited by other functions
    for ACTION in clean compile prepack strip pack ; do
	declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
	declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
	declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
    done
    return 0
}

# this function returns one exact package name from a list of potentially
# interesting ones, classed from higher preference to lower. They are all
# passed as strings, constituting packages names, or some of the following
# special names :
#   %P => use current directory as the source for the name
#   %L => use the package pointed to by the ${LINKNAME} link
#   %D => use the default package
# If several packages match a given pattern, the user is asked to select the
# desired one.
# The result is returned in REPLY.
function get_name {
    local pattern pkg_name
    local radix ver build
    local -a rel_list dev_list sort_list
    local i

    REPLY=
    for pattern in $*; do
	if [ "$pattern" = "%P" ]; then
	    pattern=$(basename $(pwd))
	elif [ "$pattern" = "%L" ]; then
	    if [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
		# the link is always an EXACT name, so we return it as-is.
		pattern=$(readlink ${LINKNAME})
		REPLY=$(basename $pattern)
		return
	    else
		continue
	    fi
	elif [ "$pattern" = "%D" ]; then
	    pattern=default
	fi
	radix=$(get_pkg_radix $pattern)
	ver=$(get_pkg_ver $pattern)
	build=$(get_build_num $pattern)
	pkg_name=${radix:-*}-${ver:-*}-${build:-*}

	REPLY=
	# we loop until pkg_name is empty, which allows recursive choices.
	while [ "$pkg_name" ]; do
	    # now we'll try to build a list of potentially matching packages for
	    # each pattern. We'll reduce the original name until either we have
	    # a non-empty list or the package name is void.
	    rel_list=( ); dev_list=( )
	    while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
		rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
		if [ "$release_only" != "1" ]; then
		    dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
		fi
		
		if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
		    radix=$(get_pkg_radix $pkg_name)
		    ver=$(get_pkg_ver $pkg_name)
		    build=$(get_build_num $pkg_name)
		    
		    if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
			if [ "$build" -a "$build" != "*" ]; then
			    pkg_name=${radix}-${ver}-*
			elif [ "${ver%.*}" != "$ver" ]; then
			    # let's reduce the version precision
			    pkg_name=${radix}-${ver%.*}-*
			else
			    pkg_name=${radix}-*
			fi
		    else
			break
		    fi
		else
		    break
		fi
	    done
	    
	    # we're prepared to break the big loop, unless someone sets pkg_name again.
	    pkg_name=
	    sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
	    
	    # if we matched nothing, we jump to the next pattern, and if we matched
	    # exactly one result, we return it immediately.
	    if [ ${#sort_list[*]} -eq 0 ]; then
		continue
	    elif [ ${#sort_list[*]} -eq 1 ]; then
		REPLY=${sort_list[0]}
		return
	    fi

	    # now, we'll present the possible names to the user.
	    i=0
	    printf " %5d : - None of the following packages -\n" 0
	    while [ $i -lt ${#sort_list[*]} ]; do
		# we'll display an 'R' in front of released names, or a 'D' for dev.
		if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
		    printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
		else
		    printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
		fi
		i=$[$i+1]
	    done
	    echo

	    while : ; do
		echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
		if [ -z "$i" ]; then
		    # empty string, we use the last choice which is the preferred one.
		    i=${#sort_list[*]}
		    REPLY=${sort_list[$[$i-1]]}
		    return
		elif [ "${i//[0-9]/}" ]; then
		    # not a plain integer, we'll allow to recursively re-select
		    #pattern=${pattern}*${i}
		    pattern=${i}
		    radix=$(get_pkg_radix $pattern)
		    ver=$(get_pkg_ver $pattern)
		    build=$(get_build_num $pattern)
		    pkg_name=${radix:-*}-${ver:-*}-${build:-*}
		    break;
		elif [ $i -le 0 ]; then
		    # if the user explicitly replied "0", then he wants other choices.
		    break;
		elif [ $i -le ${#sort_list[*]} ]; then
		    REPLY=${sort_list[$[$i-1]]}
		    return
		fi
	    done
	    # we get here only either if someone tries to refine the package name or
	    # if he refuses these ones.
	done
    done
}

# choose a package and make ${LINKNAME} point to it
function do_setpkg {
    rm -f ${LINKNAME}
    ln -s $PKGDIR ${LINKNAME}
}


# look for existing packages, and propose a new version for the current one
function do_newpkg {
    local -a rel_list dev_list sort_list
    local pkg_name new_name
    local radix ver build

    set -o noglob
    if [ -e ${LINKNAME} ]; then
	if [ -L ${LINKNAME} ]; then
	    if [ -d ${LINKNAME}/. ]; then
		echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
		exit 1
	    else
		rm -f ${LINKNAME}
	    fi
	else
	    echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
	    exit 1
	fi
    fi

    if [ $# -gt 0 ]; then
	# the user has specified an explicit version string
	# either it's the complete name, or it's the complete name followed
	# by an '=' sign preceding the old name.
	new_name=${1%%=*}
	if [ $# -gt 1 ]; then
	    pkg_name=$2
	elif [ "$new_name" != "$1" ]; then
	    pkg_name=${1##*=}
	fi
    fi

    if [ -z "$new_name" ]; then
	# the user has not specified any version string, we'll use the directory
	# name.
	new_name=$(basename $(pwd))
    fi

    rel_list=( ); dev_list=( )

    # now we'll have to guess the new package name.
    # The build rev part (flx*.*) will be ignored.
    # We'll look for existing packages with the exact
    # name+version, and if found, use this + the first unused build number.
    # If not found, a new package is created with the exact name and flx0.1

    radix=$(get_pkg_radix $new_name)
    ver=$(get_pkg_ver $new_name)
    build=$(get_build_num $new_name)
    new_name=${radix:-*}-${ver:-*}

    rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
    dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
    sort_list=(${rel_list[*]} ${dev_list[*]})

    if [ "${sort_list[*]}" ]; then
	sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
	sort_list=( $(sortnames ${sort_list[*]}) )
	if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
	    ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
	    # if the package was properly named, and not already listed, let's
	    # propose it on last position.
	    sort_list=( ${sort_list[*]} $new_name )
	fi
	# echo "package_list : ${sort_list[*]}"

	# now, we'll present the possible names to the user
	if [ ${#sort_list[*]} -gt 1 ]; then
	    local i=0
	    echo; echo ">>> Please select the name of the package to create :";echo
	    while [ $i -lt ${#sort_list[*]} ]; do
		# we'll display an 'R' in front of released names, 'P'
		# in front of packaged ones, or a 'D' for dev.
		if [ -e "$PKGROOT/${sort_list[$i]}/RELEASED" ]; then
		    printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
		elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
		    printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]}
		else
		    printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
		fi
		i=$[$i+1]
	    done

	    echo
	    while : ; do
		echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
		if [ -z "$i" ]; then
		    new_name=${sort_list[${#sort_list[*]}-1]}
		    break
		elif [ "${i//[0-9]/}" ]; then
		    # not a plain integer, we'll take it for the new name
		    new_name=$i
		    break;
		elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
		    new_name=${sort_list[$[$i-1]]}
		    break;
		fi
	    done
	else
	    new_name=${sort_list[0]}
	fi
	# we'll search for all packages starting with the same name and version
	# in both release and dev dirs. Then we'll be able to deduce the latest
	# build number used.
#	sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
	sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%f\n" 2>/dev/null|sort -u) )
	if [ ${#sort_list[*]} -eq 0 ]; then
	    # this can happen with new BUILDSFX/BUILDVER
	    new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
	else
	    sort_list=( $(sortnames ${sort_list[*]} ))
	    new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
	fi
    else
	if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
	    echo "Error: no existing package matches $new_name, and wildcards"
	    echo "or incomplete names cannot be part of a real name."
	    exit 1
	fi
	# we keep new_name since it's syntactically correct
	new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
    fi

    #echo "new_name: $new_name"

    # if pkg_name is unspecified, we'll use the current directory name to guess
    # the source package, else we'll use the explicit name
    echo; echo ">>> Please select the package to use as a reference :"; echo

    get_name $pkg_name $new_name %P %D

    if [ -z "$REPLY" ]; then
	echo "No reference package found (even default). Please specify one."
	exit 1
    fi

    echo "Using '$REPLY'."

    if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
	pkg_name=$PKGROOT/$REPLY
    else
	pkg_name=$DEVROOT/$REPLY
    fi

    # new_name is always relative to DEVROOT
    #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"

    # we should verify that new_name/released doesn't exist before extracting
    # anything into it, or even that new_name doesn't exist at all.
    new_name=$DEVROOT/$new_name
    if [ -e $new_name ]; then
	echo "Error! new directory $new_name already exists. Refusing to overwrite."
	exit 1
    fi

    rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
	tar -C $pkg_name  --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
            --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
            -cplf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
    chmod u+rw $new_name/build.cfg

    echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
    echo "The link '${LINKNAME}' now points to it."
    echo
    if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
	echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
	echo
    fi
    set +o noglob
    return 0
}


function do_edit {
    if [ -e "$PKGDIR/RELEASED" ]; then
	echo "Editing $CFGFILE in read-only mode..."
	vi -R $CFGFILE
    else
	echo "Editing $CFGFILE..."
	vi $CFGFILE
    fi
}

function do_cat {
    cat $CFGFILE
}

function do_lst {
    local FPNAME

    FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
    cat $FPNAME.lst
}

function pre_info {
    echo "Information for package '$EXACTPKG' :"

    echo "   Package version : $PKGVER (\$PKGVER)"
    echo "   Distrib version : $DISTVER (\$DISTVER)"
    echo -n "   Config. file : "
    if [ -e $CFGFILE ]; then
	echo "$CFGFILE"
    else
	echo "none found."
    fi
    echo "   Package file : $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF"
    echo -n "   Package size : "
    if [ -e $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF ]; then
	echo "$(du -b $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF |cut -f1) bytes."
    else
	echo "does not exist yet."
    fi
    if [ -n "${PATCH_LIST}" ]; then
	echo "   Patches list : ${PATCH_LIST}"
    else
	echo "   Empty patch list."
    fi

    if [ -e "$PKGDIR/ChangeLog" ]; then
	echo "   Last ChangeLog  : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
    else
	echo "   No ChangeLog."
    fi

    if [ -e "$PKGDIR/RELEASED" ]; then
	echo "   Tagged as RELEASED"
    else
	echo "   UNRELEASED."
    fi

    return 0
}

# does only compile, not changing the current config
function do_compile_only {
    $FLXMAKE
    return $?
}

# new simplified name for 'config_only', which is deprecated, not changing current scripts.
function do_config {
    if declare -f do_config_only >/dev/null 2>&1; then
	do_config_only
	return $?
    else
	return 0
    fi
}

# configures and compiles
function do_compile {
    ( do_config ) && ( do_compile_only )
}

# preparatory work for prepack()
function pre_prepack {
    if [ "$UID" != "0" -a "$force" != "1" ]; then
	echo "You must specify '--force' to install as non-root"
	exit 1
    fi
    # WARNING! here, we don't use $ROOTDIR because we don't want to risk
    # erasing a wrong directory as root !
    [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
    # permissions are important here because we don't want to get an
    # inherited setgid or something alike on the root dir
    [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
    #mkdir -p "$EXAMPLEDIR"
    return 0
}

# build link in /opt directory
# INPUT: selected path to creation in /opt
function build_opt {
    local dir

    if [ -d $ROOTDIR/opt ] ; then (
        [ $# = 0 ] && set -- bin sbin lib
	set +o noglob 
        shopt -s nullglob
	cd $ROOTDIR/opt
	for dir in $* ; do
	    mkdir $dir
            dirs=( */$dir )
            [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
	done
    ) fi
    return 0
}

# deletes the current prepack directory.
function do_delpack {
    # WARNING! here, we don't use $ROOTDIR because we don't want to risk
    # erasing a wrong directory as root !
    [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
    return 0
}

# does a full clean
function do_clean {
    make distclean || make mrproper || make clean
    ( do_delpack )
    return 0
}

# applies all the patches to the current sources
# files which match *.rej and *~ will be deleted
function do_patch {
    local i
    find . -name '*.rej' -o -name '*~' | xargs rm -f

    for i in ${PATCH_LIST}; do
	[ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
	if [ -z "${i##*.gz}" ]; then
	    gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
	else
	    patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
	fi
    done

    if [ -z "$(find . -name '*.rej')" ]; then
	find . -name '*~' | xargs rm -f
    fi
    return 0
}

# reverts all the patches from the current sources
# files which match *.rej and *~ will be deleted
function do_unpatch {
    local i
    local UNPATCH_LIST=""

    find . -name '*.rej' -o -name '*~' | xargs rm -f

    for i in ${PATCH_LIST}; do
	UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
    done

    for i in ${UNPATCH_LIST[@]}; do
	[ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
	if [ -z "${i##*.gz}" ]; then
	    gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
	else
	    patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
	fi
    done

    if [ -z "$(find . -name '*.rej')" ]; then
	find . -name '*~' | xargs rm -f
    fi
    return 0
}

# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
function do_unpack {
    local FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF
    mkdir -p $ROOTDIR
    cd $ROOTDIR

    echo -n "Extracting $FILE into $ROOTDIR ... "
    tar zUxpf $FILE >/dev/null 2>&1
    echo "done."
    return 0
}

# strips symbols from executables before building the package.
# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
function do_strip {
    if [ ! -d $ROOTDIR ] ; then
	echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
	exit 1
    fi
    #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1 
    # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
    find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1 
    return 0
} 

# forces pack() to strip before starting, even if do_pack() is redefined by the user.
function pre_pack {
    # in the mean time, we avoid removing this directory since it could have
    # been brought legally by an authorized package.
    #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
    ( do_strip )
    return 0
}

# this function finds perl dependencies for a given file.
# It's only called from _do_pack_files() and do_pack()
function get_perl_depend {
    local filename=$1
    local dep DEP
    local DEP_FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.dep

    DEP=$(grep "^\(.*['{\"]\)*[ 	]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9-_]*[; '\"]" $filename | \
                sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
                    -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
                sed 's@::@/@g')
    if [ "x$DEP" != "x" ] ; then
	echo -n "$filename" >> $DEP_FILE
        for dep in $DEP ; do
	    if [ "x${dep/*.*}" != "x" ] ; then
		echo -n " $dep.pm" >> $DEP_FILE
	    else
		echo -n " $dep" >> $DEP_FILE
            fi
        done
        echo >> $DEP_FILE
    fi
}
 
# same as pack, except that it uses files in the current directory as the root
# entries, and that no strip, link nor compression is performed.
# Only entries listed in the files pointed to by $* find their way to the archive.
# This function relies on get_perl_depend().
function _do_pack_files {  
    local DEP_FILE FPNAME ext
    local FILE_LIST=$*

    echo -n "Updating timestamps ... "
    find . -not -type l | xargs touch -m
    echo "done."

    # full path name of different files
    FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
    DEP_FILE=$FPNAME.dep

    rm -rf $DEP_FILE
    if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi

    echo -n "Creating $DEP_FILE ... "
    touch $DEP_FILE
    ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
	case $REPLY in
	    *.pm|*.pl|*.ph)
		get_perl_depend $REPLY
		;;
	    */man/man*/*.[0-9n])
		echo "$REPLY \$MAN" >> $DEP_FILE
		;;
	    */info/*.info|*/info/*.info-[0-9]*)
		echo "$REPLY \$INFO" >> $DEP_FILE
		;;
	    bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
		flr="$(file $REPLY)"
		case "$flr" in
		    *\ shell\ *)
			echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
			;;
		    *perl\ commands*)
			echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
			get_perl_depend $REPLY
			;;
		    *:\ symbolic\ link*)
			echo "$REPLY $(readlink $REPLY)" >> $DEP_FILE
			;;
		    *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
			echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
			;;
		    *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
			echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
			;;
		esac
		;;
	esac
    done
    echo "done."

    echo -n "Creating $FPNAME.lst ... "
    # we try the special case of the '.' entry which is needed to set the root permissions.
    # this entry must be set as "." in FILE_LIST.
    if grep -q '^.[ 	]' $FILE_LIST; then
	set -- $(grep '^.[ 	]' $FILE_LIST)
	owner=${2%%:*}
	group=${2##*:}
	echo "d $3 $owner $group          0 -------------------------------- 0 ."
    fi > $FPNAME.lst
    (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
    echo "done."

    echo -n "Creating $FPNAME.$PKGSUFF ... "

    # we want everything, including directories.
    cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null

    # create shortcuts ".*" for tgz, dep and lst files
    for ext in dep lst tgz; do
        rm -f $PKGDIR/.$ext
        ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
    done
    echo "done."
    return 0
}


# packs the prepacked files into a new file located in $DEVROOT.
# any eventual old package is removed.
# this function relies on _do_pack_files(), get_perl_depend(), 
function do_pack {
    local DEP_FILE FPNAME
    local FILE_LISTS ext

    # normalize the list with an absolute path for each entry
    for file in $FILE_LIST ; do
	if [ -z "${file##/*}" ]; then
	    FILE_LISTS="$FILE_LISTS $file"
	else
	    FILE_LISTS="$FILE_LISTS $(pwd)/$file"
	fi
    done
    # FIXME: is this normal ???
    if [ ! -d "$ROOTDIR" ] ; then
	echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
	exit 1
    fi
    cd $ROOTDIR

    # use the file list when available
    if [ "$FILE_LISTS" ]; then
        _do_pack_files $FILE_LISTS
        return $?
    fi

##  ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
##  find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
##  ldconfig -nr . ) > /dev/null 2>&1

    echo -n "Updating libraries ... "
    ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
    echo "done."

    echo -n "Updating timestamps ... "
    find . ! -type l | xargs touch -m
    echo "done."

    # full path name of different files
    FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
    DEP_FILE=$FPNAME.dep

    # rebuild dependencies file, first is a diff file
    echo -n "Creating $DEP_FILE ... "
    rm -rf $DEP_FILE
    if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi

    # build a one shot function 'add' to add dependences
    oldadd="$(declare -f add)"
    # usage: add file [...] need file [...]
    function add { 
       local file files
       # remove file
       while [ $# -gt 0 -a "x$1" != xneed ] ; do 
           files=( "$1" "${files[@]}" ) 
           shift
       done
       [ $# -le 1 ] && return
       shift
       for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
    }
    # load dependences function
    declare -f load_deps > /dev/null && ( load_deps )
    # reset 'add' function
    unset add
    # reload old one
    [ -n "$oldadd" ] && eval "$oldadd"

    touch $DEP_FILE
    find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
	case $REPLY in
	    *.pm|*.pl|*.ph)
		get_perl_depend $REPLY
		;;
	    */man/man*/*.[0-9n])
		if [ "${REPLY/*gz}" ] ; then
		    if [ -L $REPLY ] ; then
			LINK=$(readlink $REPLY)
			rm $REPLY
			ln -s $LINK.gz $REPLY.gz
		    else
			gzip -f -9 $REPLY
			chmod 644 $REPLY.gz
		    fi
		fi
		echo "$REPLY \$MAN" >> $DEP_FILE
		;;
	    */info/*.info|*/info/*.info-[0-9]*)
		if [ "${REPLY/*gz}" ] ; then
		    gzip -f -9 $REPLY
		    chmod 644 $REPLY.gz
		fi
		echo "$REPLY \$INFO" >> $DEP_FILE
		;;
	    bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
		flr="$(file $REPLY)"
		case "$flr" in
		    *\ shell\ *)
			echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
			;;
		    *perl\ commands*)
			echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
			get_perl_depend $REPLY
			;;
		    *:\ symbolic\ link*)
			echo "$REPLY $(readlink $REPLY)" >> $DEP_FILE
			;;
		    *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
			echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
			;;
		    *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
			echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
			;;
		esac
		;;
	esac
    done
    echo "done."

    echo -n "Creating $FPNAME.lst ... "
    ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
    echo "done."

    echo -n "Creating $FPNAME.$PKGSUFF ... "
    # we want everything, and directories only if they're empty. 
    # All this without './' we shouldn't get an empty line since . 
    # should contain at least what we want to tar !
    $FIND_CMD . | tar --no-recursion -T - -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null

    # create shortcuts ".*" for tgz, dep and lst files
    for ext in dep lst tgz; do
        rm -f $PKGDIR/.$ext
        ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
    done
    echo "done."
    return 0
}

# this function sets all needed compiler options
function set_compiler_options {
    # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
    case "$FLXARCH" in
    	i686)     arch=${arch:-i686}  cpu=${cpu:-i686}   basearch=${basearch:-i386} ;;
   	i586)     arch=${arch:-i586}  cpu=${cpu:-i686}   basearch=${basearch:-i386} ;;
    	i486)     arch=${arch:-i486}  cpu=${cpu:-i486}   basearch=${basearch:-i386} ;;
    	i386)     arch=${arch:-i386}  cpu=${cpu:-i386}   basearch=${basearch:-i386} ;;
    	ev[456]*) arch=${arch:-$FLXARCH}   cpu=${cpu:-$FLXARCH}    basearch=${basearch:-$FLXARCH} ;;
    	parisc)   arch=${arch:-1.1}   cpu=${cpu:-7100LC} basearch=${basearch:-1.1}  ;;
    	sparc)    arch=${arch:-sparc} cpu=${cpu:-sparc}  basearch=${basearch:-sparc} ;;
    	sparc64)  arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc}  basearch=${basearch:-ultrasparc} ;;
    	*)        arch=${arch:-i586}  cpu=${cpu:-i686}   basearch=${basearch:-i386} ;;
    esac
    
    # Handling of cross-compilers :
    # - setting CC will force both HOSTCC and FLXCROSSCC
    # - setting HOSTCC will keep it
    # - setting FLXCROSS will set CC
    # - setting FLXCROSSCC will set CC whatever FLXCROSS is.

    if [ -z "$FLX_CROSS_OPT_SET" ]; then
        CC=${CC:-gcc}
        AS=${AS:-as}
        LD=${LD:-ld}
        AR=${AR:-ar}
        STRIP=${STRIP:-strip}
        OBJDUMP=${OBJDUMP:-objdump}

        HOSTCC=${HOSTCC:-$CC}
        HOSTAS=${HOSTAS:-$AS}
        HOSTLD=${HOSTLD:-$LD}
        HOSTAR=${HOSTAR:-$AR}
        HOSTSTRIP=${HOSTSTRIP:-$STRIP}
        HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}

        if [ -n "$FLXCROSS" ]; then
            CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
            AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
            LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
            AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
            STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
            OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
        fi
        # specify that we don't want to do this again
        FLX_CROSS_OPT_SET=1
    fi
       
    case "$FLXARCH" in
    	*86)
    	    CC=${CC:-gcc}
    	    FLX_ARCH_CURRENT="$FLXARCH"
    	    FLX_ARCH_COMMON="i586"
    	    FLX_ARCH_SMALL="$basearch"
    	    GCC_ARCH_CURRENT="-march=$arch"
    	    GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
    	    GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
    	    GCC_CPU_CURRENT="-mcpu=$cpu"
    	    GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
    	    GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
    	    GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
    	    GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
    	    GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
    	    if [ $TESTGCC -gt 0 ] && $CC -falign-loops=0 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
    		    GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
    		    GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -falign-jumps=0"
    		    GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -falign-jumps=0 -falign-loops=0 -falign-functions=0"
    	    fi
    	    ;;
    
    	parisc*)
    	    CC=${CC:-gcc}
    	    FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
    	    FLX_ARCH_COMMON="1.0"
    	    FLX_ARCH_SMALL="1.0"
    	    GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
    	    GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
    	    GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
    	    GCC_CPU_CURRENT="-mschedule=7100LC"
    	    GCC_CPU_COMMON="-mschedule=7100"
    	    GCC_CPU_SMALL="-mschedule=7100"
    	    GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
    	    GCC_OPT_FAST="-O2 -falign-jumps=0"
    	    GCC_OPT_SMALL="-Os -falign-jumps=0 -falign-loops=0 -falign-functions=0"
    	    ;;
    	    
    	sparc*)
    	    CC=${CC:-gcc}
    	    FLX_ARCH_CURRENT="$FLXARCH"
    	    FLX_ARCH_COMMON="$FLXARCH"
    	    FLX_ARCH_SMALL="$FLXARCH"
    	    GCC_ARCH_CURRENT="-mcpu=$arch"
    	    GCC_ARCH_COMMON="-mcpu=$arch"
    	    GCC_ARCH_SMALL="-mcpu=$arch"
    	    GCC_CPU_CURRENT="-mtune=$cpu"
    	    GCC_CPU_COMMON="-mtune=$cpu"
    	    GCC_CPU_SMALL="-mtune=$cpu"
    	    GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
    	    GCC_OPT_FAST="-O2 -falign-jumps=0"
    	    GCC_OPT_SMALL="-Os -falign-jumps=0 -falign-loops=0 -falign-functions=0"
    	    ;;
    	    
    	ev[456]*)
    	    CC=${CC:-gcc}
    	    FLX_ARCH_CURRENT="$FLXARCH"
    	    FLX_ARCH_COMMON="$FLXARCH"
    	    FLX_ARCH_SMALL="$FLXARCH"
    	    GCC_ARCH_CURRENT="-mcpu=$arch"
    	    GCC_ARCH_COMMON="-mcpu=$arch"
    	    GCC_ARCH_SMALL="-mcpu=$arch"
    	    GCC_CPU_CURRENT="-mtune=$cpu"
    	    GCC_CPU_COMMON="-mtune=$cpu"
    	    GCC_CPU_SMALL="-mtune=$cpu"
    	    GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
    	    GCC_OPT_FAST="-O2 -falign-jumps=0"
    	    GCC_OPT_SMALL="-Os -falign-jumps=0 -falign-loops=0 -falign-functions=0"
    	    ;;
    	    
    	*)
    	    CC=${CC:-gcc}
    	    FLX_ARCH_CURRENT="$FLXARCH"
    	    FLX_ARCH_COMMON="$FLXARCH"
    	    FLX_ARCH_SMALL="$FLXARCH"
    	    GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
    	    GCC_OPT_FAST="-O2 -malign-jumps=0"
    	    GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
    	    if [ $TESTGCC -gt 0 ] && $CC -falign-loops=0 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
    		    GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
    		    GCC_OPT_FAST="-O2 -falign-jumps=0"
    		    GCC_OPT_SMALL="-Os -falign-jumps=0 -falign-loops=0 -falign-functions=0"
    	    fi
    	    ;;
    esac

    export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
    export CC AS LD AR STRIP OBJDUMP GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
    export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
    export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL

    return 0
}

function usage {
    # this is needed to present current options to the user
    set_compiler_options

    echo "Usage:"
    echo "  pkg [-options]* <action> [ pkg [ pkg2 ] ]"
    echo
    echo "  pkg newpkg [ new_pkg [ old_pkg ] ]"
    echo "  pkg newpkg [ newpkg ]=[ old_pkg ]"
    echo "    ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
    echo "        pkg newpkg =apache-1.3"
    echo "        pkg newpkg bash"
    echo "        pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
    echo
    echo "  pkg setpkg [ new_pkg ]"
    echo "    ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
    echo
    echo "  pkg { info | cat | edit | unpack | changelog } [ pkg ]"
    echo "    ex: pkg info"
    echo "        pkg info bash"
    echo "        pkg edit modutils-2.4"
    echo "        pkg cat gzip-1.3"
    echo
    echo "  pkg { clean | compile | config | compile_only | build }*"
    echo "  pkg { prepack | strip | pack | delpack | release }*"
    echo
    echo "  pkg { patch | unpatch } [ patch_name ]"
    echo
    echo "  pkg { any_command } [ any_args ]"
    echo
    echo "User variables are :"
    echo "PKGROOT : directory containing released packages <$PKGROOT>"
    echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
    echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
    echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
    echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
    echo
    echo "Architecture-specific variables :"
    echo -e "            CURRENT\t|COMMON\t|SMALL"
    echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
    echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
    echo -e "GCC_CPU_  : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
    echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
    echo "GCC_OPT_FAST=$GCC_OPT_FAST"
    echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"

# Those two are not user-settable anymore
#    echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
#    echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
    exit 1
}

# displays usage
function do_help {
    usage
    return 0
}

# creates a new changelog entry and prompts the user to add information.
function do_changelog {
    # Let's create a new changelog entry
    (echo '0a'; date +"%Y/%m/%d %H:%M  $LOGNAME@$HOSTNAME";
     echo ''; echo $'\t* '; echo ''; echo '.' ;
     echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null

    # we'll ask the user to fill the changelog
    vi -c ":3" $PKGDIR/ChangeLog
    return 0
}

# marks the current package as released
function do_release {
    local last_pkg

    echo "#####################################################"
    echo "# Release command not implemented yet ! Aborting... #"
    echo "#####################################################"
    #exit 1
    # some important checks before things get wrong
    if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
	echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
	exit 1
    fi

    if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
	echo "Nothing to be released in this package."
	echo "Please ensure that .lst, .dep and .tgz exist."
	exit 1
    fi

    # first, the destination directory must not exist
    if [ -d "$PKGROOT/$EXACTPKG" ]; then
	if [ -e "$PKGROOT/$EXACTPKG/RELEASED" ]; then
	    echo "Error: This package already exists."
	else
	    echo "Error: The package directory $PKGROOT/$EXACTPKG already exists."
	fi
	exit 1
    fi

    # identify last changelog entry
    last_pkg=""
    if [ -e "$PKGDIR/ChangeLog" ]; then
	last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
	last_pkg=${last_pkg##*released }
    fi

    if [ "$last_pkg" != "$EXACTPKG" ]; then
	# Let's create a new changelog entry
	touch $PKGDIR/ChangeLog	# avoid error message in case it doesn't exist
	(echo '0a'; date +"%Y/%m/%d %H:%M  $LOGNAME@$HOSTNAME";
	 echo ''; echo $'\t'"* released $EXACTPKG";
	 echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
    fi

    # we'll ask the user to fill the changelog
    vi -c ":4" $PKGDIR/ChangeLog

#<FIXME.WTA>
#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
#</FIXME>

    if ! mv $PKGDIR $PKGROOT/ ; then
	echo "Error: cannot move the package to the released directory. Cancelling."
	# the mv here fails atomically, so nothing's lost in PKGDIR, but we have
	# to clean a possible partial copy
	rm -rf $PKGROOT/$EXACTPKG
	exit 2
    fi

    touch $PKGROOT/$EXACTPKG/RELEASED

    return 0
}

######
###### here are some functions used only from main
######

function known_cmd {
    declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
    declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
    declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
    return 0
}


######
###### here is the main entry point
######

# scan the command line

release_only=0
force=0
TESTGCC=0
PRINTUSAGE=0
ARGLIST=( )
ACTION=
CHAINCMD=1

[ $# -eq 0 ] && PRINTUSAGE=1

while [ $# -gt 0 ] ; do
    case "$1" in 
	--force )
	    force=1
	    ;;
	--help|-h)
	    PRINTUSAGE=1
	    ;;
	--rel|-r*)
	    release_only=1
	    ;;
	--)
	    shift
	    ARGLIST=(${ARGLIST[*]} $*)
	    break
	    ;;
	-* )
	    PRINTUSAGE=1
	    ;;
	*)
	    ARGLIST=(${ARGLIST[*]} "$1")
	    ;;
    esac
    shift
done


#echo "arglist=${ARGLIST[*]}"

[ $PRINTUSAGE -gt 0 ] && usage
[ ${#ARGLIST[*]} -lt 1 ] && usage

# Some actions can be chained, others not. we'll get the longest
# possible chain, and stop once we encounter a non-chainable action

while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
    set -o noglob
    ACTION=${ARGLIST[0]}
    TESTGCC=0
    #    unset ARGLIST[0]  ### doesn't work in scripts with this shitty bash !!!
    ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} )  # gets expanded with shitty bash !

    case "$ACTION" in
	newpkg)
	    CHAINCMD=0
	    KNOWNCMD=1
	    # newpkg is the only command which doesn't start by a package lookup.
	    ;;
	setpkg)
	    CHAINCMD=0
	    KNOWNCMD=1
	    get_name $1 %P default
	    ;;
	info|edit|cat|unpack|changelog)
	    CHAINCMD=0
	    KNOWNCMD=1
	    get_name ${ARGLIST[0]} %L %P %D
	    ;;
	patch|unpatch)
	    CHAINCMD=0
	    KNOWNCMD=1
	    REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
	    PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
	    # get_name %L
	    ;;
	compile_only|config|config_only|compile|build)
	    KNOWNCMD=1
	    REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
	    PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
	    TESTGCC=1
	    # get_name %L
	    ;;
	prepack|strip|pack|delpack|release|clean)
	    KNOWNCMD=1
	    REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
	    PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
	    # get_name %L
	    ;;
	*)
	    CHAINCMD=0
	    KNOWNCMD=0
	    REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
	    PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
	    # get_name %L
	    ;;
    esac

    [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2

    set +o noglob
    if [ "$ACTION" != "newpkg" ]; then
	if [ -z "$REPLY" ]; then
	    echo "Error: package name not found."
	    exit 1
	fi
	EXACTPKG=$REPLY

	if [ -z "$PKGDIR" ]; then
	    if [ -e "$PKGROOT/$EXACTPKG/build.cfg" ]; then
		PKGDIR=$PKGROOT/$EXACTPKG
	    else
		PKGDIR=$DEVROOT/$EXACTPKG
	    fi
	fi
	CFGFILE=$PKGDIR/build.cfg
	PKGRADIX=$(get_pkg_radix $EXACTPKG)
	PKGVER=$(get_pkg_ver $EXACTPKG)
	DISTVER=$(get_build_num $EXACTPKG)
	ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
        EXAMPLEDIR=${ROOTDIR}/usr/share/examples

	# for compatibility with old functions. Not used anywhere outside this script.
	packver=$EXACTPKG
	pack=$PKGRADIX
    fi

    set_compiler_options

    if [ "$ACTION" != "newpkg" ]; then
	. $CFGFILE
    fi

    # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
    FLXMAKE=${FLXMAKE:-make}
    FLXPMAKE=${FLXPMAKE:-$FLXMAKE}

    export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST

#    echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
#    echo "ARGLIST=${ARGLIST[*]}"

    if [ $KNOWNCMD -gt 0 ]; then
	known_cmd ${ARGLIST[*]} || exit 1
    else
	if declare -f do_$ACTION >/dev/null; then
	    ( do_$ACTION ${ARGLIST[*]} ) || exit 1
	fi
    fi
    [ $CHAINCMD -gt 0 ] && (echo "===> PKG:  end of  [$ACTION] <===";echo) >&2

    # now, we'll loop only if we were in a chainable action
done

[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
exit 0




































exit 99

###############################################################################################################
###############################################################################################################
###############################################################################################################
###############################################################################################################


DEAD CODE BELOW !!!




































function usage {
    echo "Usage: pkg <action> [new_pkg [old_pkg]]"
    echo " action is one of :"
    echo "   help    : display this help."
    echo "   info    : get information on current package."
    echo "   newpkg  : build a more recent .pkg script from an old one."
    echo "   cat     : display last .pkg file."
    echo "   edit    : edit last .pkg file."
    echo "   patch   : apply a list of patches to the directory prior to compile."
    echo "   unpatch : revert a list of patches to the directory."
    echo "   compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
    echo "   prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
    echo "   strip   : strip binaries in temporary directory"
    echo "   pack    : strip binaries, then package into $PKGROOT"
    echo "   delpack : remove temporary directory"
    echo "   clean   : execute 'make clean' and remove temporary directory."
    echo "   build   : execute clean compile prepack pack."
    echo "   unpack  : extract package into temporary directory"
    echo "Variables are :"
    echo "CFGROOT    : directory for .pkg and patches, <$CFGROOT>"
    echo "CFGFILE    : force to use of a .pkg, <$CFGFILE>"
    echo "PKGROOT    : directory for .lst, .tgz and .dep, <$PKGROOT>"
    echo "ROOTDIR    : base directory for package (not source), <$ROOTDIR>"
    echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
    echo "FLXARCH    : architecture for package name, <$FLXARCH>"
    echo "KERNDIR    : base directory for package (not source), <$KERNDIR>"
    echo "DISTVER    : build version (flx.1)"
    exit 1
}









for ACTION in ${ARGLIST[*]}; do

# now we will try to identify two packages names :
#   - the EXACT one, deduced from command line, then version symlink, then the
#     directory name ; this one doesn't have to exist to be correct.
#   - the NEAREST one, deduced from the same criterions, with and without
#     versions, and based on EXISTING files only.
# The NEAREST one will be used as a source, while the EXACT one will be used as
# a target. When the EXACT one exists, the NEAREST one must obviously be the
# same.

# EXACTPKG can be specified as an environment variable if needed
[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))

if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
    TEMP=$(sortnames $CFGROOT/$EXACTPKG-[0-9]* | tail -1)
    TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG.* | tail -1)}
    TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG-* | tail -1)}
    TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG* | tail -1)}
#    if [ -z "$TEMP" ]; then
#	echo "Cannot find a suitable package for the current directory. Please specify"
#	echo "a correct name on the command line."
#	usage
#	exit 1
#    fi
    [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
    [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
fi

if [ -z "$(get_build_num $EXACTPKG)" ]; then
    RADIX=$(get_pkg_radix $EXACTPKG)
    TEMP=$(sortnames $CFGROOT/$EXACTPKG-* $CFGROOT/$EXACTPKG $CFGROOT/$RADIX | tail -1)

    VER=$(get_pkg_ver $TEMP)
    BUILD=$(get_build_num $TEMP)
    EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
fi

NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
NEWPKGVER=$(get_pkg_ver $EXACTPKG)
NEWDISTVER=$(get_build_num $EXACTPKG)
NEWDISTVER=${NEWDISTVER:-flx.1}
EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER

trylist=( )
[ -d "$CFGROOT/$EXACTPKG" -o -f "$CFGROOT/$EXACTPKG.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
trylist=( ${trylist[*]} $NEWPKGRADIX )
trylist=( ${trylist[*]} $(basename $(pwd)))
trylist=( ${trylist[*]} "default")

echo trylist=${trylist[*]}

for NEARESTPKG in ${trylist[*]}; do
    if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
	TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
	TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
	TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
	#TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
	[ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
    fi

    RADIX=$(get_pkg_radix $NEARESTPKG)
    VER=$(get_pkg_ver $NEARESTPKG)
    BUILD=$(get_build_num $NEARESTPKG)
    NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}

    #### [ "$(get_build_num $NEARESTPKG)" ] &&

    [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
echo NEARESTPKG=$NEARESTPKG

    ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
    ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
done

RADIX=$(get_pkg_radix $NEARESTPKG)
VER=$(get_pkg_ver $NEARESTPKG)
BUILD=$(get_build_num $NEARESTPKG)
NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}

echo "EXACTPKG=$EXACTPKG"
echo "NEARESTPKG=$NEARESTPKG"

# to be removed ## look if there was an argument, in which case we would treat it as a package
# to be removed ## name (either source or destination, depending on the action). These variables
# to be removed ## are set :
# to be removed ##   - ARGPKGFULL  : full package name with version
# to be removed ##   - ARGPKGRADIX : package radix name (without version)
# to be removed ##   - ARGPKGVER   : package version without -flx*
# to be removed ##   - ARGDISTVER  : package build version (flx*)
# to be removed #
# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
# to be removed #    ARGPKGFULL=$(basename ${ARGLIST[0]})
# to be removed #    ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
# to be removed #    ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
# to be removed #    if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
# to be removed #	 ARGDISTVER=$(get_build_num $ARGPKGFULL)
# to be removed #    fi
# to be removed #    ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
# to be removed #    ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
# to be removed #    ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
# to be removed #    ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
# to be removed #fi
# to be removed #
# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
# to be removed #
# to be removed #if [ -L .flxver ]; then
# to be removed #    PKGFULL=$(readlink .flxver)
# to be removed #else
# to be removed #    PKGFULL=$(basename $(pwd))
# to be removed #fi
# to be removed #
# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
# to be removed #
# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
# to be removed #    DISTVER=$(get_build_num $PKGFULL)
# to be removed #fi
# to be removed #
# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
# to be removed #
# to be removed #
# to be removed #
# to be removed ## now process the destination parameters
# to be removed #
# to be removed #if [ -L .flxver ]; then
# to be removed #    NEWPKGFULL=$(readlink .flxver)
# to be removed #else
# to be removed #    NEWPKGFULL=$(basename $(pwd))
# to be removed #fi
# to be removed #
# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
# to be removed #
# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
# to be removed #    NEWDISTVER=$(get_build_num $NEWPKGFULL)
# to be removed #fi
# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
# to be removed #
# to be removed ## recompute the new package version
# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
# to be removed #


# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
# directory name for the new package. If it cannot be found, all actions except
# info and newpkg will fail. So we have to do a newpkg before using a new dir.

if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
    echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
    exit 1
fi

# source configuration
ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}


CURPKG=$NEARESTPKG
PKGRADIX=$(get_pkg_radix $NEARESTPKG)
PKGVER=$(get_pkg_ver $NEARESTPKG)
if echo $NEARESTPKG | grep -q -- "-flx\." ; then
    DISTVER=$(get_build_num $NEARESTPKG)
    NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
else
    DISTVER=
    NEARESTPKG=$PKGRADIX-$PKGVER
fi

CFGDIR=$CFGROOT/$CURPKG
CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF

echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"

exit 0



if [ -n "$CFGFILE" ]; then
    CFGDIR=$NEWCFGROOT/$NEWBASECFG
    . $CFGFILE
else
	    #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
	    #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
	    #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
	    #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
	    CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
	    CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
	    CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
	    CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}

	    # to be completed

	    if [ -z "$CFGFILE" ]; then
		echo "CFGFILE not found. Cannot continue." >&2
		exit 1
	    fi

	    if [ -d $CFGFILE ]; then
		CFGROOT=`dirname $CFGFILE`
		CFGDIR=`basename $CFGFILE`-pkg
		CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
	    else
		CFGROOT=`dirname $CFGFILE`
		CFGDIR=`basename $CFGFILE`-pkg
		CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
		if [ ! -e $CFGROOT/$CFGDIR ]; then
		    echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
		    mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
		    if [ $? != 0 ]; then
			echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
			exit 1
		    else
			echo "Done !"
		    fi
		fi
	    fi

	    if [ -e "$CFGFILE" ]; then
		. $CFGFILE
	    else
		echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
		exit 1
	    fi
	fi

	if [ -z "$DISTVER" ]; then
	    if echo $CFGFILE | grep -q -- "-flx\." ; then
		DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
	    else
		DISTVER='flx.1'
	    fi
	fi

	echo $packver | grep -q -- "-flx\."
	if [ $? != 0 ] ; then
	    packver=$packver-$DISTVER
	fi

	echo $packver | grep -q -- "-$FLXARCH\$" 
	if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi

	prefix=${packver%%[._-][0-9]*} 
	suffix=${packver#$prefix[._-]} 
	PKGVER=${suffix%-flx*}
	PKGRADIX=$prefix
	#echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
	if [ -z "$DISTVER" ]; then
	    DISTVER=${suffix#$PKGVER-}
	    if [ "$DISTVER" = "$PKGVER" ]; then
		DISTVER="flx.1"
	    else
		DISTVER=${DISTVER%-*}
	    fi
	fi

	case "$FLXARCH" in
	    i686) arch=i686 cpu=i686 basearch=i386 ;;
	    i486) arch=i486 cpu=i486 basearch=i386 ;;
	    i386) arch=i386 cpu=i386 basearch=i386 ;;
	    *)    arch=i586 cpu=i686 basearch=i386 ;;
	esac

	if [ -z "$FLXMAKE" ]; then
	    FLXMAKE=make
	fi

    
	if [ -z "${PATCH_LIST}" ]; then
	    PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
	    if [ ! -e ${PATCH_LIST} ]; then
		unset PATCH_LIST
	    fi
	fi

	export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
 
	declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
	[ $? != 0 ] && exit $?
	declare -f do_$ACTION > /dev/null && ( do_$ACTION )
	[ $? != 0 ] && exit $?
	declare -f post_$ACTION > /dev/null && ( post_$ACTION )
	[ $? != 0 ] && exit $?
    fi
fi