├── res
├── drawable-hdpi
│ ├── icon.png
│ ├── connect.png
│ ├── folder.png
│ ├── arrow_up.png
│ ├── up_level.png
│ ├── arrow_down.png
│ ├── disconnect.png
│ ├── dropdown.9.png
│ ├── empty_icon.png
│ ├── folder_fav.png
│ ├── ic_menu_sort.png
│ ├── legend_apk.png
│ ├── legend_music.png
│ ├── legend_other.png
│ ├── legend_theme.png
│ ├── legend_video.png
│ ├── legend_zip.png
│ ├── notification.png
│ ├── path_pane.9.png
│ ├── popup_bg.9.png
│ ├── sd_card_icon.png
│ ├── wifi_state0.png
│ ├── wifi_state4.png
│ ├── file_icon_mid.png
│ ├── file_icon_mp3.png
│ ├── file_icon_pdf.png
│ ├── file_icon_rar.png
│ ├── file_icon_txt.png
│ ├── file_icon_wav.png
│ ├── file_icon_wma.png
│ ├── file_icon_zip.png
│ ├── image_icon_bg.png
│ ├── ipaddress_bg.9.png
│ ├── legend_picture.png
│ ├── category_bar_apk.png
│ ├── category_bar_zip.png
│ ├── category_icon_apk.png
│ ├── category_icon_zip.png
│ ├── dropdown_normal.9.png
│ ├── file_icon_default.png
│ ├── file_icon_office.png
│ ├── file_icon_picture.png
│ ├── file_icon_theme.png
│ ├── file_icon_video.png
│ ├── ic_menu_refresh.png
│ ├── ic_menu_show_sys.png
│ ├── information_bg.9.png
│ ├── legend_document.png
│ ├── remote_button.9.png
│ ├── sd_not_available.png
│ ├── up_level_pressed.png
│ ├── btn_bottom_normal.9.png
│ ├── category_bar_empty.png
│ ├── category_bar_mask.9.png
│ ├── category_bar_music.png
│ ├── category_bar_other.png
│ ├── category_bar_theme.png
│ ├── category_bar_video.png
│ ├── category_icon_music.png
│ ├── category_icon_theme.png
│ ├── category_icon_video.png
│ ├── dropdown_icon_root.png
│ ├── dropdown_pressed.9.png
│ ├── ic_menu_new_folder.png
│ ├── ic_menu_select_all.png
│ ├── operation_bar_bg.9.png
│ ├── path_pane_pressed.9.png
│ ├── btn_bottom_pressed.9.png
│ ├── category_bar_document.png
│ ├── category_bar_picture.png
│ ├── category_icon_document.png
│ ├── category_icon_favorite.png
│ ├── category_icon_picture.png
│ ├── dropdown_icon_folder.png
│ ├── operation_button_copy.png
│ ├── operation_button_info.png
│ ├── operation_button_move.png
│ ├── operation_button_send.png
│ ├── sd_card_available_icon.png
│ ├── btn_bottom_last_normal.9.png
│ ├── btn_check_off_holo_light.png
│ ├── btn_check_on_holo_light.png
│ ├── ic_menu_delete_favorite.png
│ ├── operation_button_cancel.png
│ ├── operation_button_delete.png
│ ├── remote_button_pressed.9.png
│ ├── bottom_button_bar_normal.9.png
│ ├── bottom_button_bar_pressed.9.png
│ ├── btn_bottom_last_pressed.9.png
│ ├── category_button_bg_left.9.png
│ ├── category_button_bg_middle.9.png
│ ├── category_button_bg_right.9.png
│ ├── operation_button_info_gray.png
│ ├── operation_button_pressed.9.png
│ ├── operation_button_selectall.png
│ ├── stat_sys_install_complete.png
│ ├── category_button_bg_selected.9.png
│ └── secondary_title_background.9.png
├── drawable-land-hdpi
│ ├── category_bar_apk.png
│ ├── category_bar_zip.png
│ ├── information_bg.9.png
│ ├── category_bar_empty.png
│ ├── category_bar_mask.9.png
│ ├── category_bar_music.png
│ ├── category_bar_other.png
│ ├── category_bar_theme.png
│ ├── category_bar_video.png
│ ├── category_bar_document.png
│ ├── category_bar_picture.png
│ ├── category_button_bg_top.9.png
│ ├── category_button_bg_bottom.9.png
│ └── category_button_bg_selected.9.png
├── drawable
│ ├── operation_button_background.xml
│ ├── btn_bottom.xml
│ ├── btn_bottom_last.xml
│ ├── path_pane_bg.xml
│ ├── path_up_level.xml
│ ├── dropdown_item_bg.xml
│ ├── remote_button_bg.xml
│ ├── bottom_button_bar.xml
│ ├── category_button_left.xml
│ ├── category_button_right.xml
│ ├── category_button_top.xml
│ ├── category_button_bottom.xml
│ └── category_button_middle.xml
├── layout
│ ├── fragment_pager.xml
│ ├── textinput_dialog.xml
│ ├── dropdown_item.xml
│ ├── favorite_item.xml
│ ├── information_dialog.xml
│ ├── server_control_activity.xml
│ ├── file_browser_item.xml
│ └── category_file_browser_item.xml
├── xml
│ ├── searchable.xml
│ └── preferences.xml
├── values
│ └── color.xml
├── menu
│ └── operation_menu.xml
└── values-zh-rCN
│ └── strings.xml
├── libs
└── android-support-v13.jar
├── .gitignore
├── src
├── org
│ └── swiftp
│ │ ├── UiUpdateClient.java
│ │ ├── Account.java
│ │ ├── QuotaStats.java
│ │ ├── CmdAPPE.java
│ │ ├── CmdSTOR.java
│ │ ├── CmdNOOP.java
│ │ ├── CmdTemplate.java
│ │ ├── CmdQUIT.java
│ │ ├── CmdSYST.java
│ │ ├── CmdMap.java
│ │ ├── CmdFEAT.java
│ │ ├── CmdUSER.java
│ │ ├── ProxyDataSocketInfo.java
│ │ ├── UiUpdater.java
│ │ ├── CmdTYPE.java
│ │ ├── CmdSIZE.java
│ │ ├── CmdRNFR.java
│ │ ├── MyLog.java
│ │ ├── CmdDELE.java
│ │ ├── TcpListener.java
│ │ ├── CmdRNTO.java
│ │ ├── CmdMKD.java
│ │ ├── CmdCWD.java
│ │ ├── DataSocketFactory.java
│ │ ├── WifiStateReceiver.java
│ │ ├── CmdCDUP.java
│ │ ├── CmdOPTS.java
│ │ ├── Globals.java
│ │ ├── CmdPASV.java
│ │ ├── Settings.java
│ │ ├── CmdPWD.java
│ │ ├── CmdRMD.java
│ │ ├── CmdPORT.java
│ │ ├── CmdPASS.java
│ │ ├── CmdAbstractListing.java
│ │ ├── CmdNLST.java
│ │ ├── NormalDataSocketFactory.java
│ │ ├── ProxyDataSocketFactory.java
│ │ ├── Defaults.java
│ │ └── CmdRETR.java
└── net
│ └── micode
│ └── fileexplorer
│ ├── SearchActivity.java
│ ├── FavoriteItem.java
│ ├── FileInfo.java
│ ├── Settings.java
│ ├── FilenameOtherExtFilter.java
│ ├── GlobalConsts.java
│ ├── ActivitiesManager.java
│ ├── FilenameExtFilter.java
│ ├── IFileInteractionListener.java
│ ├── FileListAdapter.java
│ ├── TextInputDialog.java
│ ├── FavoriteListAdapter.java
│ ├── FileSortHelper.java
│ ├── FileListCursorAdapter.java
│ ├── FileExplorerPreferenceActivity.java
│ ├── FavoriteDatabaseHelper.java
│ ├── IntentBuilder.java
│ └── FileIconHelper.java
├── README
└── AndroidManifest.xml
/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/libs/android-support-v13.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/libs/android-support-v13.jar
--------------------------------------------------------------------------------
/res/drawable-hdpi/connect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/connect.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/folder.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/arrow_up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/arrow_up.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/up_level.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/up_level.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/arrow_down.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/disconnect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/disconnect.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/dropdown.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/dropdown.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/empty_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/empty_icon.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/folder_fav.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/folder_fav.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_menu_sort.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/ic_menu_sort.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/legend_apk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/legend_apk.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/legend_music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/legend_music.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/legend_other.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/legend_other.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/legend_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/legend_theme.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/legend_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/legend_video.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/legend_zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/legend_zip.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/notification.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/path_pane.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/path_pane.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/popup_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/popup_bg.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/sd_card_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/sd_card_icon.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/wifi_state0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/wifi_state0.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/wifi_state4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/wifi_state4.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_mid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_mid.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_mp3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_mp3.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_pdf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_pdf.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_rar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_rar.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_txt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_txt.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_wav.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_wav.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_wma.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_wma.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_zip.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/image_icon_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/image_icon_bg.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ipaddress_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/ipaddress_bg.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/legend_picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/legend_picture.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_apk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_apk.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_zip.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_icon_apk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_icon_apk.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_icon_zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_icon_zip.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/dropdown_normal.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/dropdown_normal.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_default.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_office.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_office.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_picture.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_theme.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/file_icon_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/file_icon_video.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_menu_refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/ic_menu_refresh.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_menu_show_sys.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/ic_menu_show_sys.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/information_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/information_bg.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/legend_document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/legend_document.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/remote_button.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/remote_button.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/sd_not_available.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/sd_not_available.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/up_level_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/up_level_pressed.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/btn_bottom_normal.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/btn_bottom_normal.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_empty.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_mask.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_mask.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_music.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_other.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_other.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_theme.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_video.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_icon_music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_icon_music.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_icon_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_icon_theme.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_icon_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_icon_video.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/dropdown_icon_root.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/dropdown_icon_root.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/dropdown_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/dropdown_pressed.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_menu_new_folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/ic_menu_new_folder.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_menu_select_all.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/ic_menu_select_all.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_bar_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_bar_bg.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/path_pane_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/path_pane_pressed.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/btn_bottom_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/btn_bottom_pressed.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_document.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_bar_picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_bar_picture.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_icon_document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_icon_document.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_icon_favorite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_icon_favorite.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_icon_picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_icon_picture.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/dropdown_icon_folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/dropdown_icon_folder.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_button_copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_button_copy.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_button_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_button_info.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_button_move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_button_move.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_button_send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_button_send.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/sd_card_available_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/sd_card_available_icon.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_apk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_apk.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_zip.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/information_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/information_bg.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/btn_bottom_last_normal.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/btn_bottom_last_normal.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/btn_check_off_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/btn_check_off_holo_light.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/btn_check_on_holo_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/btn_check_on_holo_light.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_menu_delete_favorite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/ic_menu_delete_favorite.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_button_cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_button_cancel.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_button_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_button_delete.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/remote_button_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/remote_button_pressed.9.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_empty.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_mask.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_mask.9.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_music.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_other.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_other.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_theme.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_video.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/bottom_button_bar_normal.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/bottom_button_bar_normal.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/bottom_button_bar_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/bottom_button_bar_pressed.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/btn_bottom_last_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/btn_bottom_last_pressed.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_button_bg_left.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_button_bg_left.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_button_bg_middle.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_button_bg_middle.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_button_bg_right.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_button_bg_right.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_button_info_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_button_info_gray.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_button_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_button_pressed.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/operation_button_selectall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/operation_button_selectall.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/stat_sys_install_complete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/stat_sys_install_complete.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_document.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_bar_picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_bar_picture.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/category_button_bg_selected.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/category_button_bg_selected.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/secondary_title_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-hdpi/secondary_title_background.9.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_button_bg_top.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_button_bg_top.9.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_button_bg_bottom.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_button_bg_bottom.9.png
--------------------------------------------------------------------------------
/res/drawable-land-hdpi/category_button_bg_selected.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MiCode/FileExplorer/HEAD/res/drawable-land-hdpi/category_button_bg_selected.9.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # generated files
2 | bin/
3 | gen/
4 |
5 | # Local configuration file (sdk path, etc)
6 | proguard.cfg
7 | project.properties
8 | .settings/
9 | .classpath
10 | .project
11 |
--------------------------------------------------------------------------------
/res/drawable/operation_button_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/res/drawable/btn_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/drawable/btn_bottom_last.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/drawable/path_pane_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/drawable/path_up_level.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/layout/fragment_pager.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/res/drawable/dropdown_item_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/drawable/remote_button_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/drawable/bottom_button_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/xml/searchable.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/res/drawable/category_button_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/res/drawable/category_button_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/res/drawable/category_button_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/res/drawable/category_button_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/res/drawable/category_button_middle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/res/layout/textinput_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
--------------------------------------------------------------------------------
/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #FFF000
6 | #A6A6A0
7 | #ff9900
8 | #faaa5f
9 | #333333
10 | #ABABAB
11 | #FF0000
12 | #272727
13 | #9b9ba0
14 |
15 | #80000000
16 |
17 | #FFe78018
18 | #FF901821
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/org/swiftp/UiUpdateClient.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | /*
21 | package org.swiftp;
22 |
23 |
24 | public interface UiUpdateClient {
25 | public void updateUi();
26 | }
27 | */
28 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | [中文]
2 |
3 | 1. 本项目是MIUI文件管理器的社区开源版,由MIUI团队(www.miui.com) 发起并贡献第一批代码,遵循NOTICE文件所描述的开源协议,
4 | 今后为MiCode社区(www.micode.net) 拥有,并由社区发布和维护。
5 |
6 | 2. Bug反馈和跟踪,请访问Github,
7 | https://github.com/MiCode/FileExplorer/issues?sort=created&direction=desc&state=open
8 |
9 | 3. 功能建议和综合讨论,请访问MiCode,
10 | http://micode.net/forum-51-1.html
11 |
12 |
13 | [English]
14 |
15 | 1. This is open source edition of MIUI File Explorer, it's first initiated and sponsored by MIUI team (www.miui.com).
16 | It's opened under license described by NOTICE file. It's owned by the MiCode community (www.micode.net). In future,
17 | the MiCode community will release and maintain this project.
18 |
19 | 2. Regarding issue tracking, please visit Github,
20 | https://github.com/MiCode/FileExplorer/issues?sort=created&direction=desc&state=open
21 |
22 | 3. Regarding feature request and general discussion, please visit Micode forum,
23 | http://micode.net/forum-51-1.html
24 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/SearchActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import android.app.Activity;
23 |
24 | public class SearchActivity extends Activity {
25 | }
26 |
--------------------------------------------------------------------------------
/res/xml/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
15 |
16 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/org/swiftp/Account.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | public class Account {
23 | protected String username = null;
24 |
25 | public String getUsername() {
26 | return username;
27 | }
28 |
29 | public void setUsername(String username) {
30 | this.username = username;
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/swiftp/QuotaStats.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | public class QuotaStats {
23 | private int quota;
24 | private int used;
25 |
26 | public QuotaStats(int used, int quota) {
27 | this.quota = quota;
28 | this.used = used;
29 | }
30 |
31 | public int getQuota() {
32 | return quota;
33 | }
34 | public int getUsed() {
35 | return used;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdAPPE.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 |
23 | public class CmdAPPE extends CmdAbstractStore implements Runnable {
24 | protected String input;
25 |
26 | public CmdAPPE(SessionThread sessionThread, String input) {
27 | super(sessionThread, CmdAPPE.class.toString());
28 | this.input = input;
29 | }
30 |
31 | public void run() {
32 | doStorOrAppe(getParameter(input), true);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdSTOR.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 |
23 | public class CmdSTOR extends CmdAbstractStore implements Runnable {
24 | protected String input;
25 |
26 | public CmdSTOR(SessionThread sessionThread, String input) {
27 | super(sessionThread, CmdSTOR.class.toString());
28 | this.input = input;
29 | }
30 |
31 | public void run() {
32 | doStorOrAppe(getParameter(input), false);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdNOOP.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 |
23 | public class CmdNOOP extends FtpCmd implements Runnable {
24 | public static final String message = "TEMPLATE!!";
25 |
26 | public CmdNOOP(SessionThread sessionThread, String input) {
27 | super(sessionThread, CmdNOOP.class.toString());
28 | }
29 |
30 | public void run() {
31 | sessionThread.writeString("200 NOOP ok\r\n");
32 | //myLog.l(Log.INFO, "Executing NOOP, done");
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdTemplate.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import android.util.Log;
23 |
24 | public class CmdTemplate extends FtpCmd implements Runnable {
25 | public static final String message = "TEMPLATE!!";
26 |
27 | public CmdTemplate(SessionThread sessionThread, String input) {
28 | super(sessionThread, CmdTemplate.class.toString());
29 | }
30 |
31 | public void run() {
32 | sessionThread.writeString(message);
33 | myLog.l(Log.INFO, "Template log message");
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdQUIT.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import android.util.Log;
23 |
24 | public class CmdQUIT extends FtpCmd implements Runnable {
25 | public static final String message = "TEMPLATE!!";
26 |
27 | public CmdQUIT(SessionThread sessionThread, String input) {
28 | super(sessionThread, CmdQUIT.class.toString());
29 | }
30 |
31 | public void run() {
32 | myLog.l(Log.DEBUG, "QUITting");
33 | sessionThread.writeString("221 Goodbye\r\n");
34 | sessionThread.closeSocket();
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/res/menu/operation_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdSYST.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import android.util.Log;
23 |
24 | public class CmdSYST extends FtpCmd implements Runnable {
25 | // This is considered a safe response to the SYST command, see
26 | // http://cr.yp.to/ftp/syst.html
27 | public static final String response = "215 UNIX Type: L8\r\n";
28 |
29 | public CmdSYST(SessionThread sessionThread, String input) {
30 | super(sessionThread, CmdSYST.class.toString());
31 | }
32 |
33 |
34 | public void run() {
35 | myLog.l(Log.DEBUG, "SYST executing");
36 | sessionThread.writeString(response);
37 | myLog.l(Log.DEBUG, "SYST finished");
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdMap.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | public class CmdMap {
23 | protected Class extends FtpCmd> cmdClass;
24 | String name;
25 |
26 |
27 | public CmdMap(String name, Class extends FtpCmd> cmdClass) {
28 | super();
29 | this.name = name;
30 | this.cmdClass = cmdClass;
31 | }
32 |
33 | public Class extends FtpCmd> getCommand() {
34 | return cmdClass;
35 | }
36 |
37 | public void setCommand(Class extends FtpCmd> cmdClass) {
38 | this.cmdClass = cmdClass;
39 | }
40 |
41 | public String getName() {
42 | return name;
43 | }
44 |
45 | public void setName(String name) {
46 | this.name = name;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/res/layout/dropdown_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
25 |
26 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FavoriteItem.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | public class FavoriteItem {
23 | // id in the database
24 | public long id;
25 |
26 | public String title;
27 |
28 | // path
29 | public String location;
30 |
31 | public FileInfo fileInfo;
32 |
33 | public FavoriteItem(String t, String l) {
34 | title = t;
35 | location = l;
36 | }
37 |
38 | public FavoriteItem(long i, String t, String l) {
39 | id = i;
40 | title = t;
41 | location = l;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FileInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | public class FileInfo {
23 |
24 | public String fileName;
25 |
26 | public String filePath;
27 |
28 | public long fileSize;
29 |
30 | public boolean IsDir;
31 |
32 | public int Count;
33 |
34 | public long ModifiedDate;
35 |
36 | public boolean Selected;
37 |
38 | public boolean canRead;
39 |
40 | public boolean canWrite;
41 |
42 | public boolean isHidden;
43 |
44 | public long dbId; // id in the database, if is from database
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdFEAT.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import android.util.Log;
23 |
24 | public class CmdFEAT extends FtpCmd implements Runnable {
25 | public static final String message = "TEMPLATE!!";
26 |
27 | public CmdFEAT(SessionThread sessionThread, String input) {
28 | super(sessionThread, CmdFEAT.class.toString());
29 | }
30 |
31 | public void run() {
32 | //sessionThread.writeString("211 No extended features\r\n");
33 | sessionThread.writeString("211-Features supported\r\n");
34 | sessionThread.writeString(" UTF8\r\n"); // advertise UTF8 support (fixes bug 14)
35 | sessionThread.writeString("211 End\r\n");
36 | myLog.l(Log.DEBUG, "Gave FEAT response");
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdUSER.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import android.util.Log;
23 |
24 | public class CmdUSER extends FtpCmd implements Runnable {
25 | protected String input;
26 |
27 | public CmdUSER(SessionThread sessionThread, String input) {
28 | super(sessionThread, CmdUSER.class.toString());
29 | this.input = input;
30 |
31 | }
32 |
33 | public void run() {
34 | myLog.l(Log.DEBUG, "USER executing");
35 | String username = FtpCmd.getParameter(input);
36 | if(!username.matches("[A-Za-z0-9]+")) {
37 | sessionThread.writeString("530 Invalid username\r\n");
38 | return;
39 | }
40 | sessionThread.writeString("331 Send password\r\n");
41 | sessionThread.account.setUsername(username);
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/org/swiftp/ProxyDataSocketInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.net.Socket;
23 |
24 | public class ProxyDataSocketInfo extends Socket {
25 | private int remotePublicPort;
26 | private Socket socket;
27 |
28 | public Socket getSocket() {
29 | return socket;
30 | }
31 |
32 | public void setSocket(Socket socket) {
33 | this.socket = socket;
34 | }
35 |
36 | public ProxyDataSocketInfo(Socket socket, int remotePublicPort) {
37 | this.remotePublicPort = remotePublicPort;
38 | this.socket = socket;
39 | }
40 |
41 | public int getRemotePublicPort() {
42 | return remotePublicPort;
43 | }
44 |
45 | public void setRemotePublicPort(int remotePublicPort) {
46 | this.remotePublicPort = remotePublicPort;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/Settings.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | public class Settings {
23 | // whether show system and cache images, default not
24 | private boolean mShowDotAndHiddenFiles;
25 | private static Settings mInstance;
26 |
27 | private Settings() {
28 |
29 | }
30 |
31 | public static Settings instance() {
32 | if(mInstance == null) {
33 | mInstance = new Settings();
34 | }
35 | return mInstance;
36 | }
37 |
38 | public boolean getShowDotAndHiddenFiles() {
39 | return mShowDotAndHiddenFiles;
40 | }
41 |
42 | public void setShowDotAndHiddenFiles(boolean s) {
43 | mShowDotAndHiddenFiles = s;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/org/swiftp/UiUpdater.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | import android.os.Handler;
26 |
27 | public class UiUpdater {
28 | protected static MyLog myLog = new MyLog("UiUpdater");
29 | protected static List clients = new ArrayList();
30 |
31 | public static void registerClient(Handler client) {
32 | if(!clients.contains(client)) {
33 | clients.add(client);
34 | }
35 | }
36 |
37 | public static void unregisterClient(Handler client) {
38 | while(clients.contains(client)) {
39 | clients.remove(client);
40 | }
41 | }
42 |
43 | public static void updateClients() {
44 | //myLog.l(Log.DEBUG, "UI update");
45 | //Log.d("UiUpdate", "Update now");
46 | for (Handler client : clients) {
47 | client.sendEmptyMessage(0);
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FilenameOtherExtFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import java.util.Arrays;
23 | import java.util.HashSet;
24 |
25 | public class FilenameOtherExtFilter extends FilenameExtFilter {
26 |
27 | private HashSet mExts;
28 |
29 | // using lower case
30 | public FilenameOtherExtFilter(FilenameExtFilter[] exts) {
31 | super(null);
32 | mExts = new HashSet();
33 | mExts.addAll(Arrays.asList(exts));
34 | }
35 |
36 | @Override
37 | public boolean contains(String ext) {
38 | for (FilenameExtFilter f : mExts) {
39 | if (f.contains(ext))
40 | return false;
41 | }
42 | return true;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdTYPE.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import android.util.Log;
23 |
24 | public class CmdTYPE extends FtpCmd implements Runnable {
25 | String input;
26 |
27 | public CmdTYPE(SessionThread sessionThread, String input) {
28 | super(sessionThread, CmdTYPE.class.toString());
29 | this.input = input;
30 | }
31 |
32 | public void run() {
33 | String output;
34 | myLog.l(Log.DEBUG, "TYPE executing");
35 | String param = getParameter(input);
36 | if(param.equals("I") || param.equals("L 8")) {
37 | output = "200 Binary type set\r\n";
38 | sessionThread.setBinaryMode(true);
39 | } else if (param.equals("A") || param.equals("A N")) {
40 | output = "200 ASCII type set\r\n";
41 | sessionThread.setBinaryMode(false);
42 | } else {
43 | output = "503 Malformed TYPE command\r\n";
44 | }
45 | sessionThread.writeString(output);
46 | myLog.l(Log.DEBUG, "TYPE complete");
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdSIZE.java:
--------------------------------------------------------------------------------
1 | package org.swiftp;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | public class CmdSIZE extends FtpCmd {
7 | protected String input;
8 |
9 | public CmdSIZE(SessionThread sessionThread, String input) {
10 | super(sessionThread, CmdSIZE.class.toString());
11 | this.input = input;
12 | }
13 |
14 | public void run() {
15 | myLog.d("SIZE executing");
16 |
17 | String errString = null;
18 | String param = getParameter(input);
19 | long size = 0;
20 | mainblock: {
21 | File currentDir = sessionThread.getWorkingDir();
22 | if(param.contains(File.separator)) {
23 | errString = "550 No directory traversal allowed in SIZE param\r\n";
24 | break mainblock;
25 | }
26 | File target = new File(currentDir, param);
27 |
28 | // We should have caught any invalid location access before now, but
29 | // here we check again, just to be explicitly sure.
30 | if(violatesChroot(target)) {
31 | errString = "550 SIZE target violates chroot\r\n";
32 | break mainblock;
33 | }
34 | if(!target.exists()) {
35 | errString = "550 Cannot get the SIZE of nonexistent object\r\n";
36 | try {
37 | myLog.i("Failed getting size of: " + target.getCanonicalPath());
38 | } catch (IOException e) {}
39 | break mainblock;
40 | }
41 | if(!target.isFile()) {
42 | errString = "550 Cannot get the size of a non-file\r\n";
43 | break mainblock;
44 | }
45 | size = target.length();
46 | }
47 | if(errString != null) {
48 | sessionThread.writeString(errString);
49 | } else {
50 | sessionThread.writeString("213 " + size + "\r\n");
51 | }
52 | myLog.d("SIZE complete");
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/GlobalConsts.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | public abstract class GlobalConsts {
23 | public static final String KEY_BASE_SD = "key_base_sd";
24 |
25 | public static final String KEY_SHOW_CATEGORY = "key_show_category";
26 |
27 | public static final String INTENT_EXTRA_TAB = "TAB";
28 |
29 | public static final String ROOT_PATH = "/";
30 |
31 | public static final String SDCARD_PATH = ROOT_PATH + "sdcard";
32 |
33 | // Menu id
34 | public static final int MENU_NEW_FOLDER = 100;
35 | public static final int MENU_FAVORITE = 101;
36 | public static final int MENU_COPY = 104;
37 | public static final int MENU_PASTE = 105;
38 | public static final int MENU_MOVE = 106;
39 | public static final int MENU_SHOWHIDE = 117;
40 | public static final int MENU_COPY_PATH = 118;
41 |
42 | public static final int OPERATION_UP_LEVEL = 3;
43 | }
44 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdRNFR.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 |
24 | import android.util.Log;
25 |
26 | public class CmdRNFR extends FtpCmd implements Runnable {
27 | protected String input;
28 |
29 | public CmdRNFR(SessionThread sessionThread, String input) {
30 | super(sessionThread, CmdRNFR.class.toString());
31 | this.input = input;
32 | }
33 |
34 | public void run() {
35 | String param = getParameter(input);
36 | String errString = null;
37 | File file = null;
38 | mainblock: {
39 | file = inputPathToChrootedFile(sessionThread.getWorkingDir(), param);
40 | if(violatesChroot(file)) {
41 | errString = "550 Invalid name or chroot violation\r\n";
42 | break mainblock;
43 | }
44 | if(!file.exists()) {
45 | errString = "450 Cannot rename nonexistent file\r\n";
46 | }
47 | }
48 | if(errString != null) {
49 | sessionThread.writeString(errString);
50 | myLog.l(Log.INFO, "RNFR failed: " + errString.trim());
51 | sessionThread.setRenameFrom(null);
52 | } else {
53 | sessionThread.writeString("350 Filename noted, now send RNTO\r\n");
54 | sessionThread.setRenameFrom(file);
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/org/swiftp/MyLog.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import net.micode.fileexplorer.FTPServerService;
23 |
24 | import android.util.Log;
25 |
26 | public class MyLog {
27 | protected String tag;
28 |
29 | public MyLog(String tag) {
30 | this.tag = tag;
31 | }
32 |
33 | public void l(int level, String str, boolean sysOnly) {
34 | synchronized (MyLog.class) {
35 | str = str.trim();
36 | // Messages of this severity are handled specially
37 | if(level == Log.ERROR || level == Log.WARN) {
38 | Globals.setLastError(str);
39 | }
40 | if(level >= Defaults.getConsoleLogLevel()) {
41 | Log.println(level,tag, str);
42 | }
43 | if(!sysOnly) { // some messages only go to the Android log
44 | if(level >= Defaults.getUiLogLevel()) {
45 | FTPServerService.log(level, str);
46 | }
47 | }
48 | }
49 | }
50 |
51 | public void l(int level, String str) {
52 | l(level, str, false);
53 | }
54 |
55 | public void e(String s) {
56 | l(Log.ERROR, s, false);
57 | }
58 | public void w(String s) {
59 | l(Log.WARN, s, false);
60 | }
61 | public void i(String s) {
62 | l(Log.INFO, s, false);
63 | }
64 | public void d(String s) {
65 | l(Log.DEBUG, s, false);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/ActivitiesManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import java.util.HashMap;
23 |
24 | import android.app.Activity;
25 |
26 | public class ActivitiesManager {
27 | public static final String ACTIVITY_FILE_VIEW = "FileView";
28 |
29 | public static final String ACTIVITY_FILE_CATEGORY = "FileCategory";
30 |
31 | public static final String ACTIVITY_TAB = "FileExplorerTab";
32 |
33 | private static ActivitiesManager instance;
34 |
35 | private HashMap activities = new HashMap();
36 |
37 | private ActivitiesManager() {
38 | }
39 |
40 | // return true indicates successful, false indicates the name exists
41 | public void registerActivity(String name, Activity a) {
42 | activities.put(name, a);
43 | }
44 |
45 | public Activity getActivity(String name) {
46 | return activities.get(name);
47 | }
48 |
49 | public static ActivitiesManager getInstance() {
50 | if (instance == null)
51 | instance = new ActivitiesManager();
52 | return instance;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdDELE.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 |
24 | import android.util.Log;
25 |
26 | public class CmdDELE extends FtpCmd implements Runnable {
27 | protected String input;
28 |
29 | public CmdDELE(SessionThread sessionThread, String input) {
30 | super(sessionThread, CmdDELE.class.toString());
31 | this.input = input;
32 | }
33 |
34 | public void run() {
35 | myLog.l(Log.INFO, "DELE executing");
36 | String param = getParameter(input);
37 | File storeFile = inputPathToChrootedFile(sessionThread.getWorkingDir(), param);
38 | String errString = null;
39 | if(violatesChroot(storeFile)) {
40 | errString = "550 Invalid name or chroot violation\r\n";
41 | } else if(storeFile.isDirectory()) {
42 | errString = "550 Can't DELE a directory\r\n";
43 | } else if(!storeFile.delete()) {
44 | errString = "450 Error deleting file\r\n";
45 | }
46 |
47 | if(errString != null) {
48 | sessionThread.writeString(errString);
49 | myLog.l(Log.INFO, "DELE failed: " + errString.trim());
50 | } else {
51 | sessionThread.writeString("250 File successfully deleted\r\n");
52 | Util.deletedFileNotify(storeFile.getPath());
53 | }
54 | myLog.l(Log.INFO, "DELE finished");
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FilenameExtFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import java.io.File;
23 | import java.io.FilenameFilter;
24 | import java.util.Arrays;
25 | import java.util.HashSet;
26 |
27 | public class FilenameExtFilter implements FilenameFilter {
28 |
29 | private HashSet mExts = new HashSet();
30 |
31 | // using lower case
32 | public FilenameExtFilter(String[] exts) {
33 | if (exts != null) {
34 | mExts.addAll(Arrays.asList(exts));
35 | }
36 | }
37 |
38 | public boolean contains(String ext) {
39 | return mExts.contains(ext.toLowerCase());
40 | }
41 |
42 | @Override
43 | public boolean accept(File dir, String filename) {
44 |
45 | File file = new File(dir + File.separator + filename);
46 | if (file.isDirectory()) {
47 | return true;
48 | }
49 |
50 | int dotPosition = filename.lastIndexOf('.');
51 | if (dotPosition != -1) {
52 | String ext = (String) filename.subSequence(dotPosition + 1, filename.length());
53 | return contains(ext.toLowerCase());
54 | }
55 |
56 | return false;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/org/swiftp/TcpListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import net.micode.fileexplorer.FTPServerService;
23 |
24 | import java.net.ServerSocket;
25 | import java.net.Socket;
26 |
27 | import android.util.Log;
28 |
29 | public class TcpListener extends Thread {
30 | ServerSocket listenSocket;
31 | FTPServerService ftpServerService;
32 | MyLog myLog = new MyLog(getClass().getName());
33 |
34 | public TcpListener(ServerSocket listenSocket, FTPServerService ftpServerService) {
35 | this.listenSocket = listenSocket;
36 | this.ftpServerService = ftpServerService;
37 | }
38 |
39 | public void quit() {
40 | try {
41 | listenSocket.close(); // if the TcpListener thread is blocked on accept,
42 | // closing the socket will raise an exception
43 | } catch (Exception e) {
44 | myLog.l(Log.DEBUG, "Exception closing TcpListener listenSocket");
45 | }
46 | }
47 |
48 | public void run() {
49 | try {
50 | while(true) {
51 |
52 | Socket clientSocket = listenSocket.accept();
53 | myLog.l(Log.INFO, "New connection, spawned thread");
54 | SessionThread newSession = new SessionThread(clientSocket,
55 | new NormalDataSocketFactory(),
56 | SessionThread.Source.LOCAL);
57 | newSession.start();
58 | ftpServerService.registerSessionThread(newSession);
59 | }
60 | } catch (Exception e) {
61 | myLog.l(Log.DEBUG, "Exception in TcpListener");
62 | }
63 | }
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdRNTO.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 |
24 | import android.util.Log;
25 |
26 | public class CmdRNTO extends FtpCmd implements Runnable {
27 | protected String input;
28 |
29 | public CmdRNTO(SessionThread sessionThread, String input) {
30 | super(sessionThread, CmdRNTO.class.toString());
31 | this.input = input;
32 | }
33 |
34 | public void run() {
35 | String param = getParameter(input);
36 | String errString = null;
37 | File toFile = null;
38 | myLog.l(Log.DEBUG, "RNTO executing\r\n");
39 | mainblock: {
40 | myLog.l(Log.INFO, "param: " + param);
41 | toFile = inputPathToChrootedFile(sessionThread.getWorkingDir(), param);
42 | myLog.l(Log.INFO, "RNTO parsed: " + toFile.getPath());
43 | if(violatesChroot(toFile)) {
44 | errString = "550 Invalid name or chroot violation\r\n";
45 | break mainblock;
46 | }
47 | File fromFile = sessionThread.getRenameFrom();
48 | if(fromFile == null) {
49 | errString = "550 Rename error, maybe RNFR not sent\r\n";
50 | break mainblock;
51 | }
52 | if(!fromFile.renameTo(toFile)) {
53 | errString = "550 Error during rename operation\r\n";
54 | break mainblock;
55 | }
56 | }
57 | if(errString != null) {
58 | sessionThread.writeString(errString);
59 | myLog.l(Log.INFO, "RNFR failed: " + errString.trim());
60 | } else {
61 | sessionThread.writeString("250 rename successful\r\n");
62 | }
63 | sessionThread.setRenameFrom(null);
64 | myLog.l(Log.DEBUG, "RNTO finished");
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdMKD.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 |
24 | import android.util.Log;
25 |
26 | public class CmdMKD extends FtpCmd implements Runnable {
27 | String input;
28 |
29 | public CmdMKD(SessionThread sessionThread, String input) {
30 | super(sessionThread, CmdMKD.class.toString());
31 | this.input = input;
32 | }
33 |
34 | public void run() {
35 | myLog.l(Log.DEBUG, "MKD executing");
36 | String param = getParameter(input);
37 | File toCreate;
38 | String errString = null;
39 | mainblock: {
40 | // If the param is an absolute path, use it as is. If it's a
41 | // relative path, prepend the current working directory.
42 | if(param.length() < 1) {
43 | errString = "550 Invalid name\r\n";
44 | break mainblock;
45 | }
46 | toCreate = inputPathToChrootedFile(sessionThread.getWorkingDir(), param);
47 | if(violatesChroot(toCreate)) {
48 | errString = "550 Invalid name or chroot violation\r\n";
49 | break mainblock;
50 | }
51 | if(toCreate.exists()) {
52 | errString = "550 Already exists\r\n";
53 | break mainblock;
54 | }
55 | if(!toCreate.mkdir()) {
56 | errString = "550 Error making directory (permissions?)\r\n";
57 | break mainblock;
58 | }
59 | }
60 | if(errString != null) {
61 | sessionThread.writeString(errString);
62 | myLog.l(Log.INFO, "MKD error: " + errString.trim());
63 | } else {
64 | sessionThread.writeString("250 Directory created\r\n");
65 | }
66 | myLog.l(Log.INFO, "MKD complete");
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdCWD.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 | import java.io.IOException;
24 |
25 | import android.util.Log;
26 |
27 | public class CmdCWD extends FtpCmd implements Runnable {
28 | protected String input;
29 |
30 | public CmdCWD(SessionThread sessionThread, String input) {
31 | super(sessionThread, CmdCWD.class.toString());
32 | this.input = input;
33 | }
34 |
35 | public void run() {
36 | myLog.l(Log.DEBUG, "CWD executing");
37 | String param = getParameter(input);
38 | File newDir;
39 | String errString = null;
40 | mainblock: {
41 | newDir = inputPathToChrootedFile(sessionThread.getWorkingDir(), param);
42 |
43 | // Ensure the new path does not violate the chroot restriction
44 | if(violatesChroot(newDir)) {
45 | errString = "550 Invalid name or chroot violation\r\n";
46 | sessionThread.writeString(errString);
47 | myLog.l(Log.INFO, errString);
48 | break mainblock;
49 | }
50 |
51 | try {
52 | newDir = newDir.getCanonicalFile();
53 | if(!newDir.isDirectory()) {
54 | sessionThread.writeString("550 Can't CWD to invalid directory\r\n");
55 | } else if(newDir.canRead()) {
56 | sessionThread.setWorkingDir(newDir);
57 | sessionThread.writeString("250 CWD successful\r\n");
58 | } else {
59 | sessionThread.writeString("550 That path is inaccessible\r\n");
60 | }
61 | } catch(IOException e) {
62 | sessionThread.writeString("550 Invalid path\r\n");
63 | break mainblock;
64 | }
65 | }
66 | myLog.l(Log.DEBUG, "CWD complete");
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/IFileInteractionListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import android.content.Context;
23 | import android.content.Intent;
24 | import android.view.View;
25 |
26 | import java.util.Collection;
27 |
28 | public interface IFileInteractionListener {
29 |
30 | public View getViewById(int id);
31 |
32 | public Context getContext();
33 |
34 | public void startActivity(Intent intent);
35 |
36 | public void onDataChanged();
37 |
38 | public void onPick(FileInfo f);
39 |
40 | public boolean shouldShowOperationPane();
41 |
42 | /**
43 | * Handle operation listener.
44 | * @param id
45 | * @return true: indicate have operated it; false: otherwise.
46 | */
47 | public boolean onOperation(int id);
48 |
49 | public String getDisplayPath(String path);
50 |
51 | public String getRealPath(String displayPath);
52 |
53 | public void runOnUiThread(Runnable r);
54 |
55 | // return true indicates the navigation has been handled
56 | public boolean onNavigation(String path);
57 |
58 | public boolean shouldHideMenu(int menu);
59 |
60 | public FileIconHelper getFileIconHelper();
61 |
62 | public FileInfo getItem(int pos);
63 |
64 | public void sortCurrentList(FileSortHelper sort);
65 |
66 | public Collection getAllFiles();
67 |
68 | public void addSingleFile(FileInfo file);
69 |
70 | public boolean onRefreshFileList(String path, FileSortHelper sort);
71 |
72 | public int getItemCount();
73 | }
74 |
--------------------------------------------------------------------------------
/src/org/swiftp/DataSocketFactory.java:
--------------------------------------------------------------------------------
1 | package org.swiftp;
2 |
3 | import java.net.InetAddress;
4 | import java.net.Socket;
5 |
6 |
7 | abstract public class DataSocketFactory {
8 |
9 | /**
10 | * A DataSocketFactory hides the implementation of the opening and closing
11 | * of the data sockets which are used to transmit directory listings and
12 | * file contents. This is necessary because normal FTP data sockets are
13 | * opened and closed very differently from the abnormal sort of data sockets
14 | * we use in conjunction with our proxy system.
15 | */
16 | protected MyLog myLog = new MyLog(getClass().getName());
17 |
18 | /**
19 | * When SwiFTP receives a PORT command, this will be called. Subclasses should
20 | * perform whatever initialization is necessary.
21 | * @return Whether the necessary actions completed successfully
22 | */
23 | abstract public boolean onPort(InetAddress dest, int port);
24 |
25 | /**
26 | * When SwiFTP receives a PASV command, this will be called. Subclasses should
27 | * perform whatever initialization is necessary.
28 | * @return Whether the necessary actions completed successfully
29 | */
30 | abstract public int onPasv();
31 |
32 | /**
33 | * When it's time for data transfer to begin, the SessionThread will call this
34 | * method to perform any necessary actions to prepare the Socket for use and
35 | * return it in a state that's ready for reading or writing.
36 | * @return The opened Socket
37 | */
38 | abstract public Socket onTransfer();
39 |
40 | /**
41 | * Sometimes we'll need to know the IP address at which we can be contacted. For
42 | * instance, the response to a PASV command will be the IP and port that the
43 | * client should use to connect it's data socket.
44 | */
45 | abstract public InetAddress getPasvIp();
46 |
47 | /**
48 | * We sometimes want to track the total number of bytes that go over the
49 | * command and data sockets. The SessionThread can call this function to
50 | * reports its usage, and different DataSocketFactory subclasses can
51 | * handle the data however is appropriate. For the ProxyDataSocketFactory,
52 | * we want to present the total to the user in the UI to guilt them into
53 | * donating.
54 | * @param numBytes the number of bytes to add to the total
55 | */
56 | abstract public void reportTraffic(long numBytes);
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/org/swiftp/WifiStateReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | /*package org.swiftp;
21 |
22 | import android.content.BroadcastReceiver;
23 | import android.content.Context;
24 | import android.content.Intent;
25 | import android.content.SharedPreferences;
26 | import android.net.NetworkInfo;
27 | import android.net.NetworkInfo.State;
28 | import android.net.wifi.WifiManager;
29 | import android.util.Log;
30 |
31 | public class WifiStateReceiver extends BroadcastReceiver {
32 |
33 | @Override
34 | public void onReceive(Context context, Intent wifiIntent) {
35 | MyLog myLog = new MyLog(this.getClass().getName());
36 | myLog.l(Log.DEBUG, "WifiStateReceiver running!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
37 | SharedPreferences settings;
38 | if(context == null) {
39 | myLog.l(Log.INFO, "Null context in WifiStateReceiver");
40 | return;
41 | }
42 | settings = context.getSharedPreferences(Defaults.getSettingsName(),
43 | Defaults.getSettingsMode());
44 | if(wifiIntent.getAction() == WifiManager.NETWORK_STATE_CHANGED_ACTION) {
45 | NetworkInfo netInfo;
46 | netInfo = (NetworkInfo)wifiIntent.getParcelableExtra(
47 | WifiManager.EXTRA_NETWORK_INFO);
48 | Intent intent = new Intent(context, FTPServerService.class);
49 | if(netInfo.getState() == State.CONNECTED) {
50 | myLog.l(Log.DEBUG, "Wifi up");
51 | if(settings.getBoolean("autostart", false) == true) {
52 | myLog.l(Log.INFO, "Autostart on, starting server");
53 | context.startService(intent);
54 | }
55 | } else {
56 | // Wifi is connecting or shutting down, but not up
57 | myLog.l(Log.INFO, "Stopping service due to unconnected wifi");
58 | context.stopService(intent);
59 | }
60 | }
61 | }
62 |
63 | }
64 | */
--------------------------------------------------------------------------------
/src/org/swiftp/CmdCDUP.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 | import java.io.IOException;
24 |
25 | import android.util.Log;
26 |
27 | public class CmdCDUP extends FtpCmd implements Runnable {
28 | protected String input;
29 |
30 | public CmdCDUP(SessionThread sessionThread, String input) {
31 | super(sessionThread, CmdCDUP.class.toString());
32 | }
33 |
34 | public void run() {
35 | myLog.l(Log.DEBUG, "CDUP executing");
36 | File newDir;
37 | String errString = null;
38 | mainBlock: {
39 | File workingDir = sessionThread.getWorkingDir();
40 | newDir = workingDir.getParentFile();
41 | if(newDir == null) {
42 | errString = "550 Current dir cannot find parent\r\n";
43 | break mainBlock;
44 | }
45 | // Ensure the new path does not violate the chroot restriction
46 | if(violatesChroot(newDir)) {
47 | errString = "550 Invalid name or chroot violation\r\n";
48 | break mainBlock;
49 | }
50 |
51 | try {
52 | newDir = newDir.getCanonicalFile();
53 | if(!newDir.isDirectory()) {
54 | errString = "550 Can't CWD to invalid directory\r\n";
55 | break mainBlock;
56 | } else if(newDir.canRead()) {
57 | sessionThread.setWorkingDir(newDir);
58 | } else {
59 | errString = "550 That path is inaccessible\r\n";
60 | break mainBlock;
61 | }
62 | } catch(IOException e) {
63 | errString = "550 Invalid path\r\n";
64 | break mainBlock;
65 | }
66 | }
67 | if(errString != null) {
68 | sessionThread.writeString(errString);
69 | myLog.i("CDUP error: " + errString);
70 | } else {
71 | sessionThread.writeString("200 CDUP successful\r\n");
72 | myLog.l(Log.DEBUG, "CDUP success");
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdOPTS.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 |
23 | public class CmdOPTS extends FtpCmd implements Runnable {
24 | public static final String message = "TEMPLATE!!";
25 | private String input;
26 |
27 | public CmdOPTS(SessionThread sessionThread, String input) {
28 | super(sessionThread, CmdOPTS.class.toString());
29 | this.input = input;
30 | }
31 |
32 | public void run() {
33 | String param = getParameter(input);
34 | String errString = null;
35 |
36 | mainBlock: {
37 | if(param == null) {
38 | errString = "550 Need argument to OPTS\r\n";
39 | myLog.w("Couldn't understand empty OPTS command");
40 | break mainBlock;
41 | }
42 | String[] splits = param.split(" ");
43 | if(splits.length != 2) {
44 | errString = "550 Malformed OPTS command\r\n";
45 | myLog.w("Couldn't parse OPTS command");
46 | break mainBlock;
47 | }
48 | String optName = splits[0].toUpperCase();
49 | String optVal = splits[1].toUpperCase();
50 | if(optName.equals("UTF8")) {
51 | // OK, whatever. Don't really know what to do here. We
52 | // always operate in UTF8 mode.
53 | if(optVal.equals("ON")) {
54 | myLog.d("Got OPTS UTF8 ON");
55 | sessionThread.setEncoding("UTF-8");
56 | } else {
57 | myLog.i("Ignoring OPTS UTF8 for something besides ON");
58 | }
59 | break mainBlock;
60 | } else {
61 | myLog.d("Unrecognized OPTS option: " + optName);
62 | errString = "502 Unrecognized option\r\n";
63 | break mainBlock;
64 | }
65 | }
66 | if(errString != null) {
67 | sessionThread.writeString(errString);
68 | myLog.i("Template log message");
69 | } else {
70 | sessionThread.writeString("200 OPTS accepted\r\n");
71 | myLog.d("Handled OPTS ok");
72 | }
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/org/swiftp/Globals.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 |
24 | import android.content.Context;
25 |
26 | public class Globals {
27 | private static Context context;
28 | private static String lastError;
29 | private static File chrootDir = new File(Defaults.chrootDir);
30 | private static ProxyConnector proxyConnector = null;
31 | private static String username = null;
32 |
33 | public static ProxyConnector getProxyConnector() {
34 | if(proxyConnector != null) {
35 | if(!proxyConnector.isAlive()) {
36 | return null;
37 | }
38 | }
39 | return proxyConnector;
40 | }
41 |
42 | public static void setProxyConnector(ProxyConnector proxyConnector) {
43 | Globals.proxyConnector = proxyConnector;
44 | }
45 |
46 | public static File getChrootDir() {
47 | return chrootDir;
48 | }
49 |
50 | public static void setChrootDir(File chrootDir) {
51 | if(chrootDir.isDirectory()) {
52 | Globals.chrootDir = chrootDir;
53 | }
54 | }
55 |
56 | public static String getLastError() {
57 | return lastError;
58 | }
59 |
60 | public static void setLastError(String lastError) {
61 | Globals.lastError = lastError;
62 | }
63 |
64 | public static Context getContext() {
65 | return context;
66 | }
67 |
68 | public static void setContext(Context context) {
69 | if(context != null) {
70 | Globals.context = context;
71 | }
72 | }
73 |
74 | public static String getUsername() {
75 | return username;
76 | }
77 |
78 | public static void setUsername(String username) {
79 | Globals.username = username;
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdPASV.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.net.InetAddress;
23 |
24 | import android.util.Log;
25 |
26 | public class CmdPASV extends FtpCmd implements Runnable {
27 | //public static final String message = "TEMPLATE!!";
28 |
29 | public CmdPASV(SessionThread sessionThread, String input) {
30 | super(sessionThread, CmdPASV.class.toString());
31 | }
32 |
33 | public void run() {
34 | String cantOpen = "502 Couldn't open a port\r\n";
35 | myLog.l(Log.DEBUG, "PASV running");
36 | int port;
37 | if((port = sessionThread.onPasv()) == 0) {
38 | // There was a problem opening a port
39 | myLog.l(Log.ERROR, "Couldn't open a port for PASV");
40 | sessionThread.writeString(cantOpen);
41 | return;
42 | }
43 | InetAddress addr = sessionThread.getDataSocketPasvIp();
44 |
45 | if(addr == null) {
46 | myLog.l(Log.ERROR, "PASV IP string invalid");
47 | sessionThread.writeString(cantOpen);
48 | return;
49 | }
50 | myLog.d("PASV sending IP: " + addr.getHostAddress());
51 | if(port < 1) {
52 | myLog.l(Log.ERROR, "PASV port number invalid");
53 | sessionThread.writeString(cantOpen);
54 | return;
55 | }
56 | StringBuilder response = new StringBuilder(
57 | "227 Entering Passive Mode (");
58 | // Output our IP address in the format xxx,xxx,xxx,xxx
59 | response.append(addr.getHostAddress().replace('.', ','));
60 | response.append(",");
61 |
62 | // Output our port in the format p1,p2 where port=p1*256+p2
63 | response.append(port / 256);
64 | response.append(",");
65 | response.append(port % 256);
66 | response.append(").\r\n");
67 | String responseString = response.toString();
68 | sessionThread.writeString(responseString);
69 | myLog.l(Log.DEBUG, "PASV completed, sent: " + responseString);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/org/swiftp/Settings.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import android.util.Log;
23 |
24 | public class Settings {
25 | protected static int inputBufferSize = 256;
26 | protected static boolean allowOverwrite = false;
27 | protected static int dataChunkSize = 8192; // do file I/O in 8k chunks
28 | protected static int sessionMonitorScrollBack = 10;
29 | protected static int serverLogScrollBack = 10;
30 | protected static int uiLogLevel = Log.INFO;
31 |
32 | public static int getUiLogLevel() {
33 | return uiLogLevel;
34 | }
35 |
36 | public static void setUiLogLevel(int uiLogLevel) {
37 | Settings.uiLogLevel = uiLogLevel;
38 | }
39 |
40 | public static int getInputBufferSize() {
41 | return inputBufferSize;
42 | }
43 |
44 | public static void setInputBufferSize(int inputBufferSize) {
45 | Settings.inputBufferSize = inputBufferSize;
46 | }
47 |
48 | public static boolean isAllowOverwrite() {
49 | return allowOverwrite;
50 | }
51 |
52 | public static void setAllowOverwrite(boolean allowOverwrite) {
53 | Settings.allowOverwrite = allowOverwrite;
54 | }
55 |
56 | public static int getDataChunkSize() {
57 | return dataChunkSize;
58 | }
59 |
60 | public static void setDataChunkSize(int dataChunkSize) {
61 | Settings.dataChunkSize = dataChunkSize;
62 | }
63 |
64 | public static int getSessionMonitorScrollBack() {
65 | return sessionMonitorScrollBack;
66 | }
67 |
68 | public static void setSessionMonitorScrollBack(
69 | int sessionMonitorScrollBack)
70 | {
71 | Settings.sessionMonitorScrollBack = sessionMonitorScrollBack;
72 | }
73 |
74 | public static int getServerLogScrollBack() {
75 | return serverLogScrollBack;
76 | }
77 |
78 | public static void setLogScrollBack(int serverLogScrollBack) {
79 | Settings.serverLogScrollBack = serverLogScrollBack;
80 | }
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdPWD.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 | import java.io.IOException;
24 |
25 | import android.util.Log;
26 |
27 | public class CmdPWD extends FtpCmd implements Runnable {
28 | // public static final String message = "TEMPLATE!!";
29 |
30 | public CmdPWD(SessionThread sessionThread, String input) {
31 | super(sessionThread, CmdPWD.class.toString());
32 | }
33 |
34 | public void run() {
35 | myLog.l(Log.DEBUG, "PWD executing");
36 |
37 | // We assume that the chroot restriction has been applied, and that
38 | // therefore the current directory is located somewhere within the
39 | // chroot directory. Therefore, we can just slice of the chroot
40 | // part of the current directory path in order to get the
41 | // user-visible path (inside the chroot directory).
42 | try {
43 | File workingDir = sessionThread.getWorkingDir();
44 | String currentDir = workingDir != null ? workingDir.getCanonicalPath() : Globals.getChrootDir()
45 | .getCanonicalPath();
46 | currentDir = currentDir.substring(Globals.getChrootDir().getCanonicalPath().length());
47 | // The root directory requires special handling to restore its
48 | // leading slash
49 | if (currentDir.length() == 0) {
50 | currentDir = "/";
51 | }
52 | sessionThread.writeString("257 \"" + currentDir + "\"\r\n");
53 | } catch (IOException e) {
54 | // This shouldn't happen unless our input validation has failed
55 | myLog.l(Log.ERROR, "PWD canonicalize");
56 | sessionThread.closeSocket(); // should cause thread termination
57 | }
58 | myLog.l(Log.DEBUG, "PWD complete");
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FileListAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import android.content.Context;
23 | import android.view.LayoutInflater;
24 | import android.view.View;
25 | import android.view.ViewGroup;
26 | import android.widget.ArrayAdapter;
27 |
28 | import java.util.List;
29 |
30 | public class FileListAdapter extends ArrayAdapter {
31 | private LayoutInflater mInflater;
32 |
33 | private FileViewInteractionHub mFileViewInteractionHub;
34 |
35 | private FileIconHelper mFileIcon;
36 |
37 | private Context mContext;
38 |
39 | public FileListAdapter(Context context, int resource,
40 | List objects, FileViewInteractionHub f,
41 | FileIconHelper fileIcon) {
42 | super(context, resource, objects);
43 | mInflater = LayoutInflater.from(context);
44 | mFileViewInteractionHub = f;
45 | mFileIcon = fileIcon;
46 | mContext = context;
47 | }
48 |
49 | @Override
50 | public View getView(int position, View convertView, ViewGroup parent) {
51 | View view = null;
52 | if (convertView != null) {
53 | view = convertView;
54 | } else {
55 | view = mInflater.inflate(R.layout.file_browser_item, parent, false);
56 | }
57 |
58 | FileInfo lFileInfo = mFileViewInteractionHub.getItem(position);
59 | FileListItem.setupFileListItemInfo(mContext, view, lFileInfo,
60 | mFileIcon, mFileViewInteractionHub);
61 | view.findViewById(R.id.file_checkbox_area).setOnClickListener(
62 | new FileListItem.FileItemOnClickListener(mContext,
63 | mFileViewInteractionHub));
64 | return view;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/res/layout/favorite_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
25 |
32 |
33 |
41 |
42 |
48 |
49 |
53 |
60 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdRMD.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 |
24 | import android.util.Log;
25 |
26 | public class CmdRMD extends FtpCmd implements Runnable {
27 | public static final String message = "TEMPLATE!!";
28 | protected String input;
29 |
30 | public CmdRMD(SessionThread sessionThread, String input) {
31 | super(sessionThread, CmdRMD.class.toString());
32 | this.input = input;
33 | }
34 |
35 | public void run() {
36 | myLog.l(Log.INFO, "RMD executing");
37 | String param = getParameter(input);
38 | File toRemove;
39 | String errString = null;
40 | mainblock: {
41 | if(param.length() < 1) {
42 | errString = "550 Invalid argument\r\n";
43 | break mainblock;
44 | }
45 | toRemove = inputPathToChrootedFile(sessionThread.getWorkingDir(), param);
46 | if(violatesChroot(toRemove)) {
47 | errString = "550 Invalid name or chroot violation\r\n";
48 | break mainblock;
49 | }
50 | if(!toRemove.isDirectory()) {
51 | errString = "550 Can't RMD a non-directory\r\n";
52 | break mainblock;
53 | }
54 | if(toRemove.equals(new File("/"))) {
55 | errString = "550 Won't RMD the root directory\r\n";
56 | break mainblock;
57 | }
58 | if(!recursiveDelete(toRemove)) {
59 | errString = "550 Deletion error, possibly incomplete\r\n";
60 | break mainblock;
61 | }
62 | }
63 | if(errString != null) {
64 | sessionThread.writeString(errString);
65 | myLog.l(Log.INFO, "RMD failed: " + errString.trim());
66 | } else {
67 | sessionThread.writeString("250 Removed directory\r\n");
68 | }
69 | myLog.l(Log.DEBUG, "RMD finished");
70 | }
71 |
72 | /**
73 | * Accepts a file or directory name, and recursively deletes the contents
74 | * of that directory and all subdirectories.
75 | * @param toDelete
76 | * @return Whether the operation completed successfully
77 | */
78 | protected boolean recursiveDelete(File toDelete) {
79 | if(!toDelete.exists()) {
80 | return false;
81 | }
82 | if(toDelete.isDirectory()) {
83 | // If any of the recursive operations fail, then we return false
84 | boolean success = true;
85 | for(File entry : toDelete.listFiles()) {
86 | success &= recursiveDelete(entry);
87 | }
88 | myLog.l(Log.DEBUG, "Recursively deleted: " + toDelete);
89 | return success && toDelete.delete();
90 | } else {
91 | myLog.l(Log.DEBUG, "RMD deleting file: " + toDelete);
92 | return toDelete.delete();
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/TextInputDialog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import android.app.AlertDialog;
23 | import android.content.Context;
24 | import android.content.DialogInterface;
25 | import android.os.Bundle;
26 | import android.view.View;
27 | import android.widget.EditText;
28 |
29 | public class TextInputDialog extends AlertDialog {
30 | private String mInputText;
31 | private String mTitle;
32 | private String mMsg;
33 | private OnFinishListener mListener;
34 | private Context mContext;
35 | private View mView;
36 | private EditText mFolderName;
37 |
38 | public interface OnFinishListener {
39 | // return true to accept and dismiss, false reject
40 | boolean onFinish(String text);
41 | }
42 |
43 | public TextInputDialog(Context context, String title, String msg, String text, OnFinishListener listener) {
44 | super(context);
45 | mTitle = title;
46 | mMsg = msg;
47 | mListener = listener;
48 | mInputText = text;
49 | mContext = context;
50 | }
51 |
52 | public String getInputText() {
53 | return mInputText;
54 | }
55 |
56 | protected void onCreate(Bundle savedInstanceState) {
57 | mView = getLayoutInflater().inflate(R.layout.textinput_dialog, null);
58 |
59 | setTitle(mTitle);
60 | setMessage(mMsg);
61 |
62 | mFolderName = (EditText) mView.findViewById(R.id.text);
63 | mFolderName.setText(mInputText);
64 |
65 | setView(mView);
66 | setButton(BUTTON_POSITIVE, mContext.getString(android.R.string.ok),
67 | new DialogInterface.OnClickListener() {
68 | @Override
69 | public void onClick(DialogInterface dialog, int which) {
70 | if (which == BUTTON_POSITIVE) {
71 | mInputText = mFolderName.getText().toString();
72 | if (mListener.onFinish(mInputText)) {
73 | dismiss();
74 | }
75 | }
76 | }
77 | });
78 | setButton(BUTTON_NEGATIVE, mContext.getString(android.R.string.cancel),
79 | (DialogInterface.OnClickListener) null);
80 |
81 | super.onCreate(savedInstanceState);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdPORT.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.net.InetAddress;
23 | import java.net.UnknownHostException;
24 |
25 | import android.util.Log;
26 |
27 | public class CmdPORT extends FtpCmd implements Runnable {
28 | //public static final String message = "TEMPLATE!!";
29 | String input;
30 |
31 | public CmdPORT(SessionThread sessionThread, String input) {
32 | super(sessionThread, CmdPORT.class.toString());
33 | this.input = input;
34 | }
35 |
36 | public void run() {
37 | myLog.l(Log.DEBUG, "PORT running");
38 | String errString = null;
39 | mainBlock: {
40 | String param = getParameter(input);
41 | if(param.contains("|") && param.contains("::")) {
42 | errString = "550 No IPv6 support, reconfigure your client\r\n";
43 | break mainBlock;
44 | }
45 | String[] substrs = param.split(",");
46 | if(substrs.length != 6) {
47 | errString = "550 Malformed PORT argument\r\n";
48 | break mainBlock;
49 | }
50 | for(int i=0; i 3)
54 | {
55 | errString = "550 Invalid PORT argument: " + substrs[i] +
56 | "\r\n";
57 | break mainBlock;
58 | }
59 | }
60 | byte[] ipBytes = new byte[4];
61 | for(int i=0; i<4; i++) {
62 | try {
63 | // We have to manually convert unsigned to signed
64 | // byte representation.
65 | int ipByteAsInt = Integer.parseInt(substrs[i]);
66 | if(ipByteAsInt >= 128) {
67 | ipByteAsInt -= 256;
68 | }
69 | ipBytes[i] = (byte)ipByteAsInt;
70 | } catch (Exception e) {
71 | errString = "550 Invalid PORT format: "
72 | + substrs[i] + "\r\n";
73 | break mainBlock;
74 | }
75 | }
76 | InetAddress inetAddr;
77 | try {
78 | inetAddr = InetAddress.getByAddress(ipBytes);
79 | } catch (UnknownHostException e) {
80 | errString = "550 Unknown host\r\n";
81 | break mainBlock;
82 | }
83 |
84 | int port = Integer.parseInt(substrs[4]) * 256 +
85 | Integer.parseInt(substrs[5]);
86 |
87 | sessionThread.onPort(inetAddr, port);
88 | }
89 | if(errString == null) {
90 | sessionThread.writeString("200 PORT OK\r\n");
91 | myLog.l(Log.DEBUG, "PORT completed");
92 | } else {
93 | myLog.l(Log.INFO, "PORT error: " + errString);
94 | sessionThread.writeString(errString);
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdPASS.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import android.content.Context;
23 | import android.content.SharedPreferences;
24 | import android.util.Log;
25 |
26 | public class CmdPASS extends FtpCmd implements Runnable {
27 | String input;
28 |
29 | public CmdPASS(SessionThread sessionThread, String input) {
30 | // We can just discard the password for now. We're just
31 | // following the expected dialogue, we're going to allow
32 | // access in any case.
33 | super(sessionThread, CmdPASS.class.toString());
34 | this.input = input;
35 | }
36 |
37 | public void run() {
38 | // User must have already executed a USER command to
39 | // populate the Account object's username
40 | myLog.l(Log.DEBUG, "Executing PASS");
41 |
42 | sessionThread.writeString("230 Access granted\r\n");
43 | sessionThread.authAttempt(true);
44 | //
45 | // String attemptPassword = getParameter(input, true); // silent
46 | // String attemptUsername = sessionThread.account.getUsername();
47 | // if(attemptUsername == null) {
48 | // sessionThread.writeString("503 Must send USER first\r\n");
49 | // return;
50 | // }
51 | // Context ctx = Globals.getContext();
52 | // if(ctx == null) {
53 | // // This will probably never happen, since the global
54 | // // context is configured by the Service
55 | // myLog.l(Log.ERROR, "No global context in PASS\r\n");
56 | // }
57 | // String password;
58 | // String username;
59 | // SharedPreferences settings = ctx.getSharedPreferences(
60 | // Defaults.getSettingsName(), Defaults.getSettingsMode());
61 | // username = settings.getString("username", null);
62 | // password = settings.getString("password", null);
63 | // if(username == null || password == null) {
64 | // myLog.l(Log.ERROR, "Username or password misconfigured");
65 | // sessionThread.writeString("500 Internal error during authentication");
66 | // } else if(username.equals(attemptUsername) &&
67 | // password.equals(attemptPassword)) {
68 | // sessionThread.writeString("230 Access granted\r\n");
69 | // myLog.l(Log.INFO, "User " + username + " password verified");
70 | // sessionThread.authAttempt(true);
71 | // } else {
72 | // try {
73 | // // If the login failed, sleep for one second to foil
74 | // // brute force attacks
75 | // Thread.sleep(1000);
76 | // } catch(InterruptedException e) {}
77 | // myLog.l(Log.INFO, "Failed authentication");
78 | // sessionThread.writeString("530 Login incorrect.\r\n");
79 | // sessionThread.authAttempt(false);
80 | // }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FavoriteListAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import java.util.List;
23 |
24 | import android.content.Context;
25 | import android.view.LayoutInflater;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 | import android.widget.ArrayAdapter;
29 | import android.widget.ImageView;
30 |
31 | public class FavoriteListAdapter extends ArrayAdapter {
32 | private Context mContext;
33 |
34 | private LayoutInflater mInflater;
35 |
36 | private FileIconHelper mFileIcon;
37 |
38 | public FavoriteListAdapter(Context context, int resource, List objects, FileIconHelper fileIcon) {
39 | super(context, resource, objects);
40 | mContext = context;
41 | mInflater = LayoutInflater.from(context);
42 | mFileIcon = fileIcon;
43 | }
44 |
45 | @Override
46 | public View getView(int position, View convertView, ViewGroup parent) {
47 | View view = null;
48 | if (convertView != null) {
49 | view = convertView;
50 | } else {
51 | view = mInflater.inflate(R.layout.favorite_item, parent, false);
52 | }
53 |
54 | FavoriteItem item = getItem(position);
55 | FileInfo lFileInfo = item.fileInfo;
56 |
57 | Util.setText(view, R.id.file_name, item.title != null ? item.title : lFileInfo.fileName);
58 | if (lFileInfo.ModifiedDate > 0) {
59 | Util.setText(view, R.id.modified_time, Util.formatDateString(mContext, lFileInfo.ModifiedDate));
60 | view.findViewById(R.id.modified_time).setVisibility(View.VISIBLE);
61 | } else {
62 | view.findViewById(R.id.modified_time).setVisibility(View.GONE);
63 | }
64 | view.findViewById(R.id.modified_time).setVisibility(lFileInfo.ModifiedDate > 0 ? View.VISIBLE: View.GONE);
65 | if (lFileInfo.IsDir) {
66 | view.findViewById(R.id.file_size).setVisibility(View.GONE);
67 | } else {
68 | view.findViewById(R.id.file_size).setVisibility(View.VISIBLE);
69 | Util.setText(view, R.id.file_size, Util.convertStorage(lFileInfo.fileSize));
70 | }
71 |
72 | ImageView lFileImage = (ImageView) view.findViewById(R.id.file_image);
73 | ImageView lFileImageFrame = (ImageView) view.findViewById(R.id.file_image_frame);
74 | lFileImage.setTag(position);
75 |
76 | if (lFileInfo.IsDir) {
77 | lFileImageFrame.setVisibility(View.GONE);
78 | lFileImage.setImageResource(R.drawable.folder_fav);
79 | } else {
80 | mFileIcon.setIcon(lFileInfo, lFileImage, lFileImageFrame);
81 | }
82 |
83 | return view;
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/res/layout/information_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
11 |
17 |
21 |
22 |
23 |
29 |
33 |
34 |
35 |
41 |
45 |
46 |
47 |
53 |
57 |
58 |
59 |
65 |
69 |
70 |
71 |
77 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdAbstractListing.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | /*
21 | * Since the FTP verbs LIST and NLST do very similar things related to listing
22 | * directory contents, the common tasks that they share have been factored
23 | * out into this abstract class. Both CmdLIST and CmdNLST inherit from this
24 | * class.
25 | */
26 |
27 | package org.swiftp;
28 |
29 | import java.io.File;
30 |
31 | import android.util.Log;
32 |
33 | public abstract class CmdAbstractListing extends FtpCmd {
34 | protected static MyLog staticLog = new MyLog(CmdLIST.class.toString());
35 |
36 | public CmdAbstractListing(SessionThread sessionThread, String input) {
37 | super(sessionThread, CmdAbstractListing.class.toString());
38 | }
39 |
40 | abstract String makeLsString(File file);
41 |
42 | // Creates a directory listing by finding the contents of the directory,
43 | // calling makeLsString on each file, and concatenating the results.
44 | // Returns an error string if failure, returns null on success. May be
45 | // called by CmdLIST or CmdNLST, since they each override makeLsString
46 | // in a different way.
47 | public String listDirectory(StringBuilder response, File dir) {
48 | if(!dir.isDirectory()) {
49 | return "500 Internal error, listDirectory on non-directory\r\n";
50 | }
51 | myLog.l(Log.DEBUG, "Listing directory: " + dir.toString());
52 |
53 | // Get a listing of all files and directories in the path
54 | File[] entries = dir.listFiles();
55 | if(entries == null) {
56 | return "500 Couldn't list directory. Check config and mount status.\r\n";
57 | }
58 | myLog.l(Log.DEBUG, "Dir len " + entries.length);
59 | for(File entry : entries) {
60 | String curLine = makeLsString(entry);
61 | if(curLine != null) {
62 | response.append(curLine);
63 | }
64 | }
65 | return null;
66 | }
67 |
68 | // Send the directory listing over the data socket. Used by CmdLIST and
69 | // CmdNLST.
70 | // Returns an error string on failure, or returns null if successful.
71 | protected String sendListing(String listing) {
72 | if(sessionThread.startUsingDataSocket()) {
73 | myLog.l(Log.DEBUG, "LIST/NLST done making socket");
74 | } else {
75 | sessionThread.closeDataSocket();
76 | return "425 Error opening data socket\r\n";
77 | }
78 | String mode = sessionThread.isBinaryMode() ? "BINARY" : "ASCII";
79 | sessionThread.writeString(
80 | "150 Opening "+mode+" mode data connection for file list\r\n");
81 | myLog.l(Log.DEBUG, "Sent code 150, sending listing string now");
82 | if(!sessionThread.sendViaDataSocket(listing)) {
83 | myLog.l(Log.DEBUG, "sendViaDataSocket failure");
84 | sessionThread.closeDataSocket();
85 | return "426 Data socket or network error\r\n";
86 | }
87 | sessionThread.closeDataSocket();
88 | myLog.l(Log.DEBUG, "Listing sendViaDataSocket success");
89 | sessionThread.writeString("226 Data transmission OK\r\n");
90 | return null;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/res/layout/server_control_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
14 |
21 |
30 |
36 |
37 |
42 |
50 |
57 |
58 |
73 |
74 |
83 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FileSortHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import java.util.Comparator;
23 | import java.util.HashMap;
24 |
25 | public class FileSortHelper {
26 |
27 | public enum SortMethod {
28 | name, size, date, type
29 | }
30 |
31 | private SortMethod mSort;
32 |
33 | private boolean mFileFirst;
34 |
35 | private HashMap mComparatorList = new HashMap();
36 |
37 | public FileSortHelper() {
38 | mSort = SortMethod.name;
39 | mComparatorList.put(SortMethod.name, cmpName);
40 | mComparatorList.put(SortMethod.size, cmpSize);
41 | mComparatorList.put(SortMethod.date, cmpDate);
42 | mComparatorList.put(SortMethod.type, cmpType);
43 | }
44 |
45 | public void setSortMethog(SortMethod s) {
46 | mSort = s;
47 | }
48 |
49 | public SortMethod getSortMethod() {
50 | return mSort;
51 | }
52 |
53 | public void setFileFirst(boolean f) {
54 | mFileFirst = f;
55 | }
56 |
57 | public Comparator getComparator() {
58 | return mComparatorList.get(mSort);
59 | }
60 |
61 | private abstract class FileComparator implements Comparator {
62 |
63 | @Override
64 | public int compare(FileInfo object1, FileInfo object2) {
65 | if (object1.IsDir == object2.IsDir) {
66 | return doCompare(object1, object2);
67 | }
68 |
69 | if (mFileFirst) {
70 | // the files are listed before the dirs
71 | return (object1.IsDir ? 1 : -1);
72 | } else {
73 | // the dir-s are listed before the files
74 | return object1.IsDir ? -1 : 1;
75 | }
76 | }
77 |
78 | protected abstract int doCompare(FileInfo object1, FileInfo object2);
79 | }
80 |
81 | private Comparator cmpName = new FileComparator() {
82 | @Override
83 | public int doCompare(FileInfo object1, FileInfo object2) {
84 | return object1.fileName.compareToIgnoreCase(object2.fileName);
85 | }
86 | };
87 |
88 | private Comparator cmpSize = new FileComparator() {
89 | @Override
90 | public int doCompare(FileInfo object1, FileInfo object2) {
91 | return longToCompareInt(object1.fileSize - object2.fileSize);
92 | }
93 | };
94 |
95 | private Comparator cmpDate = new FileComparator() {
96 | @Override
97 | public int doCompare(FileInfo object1, FileInfo object2) {
98 | return longToCompareInt(object2.ModifiedDate - object1.ModifiedDate);
99 | }
100 | };
101 |
102 | private int longToCompareInt(long result) {
103 | return result > 0 ? 1 : (result < 0 ? -1 : 0);
104 | }
105 |
106 | private Comparator cmpType = new FileComparator() {
107 | @Override
108 | public int doCompare(FileInfo object1, FileInfo object2) {
109 | int result = Util.getExtFromFilename(object1.fileName).compareToIgnoreCase(
110 | Util.getExtFromFilename(object2.fileName));
111 | if (result != 0)
112 | return result;
113 |
114 | return Util.getNameFromFilename(object1.fileName).compareToIgnoreCase(
115 | Util.getNameFromFilename(object2.fileName));
116 | }
117 | };
118 | }
119 |
--------------------------------------------------------------------------------
/res/layout/file_browser_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
25 |
32 |
33 |
41 |
42 |
46 |
47 |
53 |
60 |
61 |
62 |
63 |
67 |
74 |
82 |
83 |
84 |
85 |
86 |
93 |
94 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/res/layout/category_file_browser_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
25 |
32 |
33 |
41 |
42 |
46 |
47 |
53 |
60 |
61 |
62 |
63 |
67 |
74 |
82 |
83 |
84 |
85 |
86 |
93 |
94 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
42 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
82 |
83 |
84 |
89 |
90 |
91 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdNLST.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | /* The code that is common to LIST and NLST is implemented in the abstract
21 | * class CmdAbstractListing, which is inherited here.
22 | * CmdLIST and CmdNLST just override the
23 | * makeLsString() function in different ways to provide the different forms
24 | * of output.
25 | */
26 |
27 | package org.swiftp;
28 |
29 | import java.io.File;
30 |
31 | import android.util.Log;
32 |
33 | public class CmdNLST extends CmdAbstractListing implements Runnable {
34 | // The approximate number of milliseconds in 6 months
35 | public final static long MS_IN_SIX_MONTHS = 6 * 30 * 24 * 60 * 60 * 1000;
36 | private String input;
37 |
38 |
39 | public CmdNLST(SessionThread sessionThread, String input) {
40 | super(sessionThread, input);
41 | this.input = input;
42 | }
43 |
44 | public void run() {
45 | String errString = null;
46 |
47 | mainblock: {
48 | String param = getParameter(input);
49 | if(param.startsWith("-")) {
50 | // Ignore options to list, which start with a dash
51 | param = "";
52 | }
53 | File fileToList = null;
54 | if(param.equals("")) {
55 | fileToList = sessionThread.getWorkingDir();
56 | } else {
57 | if(param.contains("*")) {
58 | errString = "550 NLST does not support wildcards\r\n";
59 | break mainblock;
60 | }
61 | fileToList = new File(sessionThread.getWorkingDir(), param);
62 | if(violatesChroot(fileToList)) {
63 | errString = "450 Listing target violates chroot\r\n";
64 | break mainblock;
65 | } else if(fileToList.isFile()) {
66 | // Bernstein suggests that NLST should fail when a
67 | // parameter is given and the parameter names a regular
68 | // file (not a directory).
69 | errString = "550 NLST for regular files is unsupported\r\n";
70 | break mainblock;
71 | }
72 | }
73 | String listing;
74 | if(fileToList.isDirectory()) {
75 | StringBuilder response = new StringBuilder();
76 | errString = listDirectory(response, fileToList);
77 | if(errString != null) {
78 | break mainblock;
79 | }
80 | listing = response.toString();
81 | } else {
82 | listing = makeLsString(fileToList);
83 | if(listing == null) {
84 | errString = "450 Couldn't list that file\r\n";
85 | break mainblock;
86 | }
87 | }
88 | errString = sendListing(listing);
89 | if(errString != null) {
90 | break mainblock;
91 | }
92 | }
93 |
94 | if(errString != null) {
95 | sessionThread.writeString(errString);
96 | myLog.l(Log.DEBUG, "NLST failed with: " + errString);
97 | } else {
98 | myLog.l(Log.DEBUG, "NLST completed OK");
99 | }
100 | // The success or error response over the control connection will
101 | // have already been handled by sendListing, so we can just quit now.
102 | }
103 |
104 | protected String makeLsString(File file) {
105 | if(!file.exists()) {
106 | staticLog.l(Log.INFO, "makeLsString had nonexistent file");
107 | return null;
108 | }
109 |
110 | // See Daniel Bernstein's explanation of NLST format at:
111 | // http://cr.yp.to/ftp/list/binls.html
112 | // This stuff is almost entirely based on his recommendations.
113 |
114 | String lastNamePart = file.getName();
115 | // Many clients can't handle files containing these symbols
116 | if(lastNamePart.contains("*") ||
117 | lastNamePart.contains("/"))
118 | {
119 | staticLog.l(Log.INFO, "Filename omitted due to disallowed character");
120 | return null;
121 | } else {
122 | staticLog.l(Log.DEBUG, "Filename: " + lastNamePart );
123 | return lastNamePart + "\r\n";
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/org/swiftp/NormalDataSocketFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import net.micode.fileexplorer.FTPServerService;
23 |
24 | import java.io.IOException;
25 | import java.net.InetAddress;
26 | import java.net.ServerSocket;
27 | import java.net.Socket;
28 |
29 | import android.util.Log;
30 |
31 | public class NormalDataSocketFactory extends DataSocketFactory {
32 | /**
33 | * This class implements normal, traditional opening and closing of data sockets
34 | * used for transmitting directory listings and file contents. PORT and PASV
35 | * work according to the FTP specs. This is in contrast to a
36 | * ProxyDataSocketFactory, which performs contortions to allow data sockets
37 | * to be proxied through a server out in the cloud.
38 | *
39 | */
40 |
41 | // Listener socket used for PASV mode
42 | ServerSocket server = null;
43 | // Remote IP & port information used for PORT mode
44 | InetAddress remoteAddr;
45 | int remotePort;
46 | boolean isPasvMode = true;
47 |
48 | public NormalDataSocketFactory() {
49 | clearState();
50 | }
51 |
52 |
53 | private void clearState() {
54 | /**
55 | * Clears the state of this object, as if no pasv() or port() had occurred.
56 | * All sockets are closed.
57 | */
58 | if(server != null) {
59 | try {
60 | server.close();
61 | } catch (IOException e) {}
62 | }
63 | server = null;
64 | remoteAddr = null;
65 | remotePort = 0;
66 | myLog.l(Log.DEBUG, "NormalDataSocketFactory state cleared");
67 | }
68 |
69 | public int onPasv() {
70 | clearState();
71 | try {
72 | // Listen on any port (port parameter 0)
73 | server = new ServerSocket(0, Defaults.tcpConnectionBacklog);
74 | myLog.l(Log.DEBUG, "Data socket pasv() listen successful");
75 | return server.getLocalPort();
76 | } catch(IOException e) {
77 | myLog.l(Log.ERROR, "Data socket creation error");
78 | clearState();
79 | return 0;
80 | }
81 | }
82 |
83 | public boolean onPort(InetAddress remoteAddr, int remotePort) {
84 | clearState();
85 | this.remoteAddr = remoteAddr;
86 | this.remotePort = remotePort;
87 | return true;
88 | }
89 |
90 | public Socket onTransfer() {
91 | if(server == null) {
92 | // We're in PORT mode (not PASV)
93 | if(remoteAddr == null || remotePort == 0) {
94 | myLog.l(Log.INFO, "PORT mode but not initialized correctly");
95 | clearState();
96 | return null;
97 | }
98 | Socket socket;
99 | try {
100 | socket = new Socket(remoteAddr, remotePort);
101 | } catch (IOException e) {
102 | myLog.l(Log.INFO,
103 | "Couldn't open PORT data socket to: " +
104 | remoteAddr.toString() + ":" + remotePort);
105 | clearState();
106 | return null;
107 | }
108 |
109 | // Kill the socket if nothing happens for X milliseconds
110 | try {
111 | socket.setSoTimeout(Defaults.SO_TIMEOUT_MS);
112 | } catch (Exception e) {
113 | myLog.l(Log.ERROR, "Couldn't set SO_TIMEOUT");
114 | clearState();
115 | return null;
116 | }
117 |
118 | return socket;
119 | } else {
120 | // We're in PASV mode (not PORT)
121 | Socket socket = null;
122 | try {
123 | socket = server.accept();
124 | myLog.l(Log.DEBUG, "onTransfer pasv accept successful");
125 | } catch (Exception e) {
126 | myLog.l(Log.INFO, "Exception accepting PASV socket");
127 | socket = null;
128 | }
129 | clearState();
130 | return socket; // will be null if error occurred
131 | }
132 | }
133 |
134 | /**
135 | * Return the port number that the remote client should be informed of (in the body
136 | * of the PASV response).
137 | * @return The port number, or -1 if error.
138 | */
139 | public int getPortNumber() {
140 | if(server != null) {
141 | return server.getLocalPort(); // returns -1 if serversocket is unbound
142 | } else {
143 | return -1;
144 | }
145 | }
146 |
147 | public InetAddress getPasvIp() {
148 | //String retVal = server.getInetAddress().getHostAddress();
149 | return FTPServerService.getWifiIp();
150 | }
151 |
152 | public void reportTraffic(long bytes) {
153 | // ignore, we don't care about how much traffic goes over wifi.
154 | }
155 | }
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FileListCursorAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import android.content.Context;
23 | import android.database.Cursor;
24 | import android.view.LayoutInflater;
25 | import android.view.View;
26 | import android.view.ViewGroup;
27 | import android.widget.CursorAdapter;
28 |
29 | import java.util.Collection;
30 | import java.util.HashMap;
31 |
32 | public class FileListCursorAdapter extends CursorAdapter {
33 |
34 | private final LayoutInflater mFactory;
35 |
36 | private FileViewInteractionHub mFileViewInteractionHub;
37 |
38 | private FileIconHelper mFileIcon;
39 |
40 | private HashMap mFileNameList = new HashMap();
41 |
42 | private Context mContext;
43 |
44 | public FileListCursorAdapter(Context context, Cursor cursor,
45 | FileViewInteractionHub f, FileIconHelper fileIcon) {
46 | super(context, cursor, false /* auto-requery */);
47 | mFactory = LayoutInflater.from(context);
48 | mFileViewInteractionHub = f;
49 | mFileIcon = fileIcon;
50 | mContext = context;
51 | }
52 |
53 | @Override
54 | public void bindView(View view, Context context, Cursor cursor) {
55 | FileInfo fileInfo = getFileItem(cursor.getPosition());
56 | if (fileInfo == null) {
57 | // file is not existing, create a fake info
58 | fileInfo = new FileInfo();
59 | fileInfo.dbId = cursor.getLong(FileCategoryHelper.COLUMN_ID);
60 | fileInfo.filePath = cursor.getString(FileCategoryHelper.COLUMN_PATH);
61 | fileInfo.fileName = Util.getNameFromFilepath(fileInfo.filePath);
62 | fileInfo.fileSize = cursor.getLong(FileCategoryHelper.COLUMN_SIZE);
63 | fileInfo.ModifiedDate = cursor.getLong(FileCategoryHelper.COLUMN_DATE);
64 | }
65 | FileListItem.setupFileListItemInfo(mContext, view, fileInfo, mFileIcon,
66 | mFileViewInteractionHub);
67 | view.findViewById(R.id.category_file_checkbox_area).setOnClickListener(
68 | new FileListItem.FileItemOnClickListener(mContext, mFileViewInteractionHub));
69 | }
70 |
71 | @Override
72 | public View newView(Context context, Cursor cursor, ViewGroup parent) {
73 | return mFactory.inflate(R.layout.category_file_browser_item, parent, false);
74 | }
75 |
76 | @Override
77 | public void changeCursor(Cursor cursor) {
78 | mFileNameList.clear();
79 | super.changeCursor(cursor);
80 | }
81 |
82 | public Collection getAllFiles() {
83 | if (mFileNameList.size() == getCount())
84 | return mFileNameList.values();
85 |
86 | Cursor cursor = getCursor();
87 | if (cursor.moveToFirst()) {
88 | do {
89 | Integer position = Integer.valueOf(cursor.getPosition());
90 | if (mFileNameList.containsKey(position))
91 | continue;
92 | FileInfo fileInfo = getFileInfo(cursor);
93 | if (fileInfo != null) {
94 | mFileNameList.put(position, fileInfo);
95 | }
96 | } while (cursor.moveToNext());
97 | }
98 |
99 | return mFileNameList.values();
100 | }
101 |
102 | public FileInfo getFileItem(int pos) {
103 | Integer position = Integer.valueOf(pos);
104 | if (mFileNameList.containsKey(position))
105 | return mFileNameList.get(position);
106 |
107 | Cursor cursor = (Cursor) getItem(pos);
108 | FileInfo fileInfo = getFileInfo(cursor);
109 | if (fileInfo == null)
110 | return null;
111 |
112 | fileInfo.dbId = cursor.getLong(FileCategoryHelper.COLUMN_ID);
113 | mFileNameList.put(position, fileInfo);
114 | return fileInfo;
115 | }
116 |
117 | private FileInfo getFileInfo(Cursor cursor) {
118 | return (cursor == null || cursor.getCount() == 0) ? null : Util
119 | .GetFileInfo(cursor.getString(FileCategoryHelper.COLUMN_PATH));
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FileExplorerPreferenceActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import java.io.File;
23 |
24 | import android.content.Context;
25 | import android.content.SharedPreferences;
26 | import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
27 | import android.os.Bundle;
28 | import android.preference.EditTextPreference;
29 | import android.preference.PreferenceActivity;
30 | import android.preference.PreferenceManager;
31 | import android.text.TextUtils;
32 |
33 | /**
34 | *
35 | * @author ShunLi
36 | */
37 | public class FileExplorerPreferenceActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
38 | private static final String PRIMARY_FOLDER = "pref_key_primary_folder";
39 | private static final String READ_ROOT = "pref_key_read_root";
40 | private static final String SHOW_REAL_PATH = "pref_key_show_real_path";
41 | private static final String SYSTEM_SEPARATOR = File.separator;
42 |
43 | private EditTextPreference mEditTextPreference;
44 |
45 | @Override
46 | protected void onCreate(Bundle savedInstanceState) {
47 | super.onCreate(savedInstanceState);
48 | addPreferencesFromResource(R.xml.preferences);
49 |
50 | mEditTextPreference = (EditTextPreference) findPreference(PRIMARY_FOLDER);
51 | }
52 |
53 | @Override
54 | protected void onResume() {
55 | super.onResume();
56 |
57 | // Setup the initial values
58 | SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
59 |
60 | mEditTextPreference.setSummary(this.getString(
61 | R.string.pref_primary_folder_summary,
62 | sharedPreferences.getString(PRIMARY_FOLDER, GlobalConsts.ROOT_PATH)));
63 |
64 | // Set up a listener whenever a key changes
65 | sharedPreferences.registerOnSharedPreferenceChangeListener(this);
66 | }
67 |
68 | @Override
69 | protected void onPause() {
70 | super.onPause();
71 |
72 | // Unregister the listener whenever a key changes
73 | getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
74 | }
75 |
76 | @Override
77 | public void onSharedPreferenceChanged(SharedPreferences sharedpreferences, String key) {
78 | if (PRIMARY_FOLDER.equals(key)) {
79 | mEditTextPreference.setSummary(this.getString(
80 | R.string.pref_primary_folder_summary,
81 | sharedpreferences.getString(PRIMARY_FOLDER, GlobalConsts.ROOT_PATH)));
82 | }
83 | }
84 |
85 | public static String getPrimaryFolder(Context context) {
86 | SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
87 | String primaryFolder = settings.getString(PRIMARY_FOLDER, context.getString(R.string.default_primary_folder, GlobalConsts.ROOT_PATH));
88 |
89 | if (TextUtils.isEmpty(primaryFolder)) { // setting primary folder = empty("")
90 | primaryFolder = GlobalConsts.ROOT_PATH;
91 | }
92 |
93 | // it's remove the end char of the home folder setting when it with the '/' at the end.
94 | // if has the backslash at end of the home folder, it's has minor bug at "UpLevel" function.
95 | int length = primaryFolder.length();
96 | if (length > 1 && SYSTEM_SEPARATOR.equals(primaryFolder.substring(length - 1))) { // length = 1, ROOT_PATH
97 | return primaryFolder.substring(0, length - 1);
98 | } else {
99 | return primaryFolder;
100 | }
101 | }
102 |
103 | public static boolean isReadRoot(Context context) {
104 | SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
105 |
106 | boolean isReadRootFromSetting = settings.getBoolean(READ_ROOT, false);
107 | boolean isReadRootWhenSettingPrimaryFolderWithoutSdCardPrefix = !getPrimaryFolder(context).startsWith(Util.getSdDirectory());
108 |
109 | return isReadRootFromSetting || isReadRootWhenSettingPrimaryFolderWithoutSdCardPrefix;
110 | }
111 |
112 | public static boolean showRealPath(Context context) {
113 | SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
114 | return settings.getBoolean(SHOW_REAL_PATH, false);
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/src/org/swiftp/ProxyDataSocketFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.net.InetAddress;
23 | import java.net.Socket;
24 |
25 | import android.util.Log;
26 |
27 | /**
28 | * @author david
29 | *
30 | */
31 | public class ProxyDataSocketFactory extends DataSocketFactory {
32 | /**
33 | * Implements data socket connections that go through our proxy server
34 | * out on the net. The proxy sits between the FTP client and us, the server.
35 | * We have to build in some coordination between the server and proxy in order
36 | * for data sockets to be handled properly.
37 | *
38 | * When we receive a "PASV" command from a client, we have to request that the
39 | * proxy server open a port, accept a connection, and proxy all data on that
40 | * socket between ourself and the FTP client.
41 | *
42 | * When we receive a PORT command, we store the client's connection info,
43 | * and when it's time to being transferring data, we request that the proxy
44 | * make a connection to the client's IP & port and then proxy all data between
45 | * ourself and the FTP client.
46 | */
47 |
48 | private Socket socket;
49 | private int proxyListenPort;
50 | ProxyConnector proxyConnector;
51 | InetAddress clientAddress;
52 | int clientPort;
53 |
54 | public ProxyDataSocketFactory() {
55 | clearState();
56 | }
57 |
58 | private void clearState() {
59 | if(socket != null) {
60 | try {
61 | socket.close();
62 | } catch (Exception e) {}
63 | }
64 | socket = null;
65 | proxyConnector = null;
66 | clientAddress = null;
67 | proxyListenPort = 0;
68 | clientPort = 0;
69 | }
70 |
71 | public InetAddress getPasvIp() {
72 | ProxyConnector pc = Globals.getProxyConnector();
73 | if(pc == null) {
74 | return null;
75 | }
76 | return pc.getProxyIp();
77 | }
78 |
79 | // public int getPortNumber() {
80 | // if(socket == )
81 | // return 0;
82 | // }
83 |
84 | public int onPasv() {
85 | clearState();
86 | proxyConnector = Globals.getProxyConnector();
87 | if(proxyConnector == null) {
88 | myLog.l(Log.INFO, "Unexpected null proxyConnector in onPasv");
89 | clearState();
90 | return 0;
91 | }
92 | ProxyDataSocketInfo info = proxyConnector.pasvListen();
93 | if(info == null) {
94 | myLog.l(Log.INFO, "Null ProxyDataSocketInfo");
95 | clearState();
96 | return 0;
97 | }
98 | socket = info.getSocket();
99 | proxyListenPort = info.getRemotePublicPort();
100 | return proxyListenPort;
101 | }
102 |
103 | public boolean onPort(InetAddress dest, int port) {
104 | clearState();
105 | proxyConnector = Globals.getProxyConnector();
106 | this.clientAddress = dest;
107 | this.clientPort = port;
108 | myLog.d("ProxyDataSocketFactory client port settings stored");
109 | return true;
110 | }
111 |
112 | /**
113 | * When the it's time for the SessionThread to actually begin PASV
114 | * data transfer with the client, it will call this function to get
115 | * a valid socket. The socket will have been created earlier with
116 | * a call to onPasv(). The result of calling onTransfer() will be
117 | * to cause the proxy to accept the incoming connection from the FTP
118 | * client and start proxying back to us (the FTP server). The socket
119 | * can then be handed back to the SessionThread which can use it as
120 | * if it were directly connected to the client.
121 | */
122 | public Socket onTransfer() {
123 | if(proxyConnector == null) {
124 | myLog.w("Unexpected null proxyConnector in onTransfer");
125 | return null;
126 | }
127 |
128 | if(socket == null) {
129 | // We are in PORT mode (not PASV mode)
130 | if(proxyConnector == null) {
131 | myLog.l(Log.INFO, "Unexpected null proxyConnector in onTransfer");
132 | return null;
133 | }
134 | // May return null, that's fine. ProxyConnector will log errors.
135 | socket = proxyConnector.dataPortConnect(clientAddress, clientPort);
136 | return socket;
137 | } else {
138 | // We are in PASV mode (not PORT mode)
139 | if(proxyConnector.pasvAccept(socket)) {
140 | return socket;
141 | } else {
142 | myLog.w("proxyConnector pasvAccept failed");
143 | return null;
144 | }
145 | }
146 | }
147 |
148 | public void reportTraffic(long bytes) {
149 | ProxyConnector pc = Globals.getProxyConnector();
150 | if(pc == null) {
151 | myLog.d("Can't report traffic, null ProxyConnector");
152 | } else {
153 | pc.incrementProxyUsage(bytes);
154 | }
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/org/swiftp/Defaults.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import android.content.Context;
23 | import android.util.Log;
24 |
25 | public class Defaults {
26 | protected static int inputBufferSize = 256;
27 | protected static int dataChunkSize = 65536; // do file I/O in 64k chunks
28 | protected static int sessionMonitorScrollBack = 10;
29 | protected static int serverLogScrollBack = 10;
30 | protected static int uiLogLevel = Defaults.release ? Log.INFO : Log.DEBUG;
31 | protected static int consoleLogLevel = Defaults.release ? Log.INFO : Log.DEBUG;
32 | protected static String settingsName = "SwiFTP";
33 | //protected static String username = "user";
34 | //protected static String password = "";
35 | public static int portNumber = 2121;
36 | // protected static int ipRetrievalAttempts = 5;
37 | public static final int tcpConnectionBacklog = 5;
38 | public static final String chrootDir = net.micode.fileexplorer.Util.getSdDirectory();
39 | public static final boolean acceptWifi = true;
40 | public static final boolean acceptNet = false; // don't incur bandwidth charges
41 | public static final boolean stayAwake = false;
42 | public static final int REMOTE_PROXY_PORT = 2222;
43 | public static final String STRING_ENCODING = "UTF-8";
44 | public static final int SO_TIMEOUT_MS = 30000; // socket timeout millis
45 | // FTP control sessions should start out in ASCII, according to the RFC.
46 | // However, many clients don't turn on UTF-8 even though they support it,
47 | // so we just turn it on by default.
48 | public static final String SESSION_ENCODING = "UTF-8";
49 |
50 | // This is a flag that should be true for public builds and false for dev builds
51 | public static final boolean release = true;
52 |
53 | // Try to fix the transfer stall bug, reopen the destination file periodically
54 | //public static final boolean do_reopen_hack = false;
55 | //public static final int bytes_between_reopen = 4000000;
56 |
57 | // Try to fix the transfer stall bug, flush the file periodically
58 | //public static final boolean do_flush_hack = false;
59 | //public static final int bytes_between_flush = 500000;
60 |
61 | public static final boolean do_mediascanner_notify = true;
62 |
63 |
64 | // public static int getIpRetrievalAttempts() {
65 | // return ipRetrievalAttempts;
66 | // }
67 |
68 | // public static void setIpRetrievalAttempts(int ipRetrievalAttempts) {
69 | // Defaults.ipRetrievalAttempts = ipRetrievalAttempts;
70 | // }
71 |
72 | public static int getPortNumber() {
73 | return portNumber;
74 | }
75 |
76 | public static void setPortNumber(int portNumber) {
77 | Defaults.portNumber = portNumber;
78 | }
79 |
80 | public static String getSettingsName() {
81 | return settingsName;
82 | }
83 |
84 | public static void setSettingsName(String settingsName) {
85 | Defaults.settingsName = settingsName;
86 | }
87 |
88 | public static int getSettingsMode() {
89 | return settingsMode;
90 | }
91 |
92 | public static void setSettingsMode(int settingsMode) {
93 | Defaults.settingsMode = settingsMode;
94 | }
95 |
96 | public static void setServerLogScrollBack(int serverLogScrollBack) {
97 | Defaults.serverLogScrollBack = serverLogScrollBack;
98 | }
99 |
100 | protected static int settingsMode = Context.MODE_WORLD_WRITEABLE;
101 |
102 | public static int getUiLogLevel() {
103 | return uiLogLevel;
104 | }
105 |
106 | public static void setUiLogLevel(int uiLogLevel) {
107 | Defaults.uiLogLevel = uiLogLevel;
108 | }
109 |
110 | public static int getInputBufferSize() {
111 | return inputBufferSize;
112 | }
113 |
114 | public static void setInputBufferSize(int inputBufferSize) {
115 | Defaults.inputBufferSize = inputBufferSize;
116 | }
117 |
118 | public static int getDataChunkSize() {
119 | return dataChunkSize;
120 | }
121 |
122 | public static void setDataChunkSize(int dataChunkSize) {
123 | Defaults.dataChunkSize = dataChunkSize;
124 | }
125 |
126 | public static int getSessionMonitorScrollBack() {
127 | return sessionMonitorScrollBack;
128 | }
129 |
130 | public static void setSessionMonitorScrollBack(
131 | int sessionMonitorScrollBack)
132 | {
133 | Defaults.sessionMonitorScrollBack = sessionMonitorScrollBack;
134 | }
135 |
136 | public static int getServerLogScrollBack() {
137 | return serverLogScrollBack;
138 | }
139 |
140 | public static void setLogScrollBack(int serverLogScrollBack) {
141 | Defaults.serverLogScrollBack = serverLogScrollBack;
142 | }
143 |
144 | public static int getConsoleLogLevel() {
145 | return consoleLogLevel;
146 | }
147 |
148 | public static void setConsoleLogLevel(int consoleLogLevel) {
149 | Defaults.consoleLogLevel = consoleLogLevel;
150 | }
151 |
152 |
153 | }
154 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FavoriteDatabaseHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import android.content.ContentValues;
23 | import android.content.Context;
24 | import android.database.Cursor;
25 | import android.database.sqlite.SQLiteDatabase;
26 | import android.database.sqlite.SQLiteOpenHelper;
27 |
28 | public class FavoriteDatabaseHelper extends SQLiteOpenHelper {
29 |
30 | private final static String DATABASE_NAME = "file_explorer";
31 |
32 | private final static int DATABASE_VERSION = 1;
33 |
34 | private final static String TABLE_NAME = "favorite";
35 |
36 | public final static String FIELD_ID = "_id";
37 |
38 | public final static String FIELD_TITLE = "title";
39 |
40 | public final static String FIELD_LOCATION = "location";
41 |
42 | private boolean firstCreate;
43 |
44 | private FavoriteDatabaseListener mListener;
45 |
46 | private static FavoriteDatabaseHelper instance;
47 |
48 | public interface FavoriteDatabaseListener {
49 | void onFavoriteDatabaseChanged();
50 | }
51 |
52 | public FavoriteDatabaseHelper(Context context, FavoriteDatabaseListener listener) {
53 | super(context, DATABASE_NAME, null, DATABASE_VERSION);
54 | instance = this;
55 | mListener = listener;
56 | }
57 |
58 | public static FavoriteDatabaseHelper getInstance() {
59 | return instance;
60 | }
61 |
62 | @Override
63 | public void onCreate(SQLiteDatabase db) {
64 | String sql = "Create table " + TABLE_NAME + "(" + FIELD_ID + " integer primary key autoincrement,"
65 | + FIELD_TITLE + " text, " + FIELD_LOCATION + " text );";
66 | db.execSQL(sql);
67 | firstCreate = true;
68 | }
69 |
70 | @Override
71 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
72 | String sql = " DROP TABLE IF EXISTS " + TABLE_NAME;
73 | db.execSQL(sql);
74 | onCreate(db);
75 | }
76 |
77 | public boolean isFirstCreate() {
78 | return firstCreate;
79 | }
80 |
81 | public boolean isFavorite(String path) {
82 | String selection = FIELD_LOCATION + "=?";
83 | String[] selectionArgs = new String[] {
84 | path
85 | };
86 | SQLiteDatabase db = this.getReadableDatabase();
87 | Cursor cursor = db.query(TABLE_NAME, null, selection, selectionArgs, null, null, null);
88 | if (cursor == null)
89 | return false;
90 | boolean ret = cursor.getCount() > 0;
91 | cursor.close();
92 | return ret;
93 | }
94 |
95 | public Cursor query() {
96 | SQLiteDatabase db = this.getReadableDatabase();
97 | Cursor cursor = db.query(TABLE_NAME, null, null, null, null, null, null);
98 | return cursor;
99 | }
100 |
101 | public long insert(String title, String location) {
102 | if (isFavorite(location))
103 | return -1;
104 |
105 | SQLiteDatabase db = this.getWritableDatabase();
106 | long ret = db.insert(TABLE_NAME, null, createValues(title, location));
107 | mListener.onFavoriteDatabaseChanged();
108 | return ret;
109 | }
110 |
111 | public void delete(long id, boolean notify) {
112 | SQLiteDatabase db = this.getWritableDatabase();
113 | String where = FIELD_ID + "=?";
114 | String[] whereValue = {
115 | Long.toString(id)
116 | };
117 | db.delete(TABLE_NAME, where, whereValue);
118 |
119 | if (notify)
120 | mListener.onFavoriteDatabaseChanged();
121 | }
122 |
123 | public void delete(String location) {
124 | SQLiteDatabase db = this.getWritableDatabase();
125 | String where = FIELD_LOCATION + "=?";
126 | String[] whereValue = {
127 | location
128 | };
129 | db.delete(TABLE_NAME, where, whereValue);
130 | mListener.onFavoriteDatabaseChanged();
131 | }
132 |
133 | public void update(int id, String title, String location) {
134 | SQLiteDatabase db = this.getWritableDatabase();
135 | String where = FIELD_ID + "=?";
136 | String[] whereValue = {
137 | Integer.toString(id)
138 | };
139 | db.update(TABLE_NAME, createValues(title, location), where, whereValue);
140 | mListener.onFavoriteDatabaseChanged();
141 | }
142 |
143 | private ContentValues createValues(String title, String location) {
144 | ContentValues cv = new ContentValues();
145 | cv.put(FIELD_TITLE, title);
146 | cv.put(FIELD_LOCATION, location);
147 | return cv;
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/IntentBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 | import java.io.File;
23 | import java.util.ArrayList;
24 |
25 | import android.app.AlertDialog;
26 | import android.content.Context;
27 | import android.content.DialogInterface;
28 | import android.content.Intent;
29 | import android.net.Uri;
30 | import android.text.TextUtils;
31 |
32 | public class IntentBuilder {
33 |
34 | public static void viewFile(final Context context, final String filePath) {
35 | String type = getMimeType(filePath);
36 |
37 | if (!TextUtils.isEmpty(type) && !TextUtils.equals(type, "*/*")) {
38 | /* 设置intent的file与MimeType */
39 | Intent intent = new Intent();
40 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
41 | intent.setAction(android.content.Intent.ACTION_VIEW);
42 | intent.setDataAndType(Uri.fromFile(new File(filePath)), type);
43 | context.startActivity(intent);
44 | } else {
45 | // unknown MimeType
46 | AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
47 | dialogBuilder.setTitle(R.string.dialog_select_type);
48 |
49 | CharSequence[] menuItemArray = new CharSequence[] {
50 | context.getString(R.string.dialog_type_text),
51 | context.getString(R.string.dialog_type_audio),
52 | context.getString(R.string.dialog_type_video),
53 | context.getString(R.string.dialog_type_image) };
54 | dialogBuilder.setItems(menuItemArray,
55 | new DialogInterface.OnClickListener() {
56 | @Override
57 | public void onClick(DialogInterface dialog, int which) {
58 | String selectType = "*/*";
59 | switch (which) {
60 | case 0:
61 | selectType = "text/plain";
62 | break;
63 | case 1:
64 | selectType = "audio/*";
65 | break;
66 | case 2:
67 | selectType = "video/*";
68 | break;
69 | case 3:
70 | selectType = "image/*";
71 | break;
72 | }
73 | Intent intent = new Intent();
74 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
75 | intent.setAction(android.content.Intent.ACTION_VIEW);
76 | intent.setDataAndType(Uri.fromFile(new File(filePath)), selectType);
77 | context.startActivity(intent);
78 | }
79 | });
80 | dialogBuilder.show();
81 | }
82 | }
83 |
84 | public static Intent buildSendFile(ArrayList files) {
85 | ArrayList uris = new ArrayList();
86 |
87 | String mimeType = "*/*";
88 | for (FileInfo file : files) {
89 | if (file.IsDir)
90 | continue;
91 |
92 | File fileIn = new File(file.filePath);
93 | mimeType = getMimeType(file.fileName);
94 | Uri u = Uri.fromFile(fileIn);
95 | uris.add(u);
96 | }
97 |
98 | if (uris.size() == 0)
99 | return null;
100 |
101 | boolean multiple = uris.size() > 1;
102 | Intent intent = new Intent(multiple ? android.content.Intent.ACTION_SEND_MULTIPLE
103 | : android.content.Intent.ACTION_SEND);
104 |
105 | if (multiple) {
106 | intent.setType("*/*");
107 | intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
108 | } else {
109 | intent.setType(mimeType);
110 | intent.putExtra(Intent.EXTRA_STREAM, uris.get(0));
111 | }
112 |
113 | return intent;
114 | }
115 |
116 | private static String getMimeType(String filePath) {
117 | int dotPosition = filePath.lastIndexOf('.');
118 | if (dotPosition == -1)
119 | return "*/*";
120 |
121 | String ext = filePath.substring(dotPosition + 1, filePath.length()).toLowerCase();
122 | String mimeType = MimeUtils.guessMimeTypeFromExtension(ext);
123 | if (ext.equals("mtz")) {
124 | mimeType = "application/miui-mtz";
125 | }
126 |
127 | return mimeType != null ? mimeType : "*/*";
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/net/micode/fileexplorer/FileIconHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
3 | *
4 | * This file is part of FileExplorer.
5 | *
6 | * FileExplorer is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * FileExplorer is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with SwiFTP. If not, see .
18 | */
19 |
20 | package net.micode.fileexplorer;
21 |
22 |
23 | import net.micode.fileexplorer.FileCategoryHelper.FileCategory;
24 | import net.micode.fileexplorer.FileIconLoader.IconLoadFinishListener;
25 |
26 | import android.content.Context;
27 | import android.view.View;
28 | import android.widget.ImageView;
29 |
30 | import java.util.HashMap;
31 |
32 | public class FileIconHelper implements IconLoadFinishListener {
33 |
34 | private static final String LOG_TAG = "FileIconHelper";
35 |
36 | private static HashMap imageFrames = new HashMap();
37 |
38 | private static HashMap fileExtToIcons = new HashMap();
39 |
40 | private FileIconLoader mIconLoader;
41 |
42 | static {
43 | addItem(new String[] {
44 | "mp3"
45 | }, R.drawable.file_icon_mp3);
46 | addItem(new String[] {
47 | "wma"
48 | }, R.drawable.file_icon_wma);
49 | addItem(new String[] {
50 | "wav"
51 | }, R.drawable.file_icon_wav);
52 | addItem(new String[] {
53 | "mid"
54 | }, R.drawable.file_icon_mid);
55 | addItem(new String[] {
56 | "mp4", "wmv", "mpeg", "m4v", "3gp", "3gpp", "3g2", "3gpp2", "asf"
57 | }, R.drawable.file_icon_video);
58 | addItem(new String[] {
59 | "jpg", "jpeg", "gif", "png", "bmp", "wbmp"
60 | }, R.drawable.file_icon_picture);
61 | addItem(new String[] {
62 | "txt", "log", "xml", "ini", "lrc"
63 | }, R.drawable.file_icon_txt);
64 | addItem(new String[] {
65 | "doc", "ppt", "docx", "pptx", "xsl", "xslx",
66 | }, R.drawable.file_icon_office);
67 | addItem(new String[] {
68 | "pdf"
69 | }, R.drawable.file_icon_pdf);
70 | addItem(new String[] {
71 | "zip"
72 | }, R.drawable.file_icon_zip);
73 | addItem(new String[] {
74 | "mtz"
75 | }, R.drawable.file_icon_theme);
76 | addItem(new String[] {
77 | "rar"
78 | }, R.drawable.file_icon_rar);
79 | }
80 |
81 | public FileIconHelper(Context context) {
82 | mIconLoader = new FileIconLoader(context, this);
83 | }
84 |
85 | private static void addItem(String[] exts, int resId) {
86 | if (exts != null) {
87 | for (String ext : exts) {
88 | fileExtToIcons.put(ext.toLowerCase(), resId);
89 | }
90 | }
91 | }
92 |
93 | public static int getFileIcon(String ext) {
94 | Integer i = fileExtToIcons.get(ext.toLowerCase());
95 | if (i != null) {
96 | return i.intValue();
97 | } else {
98 | return R.drawable.file_icon_default;
99 | }
100 |
101 | }
102 |
103 | public void setIcon(FileInfo fileInfo, ImageView fileImage, ImageView fileImageFrame) {
104 | String filePath = fileInfo.filePath;
105 | long fileId = fileInfo.dbId;
106 | String extFromFilename = Util.getExtFromFilename(filePath);
107 | FileCategory fc = FileCategoryHelper.getCategoryFromPath(filePath);
108 | fileImageFrame.setVisibility(View.GONE);
109 | boolean set = false;
110 | int id = getFileIcon(extFromFilename);
111 | fileImage.setImageResource(id);
112 |
113 | mIconLoader.cancelRequest(fileImage);
114 | switch (fc) {
115 | case Apk:
116 | set = mIconLoader.loadIcon(fileImage, filePath, fileId, fc);
117 | break;
118 | case Picture:
119 | case Video:
120 | set = mIconLoader.loadIcon(fileImage, filePath, fileId, fc);
121 | if (set)
122 | fileImageFrame.setVisibility(View.VISIBLE);
123 | else {
124 | fileImage.setImageResource(fc == FileCategory.Picture ? R.drawable.file_icon_picture
125 | : R.drawable.file_icon_video);
126 | imageFrames.put(fileImage, fileImageFrame);
127 | set = true;
128 | }
129 | break;
130 | default:
131 | set = true;
132 | break;
133 | }
134 |
135 | if (!set)
136 | fileImage.setImageResource(R.drawable.file_icon_default);
137 | }
138 |
139 | @Override
140 | public void onIconLoadFinished(ImageView view) {
141 | ImageView frame = imageFrames.get(view);
142 | if (frame != null) {
143 | frame.setVisibility(View.VISIBLE);
144 | imageFrames.remove(view);
145 | }
146 | }
147 |
148 | }
149 |
--------------------------------------------------------------------------------
/src/org/swiftp/CmdRETR.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 David Revell
3 |
4 | This file is part of SwiFTP.
5 |
6 | SwiFTP is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | SwiFTP is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with SwiFTP. If not, see .
18 | */
19 |
20 | package org.swiftp;
21 |
22 | import java.io.File;
23 | import java.io.FileInputStream;
24 | import java.io.FileNotFoundException;
25 | import java.io.IOException;
26 |
27 | import android.util.Log;
28 |
29 | public class CmdRETR extends FtpCmd implements Runnable {
30 | //public static final String message = "TEMPLATE!!";
31 | protected String input;
32 |
33 | public CmdRETR(SessionThread sessionThread, String input) {
34 | super(sessionThread, CmdRETR.class.toString());
35 | this.input = input;
36 | }
37 |
38 | public void run() {
39 | myLog.l(Log.DEBUG, "RETR executing");
40 | String param = getParameter(input);
41 | File fileToRetr;
42 | String errString = null;
43 |
44 | mainblock: {
45 | fileToRetr = inputPathToChrootedFile(sessionThread.getWorkingDir(), param);
46 | if(violatesChroot(fileToRetr)) {
47 | errString = "550 Invalid name or chroot violation\r\n";
48 | break mainblock;
49 | } else if(fileToRetr.isDirectory()) {
50 | myLog.l(Log.DEBUG, "Ignoring RETR for directory");
51 | errString = "550 Can't RETR a directory\r\n";
52 | break mainblock;
53 | } else if(!fileToRetr.exists()) {
54 | myLog.l(Log.INFO, "Can't RETR nonexistent file: " +
55 | fileToRetr.getAbsolutePath());
56 | errString = "550 File does not exist\r\n";
57 | break mainblock;
58 | } else if(!fileToRetr.canRead()) {
59 | myLog.l(Log.INFO, "Failed RETR permission (canRead() is false)");
60 | errString = "550 No read permissions\r\n";
61 | break mainblock;
62 | } /*else if(!sessionThread.isBinaryMode()) {
63 | myLog.l(Log.INFO, "Failed RETR in text mode");
64 | errString = "550 Text mode RETR not supported\r\n";
65 | break mainblock;
66 | }*/
67 | try {
68 | FileInputStream in = new FileInputStream(fileToRetr);
69 | byte[] buffer = new byte[Defaults.getDataChunkSize()];
70 | int bytesRead;
71 | if(sessionThread.startUsingDataSocket()) {
72 | myLog.l(Log.DEBUG, "RETR opened data socket");
73 | } else {
74 | errString = "425 Error opening socket\r\n";
75 | myLog.l(Log.INFO, "Error in initDataSocket()");
76 | break mainblock;
77 | }
78 | sessionThread.writeString("150 Sending file\r\n");
79 | if(sessionThread.isBinaryMode()) {
80 | myLog.l(Log.DEBUG, "Transferring in binary mode");
81 | while((bytesRead = in.read(buffer)) != -1) {
82 | //myLog.l(Log.DEBUG,
83 | // String.format("CmdRETR sending %d bytes", bytesRead));
84 | if(sessionThread
85 | .sendViaDataSocket(buffer, bytesRead) == false)
86 | {
87 | errString = "426 Data socket error\r\n";
88 | myLog.l(Log.INFO, "Data socket error");
89 | break mainblock;
90 | }
91 | }
92 | } else { // We're in ASCII mode
93 | myLog.l(Log.DEBUG, "Transferring in ASCII mode");
94 | // We have to convert all solitary \n to \r\n
95 | boolean lastBufEndedWithCR = false;
96 | while((bytesRead = in.read(buffer)) != -1) {
97 | int startPos = 0, endPos = 0;
98 | byte[] crnBuf = {'\r','\n'};
99 | for(endPos = 0; endPos
2 |
3 |
4 | 文件管理
5 | 确定
6 | 搜索
7 | 新建文件夹
8 | 排序
9 | 名称
10 | 大小
11 | 时间
12 | 类型
13 | 收藏
14 | 取消收藏
15 | 复制
16 | 复制路径
17 | 粘贴
18 | 剪切
19 | 发送
20 | 重命名
21 | 删除
22 | 详情
23 | 取消
24 | 刷新
25 | 全选
26 | 取消全选
27 | 显示点文件和隐藏文件
28 | 隐藏点文件和隐藏文件
29 | 取消
30 | 没有文件
31 | 分类浏览
32 | 文件管理
33 | 远程管理
34 | SD卡
35 | 所有
36 | 音乐
37 | 视频
38 | 图片
39 | 主题
40 | 文档
41 | 压缩包
42 | 安装包
43 | 其它
44 | 收藏夹
45 | 请输入新名称
46 | 请输入文件夹名称
47 | 确认删除?
48 | 新建文件夹
49 | SD卡:%1$s
50 | 可用:%1$s
51 | 位置:
52 | 大小:
53 | 时间:
54 | 可读:
55 | 可写:
56 | 隐藏:
57 | 是
58 | 否
59 | 正在删除...
60 | 正在复制...
61 | 正在移动...
62 | 知道了
63 | 安装成功
64 | 安装失败
65 | 不能发送文件夹
66 | 已加入收藏夹
67 | 已从收藏夹移除
68 | 创建文件夹失败,文件夹已存在。
69 | 重命名失败失败,可能使用该名称的文件或文件夹已存在。
70 | 无可用SD卡,请插入或连接SD卡
71 | 启动服务
72 | 停止服务
73 | 远程管理服务已启动
74 | 远程管理服务正在运行
75 | 外部存储不可用.
76 | WiFi状态
77 | 启动后可以从电脑端远程管理手机文件
78 | 请在“我的电脑”地址栏中输入:
79 | 无WiFi网络
80 | 无WiFi网络,点击以查看WiFi设置
81 | 搜索文件
82 | 输入部分或全部文件名
83 | %d 字节
84 | 选择文件类型
85 | 文本
86 | 音频
87 | 视频
88 | 图像
89 | 照片
90 | SD卡
91 | 根目录
92 | MIUI截屏
93 | 铃声
94 | 已选择 %1$s 个
95 | 设置
96 | 退出
97 | 常规设置
98 | 主页文件夹
99 | 读取根目录
100 | 显示真实路径
101 | 程序启动时显示的文件夹,当前路径为%1$s
102 | 在导航栏中显示真实路径
103 |
104 |
--------------------------------------------------------------------------------