#!/bin/sh config=/bin/config PROFTPD_CONF=/tmp/proftpd.conf TMP_DATA_XYZ=/tmp/tmp_data_xyz proftpd_tmpfile=/tmp/tmp_ftp_file proftpd_anony=/tmp/ftp_anony.conf TMP_DEVICE_NAME=/tmp/tmp_device_name_xyz TMP_LOCK_FILE=/tmp/tmp_lock_abc123xyz # ftp_passwd_enable=`${config} get usb_passwdFvia` ftp_passwd_enable=0 check_all_folder_limit() { if [ -f /tmp/shared_usb_folder ]; then rm -f /tmp/shared_usb_folder; fi ${config} show | grep "shared_usb_folder" | cut -d '*' -f3,4 > /tmp/shared_usb_folder while read folder do if [ "${folder}X" != "0*0X" ]; then return 1; fi done < /tmp/shared_usb_folder ${config} show | grep "shared_usb_folder_users" | awk -F= '{print $2}' > /tmp/shared_usb_folder while read folder do if [ "${folder}X" = "0*0*0*0X" -o "${folder}X" = "1*1*1*1X" ]; then return 0; fi done < /tmp/shared_usb_folder rm -f /tmp/shared_usb_folder return 0 } creat_cur_workdir() { mkdir -p /tmp/ftpadmin mkdir -p /tmp/ftpadmin/shares mkdir -p /tmp/ftpguest mkdir -p /tmp/ftpguest/shares } checkout_other_user_display() { ${config} get sharename1 > /dev/null if [ $? -ne 0 ]; then return fi folder_auth=$(${config} get shared_usb_folder_users$1) user1=`echo $folder_auth | awk -F* '{print $1}'` user2=`echo $folder_auth | awk -F* '{print $2}'` user3=`echo $folder_auth | awk -F* '{print $3}'` user4=`echo $folder_auth | awk -F* '{print $4}'` [ "$user1" = "2" -o "$user1" = "3" ] && echo " AllowUser `${config} get sharename1 | awk '{print $1}'`" [ "$user2" = "2" -o "$user2" = "3" ] && echo " AllowUser `${config} get sharename2 | awk '{print $1}'`" [ "$user3" = "2" -o "$user3" = "3" ] && echo " AllowUser `${config} get sharename3 | awk '{print $1}'`" [ "$user4" = "2" -o "$user4" = "3" ] && echo " AllowUser `${config} get sharename4 | awk '{print $1}'`" } checkout_other_user_write() { ${config} get sharename1 > /dev/null if [ $? -ne 0 ]; then return fi folder_auth=$(${config} get shared_usb_folder_users$1) user1=`echo $folder_auth | awk -F* '{print $1}'` user2=`echo $folder_auth | awk -F* '{print $2}'` user3=`echo $folder_auth | awk -F* '{print $3}'` user4=`echo $folder_auth | awk -F* '{print $4}'` [ "$user1" = "3" ] && echo " AllowUser `${config} get sharename1 | awk '{print $1}'`" [ "$user2" = "3" ] && echo " AllowUser `${config} get sharename2 | awk '{print $1}'`" [ "$user3" = "3" ] && echo " AllowUser `${config} get sharename3 | awk '{print $1}'`" [ "$user4" = "3" ] && echo " AllowUser `${config} get sharename4 | awk '{print $1}'`" } checkout_other_user_read() { ${config} get sharename1 > /dev/null if [ $? -ne 0 ]; then return fi folder_auth=$(${config} get shared_usb_folder_users$1) user1=`echo $folder_auth | awk -F* '{print $1}'` user2=`echo $folder_auth | awk -F* '{print $2}'` user3=`echo $folder_auth | awk -F* '{print $3}'` user4=`echo $folder_auth | awk -F* '{print $4}'` [ "$user1" = "2" -o "$user1" = "3" ] && echo " AllowUser `${config} get sharename1 | awk '{print $1}'`" [ "$user2" = "2" -o "$user2" = "3" ] && echo " AllowUser `${config} get sharename2 | awk '{print $1}'`" [ "$user3" = "2" -o "$user3" = "3" ] && echo " AllowUser `${config} get sharename3 | awk '{print $1}'`" [ "$user4" = "2" -o "$user4" = "3" ] && echo " AllowUser `${config} get sharename4 | awk '{print $1}'`" } append_read_allowuser() { if [ "x$ftp_passwd_enable" = "x0" ];then case "$1" in 0) echo " AllowUser admin" echo " AllowUser guest";; 1) echo " AllowUser guest";; 2) echo " AllowUser admin";; *);; esac else case "$1" in 0 | 1 | 2) echo " AllowUser admin";; *);; esac fi checkout_other_user_read $2 } append_write_allowuser() { if [ "x$ftp_passwd_enable" = "x0" ];then case "$1" in 0) echo " AllowUser admin" echo " AllowUser guest";; 1) echo " AllowUser admin";; 2) echo " AllowUser admin";; *);; esac else case "$1" in 0 | 1 | 2) echo " AllowUser admin";; *);; esac fi checkout_other_user_write $2 } append_display_allowuser() { if [ "x$ftp_passwd_enable" = "x0" ];then case "$1" in 0 | 1) echo " AllowUser admin" echo " AllowUser guest";; 2) echo " AllowUser admin";; *);; esac else case "$1" in 0 | 1 | 2) echo " AllowUser admin";; *);; esac fi checkout_other_user_display $2 } print_onesharefolder_config() { cat <>$proftpd_tmpfile AllowOverwrite on DenyAll EOF append_display_allowuser $2 $3 >> $proftpd_tmpfile cat <>$proftpd_tmpfile DenyAll EOF append_read_allowuser $2 $3 >> $proftpd_tmpfile cat <> $proftpd_tmpfile DenyAll EOF append_write_allowuser $2 $3 >> $proftpd_tmpfile cat <> $proftpd_tmpfile EOF } print_share_anonymous_config() { cat <>$proftpd_anony DenyAll EOF append_display_allowuser $2 $3 >> $proftpd_anony cat <> $proftpd_anony DenyAll EOF append_read_allowuser $2 $3 >> $proftpd_anony cat <> $proftpd_anony DenyAll EOF append_write_allowuser $2 $3 >> $proftpd_anony cat <> $proftpd_anony EOF ## if it has a folder /test, create a network folder in GUI,folder /test, ## Share name: share_test, and it has admin:admin access. And / has ## all-no-password. use anonymous to login /. we should can not access to /test/. if [ "x$2" != "x" -a "$2" != "0" -a "$4" != "/" ];then cat <>$proftpd_anony DenyAll EOF append_display_allowuser $2 $3 >> $proftpd_anony cat <> $proftpd_anony DenyAll EOF append_read_allowuser $2 $3 >> $proftpd_anony cat <> $proftpd_anony DenyAll EOF append_write_allowuser $2 $3 >> $proftpd_anony cat <> $proftpd_anony EOF fi } print_common_head() { cat < DelayEngine off AllowOverwrite on User root Group root DefaultRoot ~ EOF } print_common_tail() { cat < EOF if [ "x$ftp_passwd_enable" = "x0" ];then cat <$TMP_DEVICE_NAME while read LINE do if [ "$LINE" = "$1" ];then return 1 break; fi done<$TMP_DEVICE_NAME return 0 } isd_card() { disk_name=`echo $1 | sed 's/[0-9]//g'` if [ "x$disk_name" = "x$($config get sd_card_diskname)" ]; then return 0 else return 1 fi } isata() { disk_name=`echo $1 | sed 's/[0-9]//g'` if [ "x$disk_name" = "x$($config get sata_diskname)" ]; then return 0 else return 1 fi } Itoa_sd_card() { array="0 1 2 3 4 5 6 7 8 9" i=0 for ch in $array;do if [ "$i" = "$1" ];then echo "$ch" break fi let i=$i+1 done } Itoa_sata() { array="s r q p o n m l k j i h g f e d c b a" i=0 for ch in $array;do if [ "$i" = "$1" ];then echo "$ch" break fi let i=$i+1 done } Itoa_usb() { array="U T S R Q P O N M L K J I H G F E D C B A" i=0 for ch in $array;do if [ "$i" = "$1" ];then echo "$ch" break fi let i=$i+1 done } isupper() { supper=`echo "$1" | awk '{if($0~/^[A-Z]/) print "1"; else if($0~/^[a-z]/) print "0"}'` echo "$supper" } get_vendor_from_disk() { dev=`echo "$1" | cut -c 1-3` vendor=`cat /sys/block/$dev/device/vendor` model=`cat /sys/block/$dev/device/model` vendor=$(echo ${vendor} | sed 's/[[:space:]]*$//') model=$(echo ${model} | sed 's/[[:space:]]*$//') device_vendor="$vendor $model" echo "$device_vendor" } construct_volume() { tmp_capacity=$2 if [ $tmp_capacity -ge 1024 ] ;then GByte=`expr $tmp_capacity / 1024` left=`expr $tmp_capacity % 1024` left=`expr $left \* 100` left=`expr $left / 1024` len=`echo ${left} | wc -L` if [ $len -eq 1 -a $left -ne 0 ];then left=0$left fi if [ $left -eq 0 ];then format_capacity="$GByte GB" else format_capacity="$GByte.$left GB" fi else format_capacity="$2 MB" fi tmp=`isupper $1` if [ "$tmp" = "1" ]; then echo "$1 Drive ($format_capacity)" elif [ "$tmp" = "0" ]; then echo "$1 External_Disk($format_capacity)" else echo "$1 Sd_Card ($format_capacity)" fi } get_sata_serial_num() { serial_num=`$config get sata_serial_no` disk_num=`echo $1 | sed 's/[a-z]//g'` echo "$serial_num"_"$disk_num" } get_usb_serial_num() { disk_name=`echo $1 | sed 's/[0-9]//g'` partition_num=`echo $1 | cut -c 4-` if [ "x$partition_num" = "x" ]; then partition_num=0 fi disk_scsi_id=`ls /sys/block/$disk_name/device/scsi_device* | awk -F: '{print $1}'` cat /proc/scsi/usb-storage/$disk_scsi_id > /tmp/disk_scsi_info_ftp while read LINE do tag=`echo $LINE | awk -F: '{print $1}'` if [ "$tag" = "Serial Number" ];then serial_num=`echo $LINE | awk -F: '{print $2}' | sed 's/[[:space:]]*$//g' | sed 's/^[ ]*//'` break fi done disk name"sda1 or sdb1 or sdc" #$2---> label "U T O P Q" #$3--->capacity "3.23GB 456MB" get_volume_from_disk() { disk_name=`echo $1 | sed 's/[0-9]//g'` partition_num=`echo $1 | cut -c 4-` volume=`/usr/sbin/vol_id -L /dev/$1` if [ "x$volume" = "x" ];then volume=`echo $(/usr/sbin/parted -s /dev/$disk_name print | grep "Number" -A16 | sed -n '2,16p' | awk 'NF>=6{for(n=6;n<=NF;n++)printf $n" ";print ""}' | sed -n $partition_num"p")` if [ "x$volume" = "x" ];then volume="`construct_volume $2 $3`" fi fi # volume="`construct_volume $2 $3 $1`" echo "$volume" } # parameters: #$1----> disk_id: "serial_number"_"partition_num" check_approved_disk() { if [ "$($config get usb_enableUSB)" = "0" ]; then return 1; fi serial=`echo $1 | awk -F_ '{print $1}'` num=1 while true do approved_device=`${config} get USB_approved_device$num` if [ "x$approved_device" = "x" ];then break; fi approved_serial=`echo $approved_device | awk -F* '{print $NF}'` if [ "x$approved_serial" = "x$serial" ]; then return 1; fi let num=$num+1 done return 0; } #------------------------------------ #cat /proc/partitions #major minor #blocks name # # 31 0 256 mtdblock0 # ... # 8 0 78150744 sda # 8 1 1 sda1 #an extended partition # 8 5 23711908 sda5 # 8 6 27487183 sda6 # 8 7 26940973 sda7 # 8 16 248288 sdb # # 8 17 248272 sdb1 #------------------------------------- scan_disk_entries() { i=0 j=0 k=0 cat /proc/partitions | awk '{print $3,$4}' | grep sd >$TMP_DATA_XYZ sharename_list="" #recode all sharename while read LINE do capacity=`echo $LINE | awk '{print $1}'` M_capacity=`expr $capacity / 1024` # It indicates that this partition should be an extended partition. if [ "$M_capacity" = "0" ];then continue fi part_name=`echo $LINE | awk '{print $2}'` # ignore the dev like "sdb" partition_tb=$(parted -s /dev/`echo $part_name | sed 's/[0-9]//g'` print | grep "Partition Table" | awk '{print $3}') if [ "`echo ${#part_name}`" != "4" -a "x$partition_tb" != "xloop" ];then continue fi if [ "x$(parted -s /dev/`echo $part_name | sed 's/[0-9]//g'` print noshare | grep $part_name)" != "x" -a "x$partition_tb" != "xloop" ]; then continue fi if isata "$part_name" then label=`Itoa_sata "$j"` if [ "x$label" = "x" ]; then continue fi let j=$j+1 disk_id=`get_sata_serial_num "$part_name"` elif isd_card "$part_name" then label=`Itoa_sd_card "$k"` if [ "x$label" = "x" ]; then continue fi let k=$k+1 disk_id=`get_sd_card_serial_num "$part_name"` else label=`Itoa_usb "$i"` if [ "x$label" = "x" ]; then continue fi let i=$i+1 disk_id=`get_usb_serial_num "$part_name"` fi #sda7 is not dafake, but it still should be record, so move i=i+1 before the isdafake check. if isdafake "$part_name" then continue fi vendor=`get_vendor_from_disk "$part_name"` volume=`get_volume_from_disk "$part_name" "$label" "$M_capacity"` if [ "x$vendor" = "x" -o "x$volume" = "x" ];then continue fi if check_approved_disk "$disk_id"; then continue fi #find the share folder in this disk scan_sharefoler_in_this_disk "$part_name" "$vendor" "$volume" "$label" "$disk_id" if [ $i -ge 20 ];then break fi done<$TMP_DATA_XYZ rm -f $TMP_DATA_XYZ } scan_sharefoler_in_this_disk() #$1: dev $2: vendor $3: volume $4:label $5:disk_id { local j=0 local root_share="" # sharename_list="" #recode all sharename while true do sharefolder_item=$($config get "shared_usb_folder$j") if [ "x$sharefolder_item" = "x" ];then break; fi # Trim the space for the share folder name sharename=`echo "$sharefolder_item" | awk -F* '{print $1}' | sed 's/ //g'` relative_path=`echo "$sharefolder_item" | awk -F* '{print $2}'` readable=`echo $sharefolder_item | awk -F* '{print $3}'` writable=`echo $sharefolder_item | awk -F* '{print $4}'` volume=`echo "$sharefolder_item" | awk -F* '{{i=NF-7; a="*";while(i!=0) {printf $(NF-2-i); if(i!=1) printf a; i--}}}'` vendor=`echo $sharefolder_item | awk -F* '{print $(NF-2)}'` serial_num=`echo $sharefolder_item | awk -F* '{print $(NF-1)}'` partition_num=`echo $sharefolder_item | awk -F* '{print $(NF)}'` let access=$readable+$writable echo "$volume = $3 -a $vendor = $2 -a $serial_num _ $partition_num = $5" > /dev/console if [ "$volume" = "$3" -a "$vendor" = "$2" -a "$serial_num"_"$partition_num" = "$5" ]; then #check this sharename have used or not? if have used, add (label) at the end of sharename #'*' is a special signal, we should not use it to filter check_share="`echo $sharename_list | grep $sharename `" if [ "x$check_share" != "x" ];then sharename="$sharename($4)" fi #add sharename in sharename_list sharename_list="$sharename_list*$sharename*" if [ "x$1" != "x" ];then if [ "$relative_path" = "/" ];then root_share="$sharename" fi print_onesharefolder_config "$sharename" "$access" "$j" if [ "x$ftp_passwd_enable" = "x0" ];then print_share_anonymous_config "$sharename" "$access" "$j" "$relative_path" "$root_share" fi #map_usb_to_ftp "$1" "$relative_path" "$sharename" "$access" "$j" mount1 "$1" "$relative_path" "$sharename" ftpadmin 0 fi fi let j=$j+1 done } generate_proftpd_conf() { # USB Storage -- FTP (via Internet) # if [ "$($config get usb_enableFvia)" = "0" ]; then # local proto="$($config get wan_proto)" # # if [ "$proto" = "pppoe" -o "$proto" = "pptp" -o "$proto" = "mulpppoe1" ]; then # wan_ifname="ppp0" # else # wan_ifname="eth1" # fi # # wan_ifvalue=`ifconfig | grep ^$wan_ifname` # if [ "x$wan_ifvalue" != "x" ];then # wan_ipaddr=`ifconfig $wan_ifname | sed 2p -n | awk '/inet/{print $2}' | awk -F: '{print $2}'` # else # wan_ipaddr="" # fi # else # wan_ipaddr="" # fi # USB Storage -- FTP(via lan) if [ "$($config get usb_enableFTP)" = "0" ]; then lan_ipaddr=$($config get lan_ipaddr) else lan_ipaddr="" fi print_common_head >$proftpd_tmpfile # check_all_folder_limit # if [ $? = 0 ]; then # cat << EOF >>$proftpd_tmpfile # # User admin # UserAlias anonymous admin # RequireValidShell off # # # User guest # UserAlias anonymous guest # RequireValidShell off # #EOF cat << EOF >$proftpd_anony User guest UserAlias anonymous guest RequireValidShell off EOF # fi # everytime before re-mount,umount the already folder,delete it clearly... umount_all "ftpadmin" umount_all "ftpguest" #find all usb disks scan_disk_entries cat << EOF >> $proftpd_anony EOF print_common_tail >>$proftpd_tmpfile if [ "$($config get ap_mode)" = "1" -a "$($config get usb_enableFTP)" = "1" ]; then cat << EOF >>$proftpd_tmpfile From 5.0.0.0/24 AllowClass LeafNets DenyAll EOF fi mv -f $proftpd_tmpfile $PROFTPD_CONF } ftp_start() { # add lock mechenism to synchronize file writting k=0 while true;do if [ -f $TMP_LOCK_FILE ];then sleep 1 let k=$k+1 if [ $k -ge 30 ];then rm -f $TMP_LOCK_FILE fi else touch $TMP_LOCK_FILE break fi done test -f $TMP_LOCK_FILE || exit 1 ftp_enable=$($config get usb_enableFTP) ftpvia_enable=$($config get usb_enableFvia) # GUI: "0" --> Enable; "1" --> Disable # if either of the ftp-lan or ftp-wan is ticked, or support remote readyshare, then start the ftp service... if [ "$ftp_enable" = "0" -o "$ftpvia_enable" = "0" ] then # everytime proftpd start,create working dir for admin and guest user, # to avoid user logining failed,,if there are no working dirs bulit. creat_cur_workdir generate_proftpd_conf lan_ipaddr=$($config get lan_ipaddr) echo "DefaultAddress "$lan_ipaddr >> $PROFTPD_CONF [ "x$(grep Directory $PROFTPD_CONF)" != "x" ] && /usr/sbin/proftpd -c $PROFTPD_CONF fi rm -f $TMP_LOCK_FILE } PID_file=/var/run/cmdftp.pid test -f $PID_file && kill $(cat $PID_file) echo "$$" > $PID_file sleep 5 case "$1" in stop) killall proftpd ;; start) killall proftpd ftp_start ;; restart) killall proftpd ftp_start ;; esac rm -f $PID_file