#!/bin/sh
#
# Script for file name charset conversion. It includes 
# options for renaming, changing charset, recursive file 
# name expansion.
#
# Syntax:
#
# chnamecoding [options] (file|dir)
#
# Brief help on parameters:
# -r | --recursive            - recursive
# -f | --charset-in            - charset of the input filename
# -o | --charset-out        - charset of output filename
## Script usage:
usage()
{
    echo "Usage:";
    echo "chnamecoding [-r | --recursive] [-f | --charset-in] [-o | --charset-out] (file|dir)";
    echo "-r | --recursive    -    recursive";
    echo "-f | --charset-in    -    charset of the input filename";
    echo "-o | --charset-out    -    charset of output filename";
}
# Exit if commandline is empty
if [ $# -eq 0 ]
then
    echo "Please specify argument list";
    usage;
    exit 1;
fi
# Init script startup variables
recursive=no;
charset_in="CP1251";                # default input charset
charset_out="KOI8-R";                # default output charset
# Analize input argument list
for i in $*
do
    case "$i" in
    --recursive | -r)
        recursive=yes;
        shift;
    ;;
    --charset-in=* )
        charset_in=`expr -- "$i" : '--charset-in=\(.*\)'`;
        shift;
    ;;
    -f=* )
        charset_in=`expr -- "$i" : '-f=\(.*\)'`;
        shift;
    ;;
    --charset-out=* )
        charset_out=`expr -- "$i" : '--charset-out=\(.*\)'`;
        shift;
    ;;
    -o=* )
        charset_out=`expr -- "$i" : '-o=\(.*\)'`;
        shift;
    ;;
    -*)
        echo "$i - Unknown option";
        usage;
        exit 1;
    ;;
    
    *)
        break;
    ;;
    esac
done
if [ $charset_in = $charset_out ]
then
    echo "Input and output charsets are the same";
    echo "===> Done.";
    exit 0;
fi
# Check for ICONV and input-output charsets
if [ ! -f /usr/local/bin/iconv ]
then
    echo "Can't find iconv executable";
    exit 1;
fi
# Check if input and output charsets are in iconv 
# charset table
charset_avail=`/usr/local/bin/iconv -l`;
check_in=0;
check_out=0;
for i in $charset_avail
do
    if [ $i = `echo $charset_in | tr "[:lower:]" "[:upper:]"` ]
    then
        check_in=1;
    fi
    if [ $i = `echo $charset_out | tr "[:lower:]" "[:upper:]"` ]
    then
        check_out=1;
    fi
done
if [ $check_in -eq 0 -o $check_out -eq 0 ]
then
    echo "Invalid input or output charset found";
    exit 1;
fi
# File, and dir name processing
echo "===> Begin processing names..."
while [ $# -gt 0 ]
do
    dir=`dirname "$1"`;
    name=`basename "$1"`;
#
# Directory name conversion
#
    if [ -d "$1" ]
    then
        newname=`echo "$1" | iconv -c -f $charset_in -t $charset_out`;
        mv "$1" "$newname" 2>/dev/null;
        echo "==> Moving directory $1 to $newname";
#
# Recursive file name processing
#
        if [ $recursive = "yes" ]
        then
            find "$newname" -type d -execdir sh -c '\
            newname=`echo "$1" | iconv -c -f $2 -t $3`;\
            mv "$1" "$newname";\
            echo "==> Moving directory $1 to $newname";' {} {} $charset_in $charset_out \; 2>/dev/null
            find "$newname" -type f -execdir sh -c '\
            newname=`echo "$1" | iconv -c -f $2 -t $3`;\
            mv "$1" "$newname";\
            echo "==> Moving file $1 to $newname";' {} {} $charset_in $charset_out \; 2>/dev/null
        fi
#
# Single file name or mask name conversion
#
    elif [ -d "$dir" ]
    then
        find "$dir" -name "$name" -type f -execdir sh -c '\
        newname=`echo "$1" | iconv -c -f $2 -t $3`;\
        mv "$1" "$newname";\
        echo "==> Moving file $1 to $newname";' {} {} $charset_in $charset_out \; 2>/dev/null    
    else
        echo "=> File \"$1\" not found.";
    fi
    shift;
done
echo "===> Done.";