Compare commits

...

39 Commits

Author SHA1 Message Date
Chee Yee 3e4b5e3ea2 update to handle Norwegian lang 2024-11-08 22:55:32 -08:00
cy33hc c4889ec160 Merge pull request #32 from xdpirate/master
Add Norwegian translation
2024-11-08 22:33:05 -08:00
xdpirate 3076f4b179 Add Norwegian translation 2024-11-08 11:24:14 +01:00
Chee Yee 93fb338ce0 failed install to display server error message 2024-11-08 00:38:31 -08:00
Chee Yee 785a073bce fixed issue parse apache2 httpd directory listing using docker image 2024-10-26 15:31:01 -07:00
Chee Yee a71bd1eb28 enchancements to install from url 2024-10-08 20:50:42 -07:00
Chee Yee 0a1420dd96 add support for myrient.erista.me website 2024-07-20 02:45:52 -07:00
Chee Yee dcdc1fc54b use spaces for separator, seems less overcrowded 2024-07-16 21:27:12 -07:00
Chee Yee 5c254589e6 Merge branch 'master' of github.com:cy33hc/ps4-ezremote-client 2024-07-16 20:59:32 -07:00
Chee Yee 2b25272379 display server url in the sites drop down to easily identify site 2024-07-16 20:59:23 -07:00
cy33hc 6b66d39eba Update README.md 2024-07-16 10:42:18 -07:00
Chee Yee b143c3e3c5 add archive org screenshot 2024-07-15 19:15:25 -07:00
Chee Yee c3cc6d5954 add screenshots for archive org retrieve download URL 2024-07-15 15:02:55 -07:00
Chee Yee cfcb420b9d add support for archive.org 2024-07-14 01:54:54 -07:00
Chee Yee 294455c735 add ability to use L2 button to navigate back to previous directory 2024-07-13 19:40:20 -07:00
Chee Yee 4ff119b34d fix crash on failed install split pkg 2024-07-03 09:12:49 -07:00
Chee Yee 114c1974e1 enable disk caching for all remote types 2024-06-28 02:26:03 -07:00
Chee Yee a99bf163d8 implement download to split_file for all remote clients 2024-06-28 00:35:02 -07:00
Chee Yee b9ab71577f fix crash installing from real-debrid webdav 2024-06-27 22:04:06 -07:00
Chee Yee f80b3112c6 increase archive read buffer size to improve extraction speed 2024-06-27 11:11:33 -07:00
Chee Yee e0c72c85e5 fix crash while error reading from archive 2024-06-27 11:10:56 -07:00
Chee Yee 01f568feac update javascript 2024-06-27 00:55:57 -07:00
Chee Yee 2046a0e096 add disk cache option for installing from WebUi 2024-06-26 21:33:47 -07:00
Chee Yee 49f535dfde set the proper start time when overwrite prompt 2024-06-16 21:19:02 -07:00
Chee Yee 5a250a4182 display transfer speed 2024-06-13 23:44:19 -07:00
Chee Yee 89fa9aba69 fix install for large patch pkg 2024-06-13 18:38:18 -07:00
Chee Yee 0feff205d2 fix extracting from webdav 2024-04-29 00:13:07 -07:00
Chee Yee 5df5447eb0 improve speed of install pkg in zip on smb, nfs and sftp 2024-04-28 23:59:01 -07:00
Chee Yee b87dc91c6f fix install from url 2024-04-28 23:19:59 -07:00
Chee Yee 14b32504e0 more improvements to install speed for nfs, smb ans sftp 2024-04-28 18:11:22 -07:00
Chee Yee d35345a270 fix install from gdrive after refactor 2024-04-28 14:16:08 -07:00
Chee Yee f041172768 improve speed of installing from smb, nfs, sftp 2024-04-28 13:49:06 -07:00
Chee Yee 232a6233ca Merge branch 'master' of github.com:cy33hc/ps4-ezremote-client 2024-04-21 21:16:19 -07:00
Chee Yee c620478691 fix extraction of 7zip 2024-04-21 21:16:12 -07:00
cy33hc 2615372288 Update README.md 2024-04-04 01:21:34 -07:00
cy33hc 0889b0923d Update README.md 2024-04-04 01:21:03 -07:00
cy33hc a2b26102de Update README.md 2024-04-04 01:20:38 -07:00
cy33hc dff469a9d7 Update README.md 2024-04-04 01:20:16 -07:00
cy33hc 37074f0102 Update README.md 2024-04-04 01:19:56 -07:00
78 changed files with 3060 additions and 539 deletions
+5 -2
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.5)
project(ezremote_client)
@@ -25,8 +25,10 @@ add_executable(ezremote_client
source/http/httplib.cpp
source/clients/baseclient.cpp
source/clients/apache.cpp
source/clients/archiveorg.cpp
source/clients/ftpclient.cpp
source/clients/gdrive.cpp
source/clients/myrient.cpp
source/clients/iis.cpp
source/clients/nginx.cpp
source/clients/npxserve.cpp
@@ -62,11 +64,12 @@ add_executable(ezremote_client
source/windows.cpp
source/zip_util.cpp
source/split_file.cpp
source/mem_file.cpp
)
add_self(ezremote_client)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.22" 32 0)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.32" 32 0)
target_link_libraries(ezremote_client
c
+12 -1
View File
@@ -2,6 +2,10 @@
ezRemote Client is an application that allows you to connect the PS4 to remote FTP/SFTP, SMB(Windows Share), NFS, WebDAV, HTTP servers and Google Drive to transfer files. The interface is inspired by Filezilla client which provides a commander like GUI.
**New: As of version 1.19**
- Install PKG inside Zip files from both local hdd and remote servers.
- Extact zip files directly from remote servers.
**New:** As of version 1.0.8, ezRemote Client has a Web Interface that can be access from any modern browser to manage the PS4 files.
**New:** As of version 1.0.9. Remote Package Installation does not require you to host an external Http Server. The embedded Web Server built into ezRemote Client acts as a Proxy Server between the PS4 and remote server (FTP, SFTP, SMB, NFS, WebDav, HttpServer(IIS/Nginx/Apache/Serve) and GoogleDrive). There's no data written to the PS4 hard drive in the process, rather everything is streamed via embedded Web Server directly to the PS4 installer.
@@ -77,7 +81,13 @@ To distinguish between FTP, SMB, NFS, WebDAV or HTTP, the URL must be prefix wit
```
- For Google Drive use the following URL for the server **https://drive.google.com**
<br />[Go to the following wiki for instructions on how to setup the app to connect to Google Drive]( https://github.com/cy33hc/ps4-ezremote-client/wiki/Setup-App-for-use-with-Google-Drive)
- For Internet Archive repos download URLs
- Only supports parsing of the download URL (ie the URL where you see a list of files). Example
| | | |
|----------|-----------|---|
| ![archive_org_screen1](https://github.com/user-attachments/assets/b129b6cf-b938-4d7c-a3fa-61e1c633c1f6) | ![archive_org_screen2](https://github.com/user-attachments/assets/646106d1-e60b-4b35-b153-3475182df968)| ![image](https://github.com/user-attachments/assets/cad94de8-a694-4ef5-92a8-b87468e30adb) |
Tested with following WebDAV server:
- **(Recommeded)** [Dufs](https://github.com/sigoden/dufs) - For hosting your own WebDAV server. (Recommended since this allow anonymous access which is required for Remote Package Install)
- [SFTPgo](https://github.com/drakkan/sftpgo) - For local hosted WebDAV server. Can also be used as a webdav frontend for Cloud Storage like AWS S3, Azure Blob or Google Storage.
@@ -132,6 +142,7 @@ Circle - Un-Select the file list to navigate to other widgets or Close Dialog wi
Square - Mark file(s)/folder(s) for Delete/Rename/Upload/Download
R1 - Navigate to the Remote list of files
L1 - Navigate to the Local list of files
L2 - To go up a directory from current directory
TouchPad Button - Exit Application (versions prior to 1.06)
Options Button - Exit Application (versions 1.06 and above)
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

+1 -1
View File
@@ -113,7 +113,7 @@ STR_DOWNLOAD_INSTALL_MSG=تثبيت الحزمة عن بعد غير ممكن. ه
STR_CHECKING_REMOTE_SERVER_MSG=التحقق من الخادم البعيد لتثبيت الحزمة عن بعد.
STR_ENABLE_RPI=RPI
STR_ENABLE_RPI_FTP_SMB_MSG=يتيح هذا الخيار تثبيت الحزمة عن بُعد عبر خادم الويب المضمن.
STR_ENABLE_RPI_WEBDAV_MSG==يتيح هذا الخيار تثبيت الحزمة عن بُعد عبر خادم الويب المضمن.
STR_ENABLE_RPI_WEBDAV_MSG=يتيح هذا الخيار تثبيت الحزمة عن بُعد عبر خادم الويب المضمن.
STR_FILES=الملفات
STR_EDITOR=المحرر
STR_SAVE=حفظ
+6 -2
View File
@@ -112,8 +112,8 @@ STR_CANNOT_CONNECT_REMOTE_MSG=Remote HTTP Server not reachable.
STR_DOWNLOAD_INSTALL_MSG=Remote Package Install not possible. Would you like to download package and install instead?
STR_CHECKING_REMOTE_SERVER_MSG=Checking remote server for Remote Package Install.
STR_ENABLE_RPI=RPI
STR_ENABLE_RPI_FTP_SMB_MSG=This option enables Remote Package Installation via embedded Web Server.
STR_ENABLE_RPI_WEBDAV_MSG==This option enables Remote Package Installation via embedded Web Server.
STR_ENABLE_RPI_FTP_SMB_MSG=This option enables Remote Package Installation via embedded Web Server proxy.
STR_ENABLE_RPI_WEBDAV_MSG=This option enables Remote Package Installation via embedded Web Server proxy.
STR_FILES=Files
STR_EDITOR=Editor
STR_SAVE=Save
@@ -160,3 +160,7 @@ STR_LANGUAGE=Language
STR_TEMP_DIRECTORY=Temp Directory
STR_REALDEBRID=Real-Debrid
STR_BACKGROUND_INSTALL_INPROGRESS=Package install is running in the background. Don't close the app while install is in progress
STR_ENABLE_DISC_CACHE_MSG=Enable disk caching. Can improve Remote Package Install speed in cases where connection to remote is slow, but breaks resuming of install
STR_ENABLE_ALLDEBRID_MSG=Install Via AllDebrid
STR_ENABLE_REALDEBRID_MSG=Install Via RealDebrid
STR_ENABLE_DISKCACHE_DESC=Enable Disk Cache
+74 -2
View File
@@ -25,7 +25,7 @@ STR_FILE=파일
STR_TYPE=종류
STR_NAME=이름
STR_SIZE=크기
STR_DATE=일시
STR_DATE=날짜
STR_NEW_FOLDER=새 폴더
STR_RENAME=이름 변경
STR_DELETE=삭제
@@ -39,7 +39,7 @@ STR_OVERWRITE=덮어쓰기
STR_DONT_OVERWRITE=덮어쓰기 금지
STR_ASK_FOR_CONFIRM=수락여부를 질문
STR_DONT_ASK_CONFIRM=수락여부를 묻지 않음
STR_ALLWAYS_USE_OPTION=다시 묻지 않고 항상 이 설정을 사용
STR_ALLWAYS_USE_OPTION=다시 묻지 않고 항상 이 설정을 사용
STR_ACTIONS=실행
STR_CONFIRM=확인
STR_OVERWRITE_OPTIONS=덮어쓰기 옵션
@@ -59,3 +59,75 @@ STR_FAIL_DEL_DIR_MSG=디렉토리 삭제에 실패하였습니다.
STR_DELETING=삭제 중
STR_FAIL_DEL_FILE_MSG=파일 삭제에 실패하였습니다.
STR_DELETED=삭제됨
STR_LINK=링크
STR_SHARE=공유
STR_FAILED=310 실패함
STR_FAIL_CREATE_LOCAL_FILE_MSG=310 로컬에서 파일을 만들기 실패함
STR_INSTALL=설치
STR_INSTALLING=설치 중
STR_INSTALL_SUCCESS=성공
STR_INSTALL_FAILED=실패함
STR_INSTALL_SKIPPED=건너뜀
STR_CHECK_HTTP_MSG=원격 HTTP 서버에 대한 연결 확인
STR_FAILED_HTTP_CHECK=HTTP 서버에 연결에 실패함
STR_REMOTE_NOT_HTTP=원격이 HTTP 서버가 아님
STR_INSTALL_FROM_DATA_MSG=패키지가 /data 또는 /mnt/usbX 폴더에 없음
STR_ALREADY_INSTALLED_MSG=패키지가 이미 설치되었음
STR_INSTALL_FROM_URL=URL에서 설치
STR_CANNOT_READ_PKG_HDR_MSG=패키지 헤더 정보를 읽을 수 없음
STR_FAVORITE_URLS=즐겨찾기 URL
STR_SLOT=슬롯
STR_EDIT=편집
STR_ONETIME_URL=한 번만 Url
STR_NOT_A_VALID_PACKAGE=유효하지 않은 패키지
STR_WAIT_FOR_INSTALL_MSG=패키지 설치가 완료되기를 기다리는 중
STR_FAIL_INSTALL_TMP_PKG_MSG=pkg 파일을 설치하지 못했습니다. tmp pkg를 수동으로 삭제하세요.
STR_AUTO_DELETE_TMP_PKG=설치 후 임시로 다운로드한 pkg 파일을 자동으로 삭제
STR_PROTOCOL_NOT_SUPPORTED=지원되지 않는 프로토콜
STR_COULD_NOT_RESOLVE_HOST=호스트 이름을 확인할 수 없음
STR_EXTRACT=압축 해제
STR_EXTRACTING=압축 해제 중
STR_FAILED_TO_EXTRACT=압축 해제 실패함
STR_EXTRACT_LOCATION=압축 해제 위치
STR_COMPRESS=압축
STR_ZIP_FILE_PATH=Zip 파일 이름
STR_COMPRESSING=압축 중
STR_ERROR_CREATE_ZIP=zip 파일을 만드는 동안 오류 발생
STR_UNSUPPORTED_FILE_FORMAT=지원되지 않는 압축 파일 형식
STR_CUT=잘라내기
STR_COPY=복사
STR_PASTE=붙여넣기
STR_MOVING=이동 중
STR_COPYING=복사 중
STR_FAIL_MOVE_MSG=파일 이동 실패함
STR_FAIL_COPY_MSG=파일 복사 실패함
STR_CANT_MOVE_TO_SUBDIR_MSG=상위 디렉토리를 하위 디렉토리로 이동할 수 없음
STR_CANT_COPY_TO_SUBDIR_MSG=상위 디렉토리를 하위 디렉토리로 복사할 수 없음
STR_UNSUPPORTED_OPERATION_MSG=지원되지 않는 작업
STR_HTTP_PORT=Http 포트
STR_REINSTALL_CONFIRM_MSG=콘텐츠가 이미 설치되었습니다. 설치를 계속할까요?
STR_REMOTE_NOT_SUPPORT_MSG=보호된 서버에서는 원격 패키지 설치가 지원되지 않습니다.
STR_CANNOT_CONNECT_REMOTE_MSG=원격 HTTP 서버에 연결할 수 없습니다.
STR_DOWNLOAD_INSTALL_MSG=원격 패키지 설치가 불가능합니다. 패키지를 다운로드하여 설치할까요?
STR_CHECKING_REMOTE_SERVER_MSG=원격 패키지 설치를 위해 원격 서버를 확인하고 있습니다.
STR_FILES=파일
STR_EDITOR=편집기
STR_SAVE=저장
STR_MAX_EDIT_FILE_SIZE_MSG=다음보다 큰 파일을 편집할 수 없음
STR_DELETE_LINE=선택한 줄 삭제
STR_INSERT_LINE=선택한 줄 아래에 삽입
STR_MODIFIED=수정됨
STR_FAIL_GET_TOKEN_MSG=다음에서 접속 토큰을 얻는데 실패함
STR_GET_TOKEN_SUCCESS_MSG=로그인에 성공했습니다. 브라우저를 닫고 애플리케이션으로 돌아갈 수 있음
STR_NEW_FILE=새 파일
STR_SETTINGS=설정
STR_GLOBAL=글로벌
STR_COPY_LINE=선택한 줄 복사
STR_PASTE_LINE=선택한 줄에 붙여넣기
STR_SHOW_HIDDEN_FILES=숨겨진 파일 표시
STR_SET_DEFAULT_DIRECTORY=기본 폴더 설정
STR_SET_DEFAULT_DIRECTORY_MSG=기본 디렉터리로 설정됨
STR_NFS_EXP_PATH_MISSING_MSG=URL에 NFS 내보내기 경로 없음
STR_FAIL_INIT_NFS_CONTEXT=NFS 컨텍스트를 초기화 실패함
STR_FAIL_MOUNT_NFS_MSG=NFS 공유를 마운트 실패함
STR_VIEW_IMAGE=이미지 보기
+166
View File
@@ -0,0 +1,166 @@
STR_CONNECTION_SETTINGS=Tilkoblingsinnstillinger
STR_SITE=Side
STR_LOCAL=Lokal
STR_REMOTE=Ekstern
STR_MESSAGES=Meldinger
STR_UPDATE_SOFTWARE=Oppdater programvare
STR_CONNECT=Koble til
STR_DISCONNECT=Koble fra
STR_SEARCH=Søk
STR_REFRESH=Oppdater
STR_SERVER=Tjener
STR_USERNAME=Brukernavn
STR_PASSWORD=Passord
STR_PORT=Port
STR_PASV=Pasv
STR_DIRECTORY=Mappe
STR_FILTER=Filter
STR_YES=Ja
STR_NO=Nei
STR_CANCEL=Avbryt
STR_CONTINUE=Fortsett
STR_CLOSE=Lukk
STR_FOLDER=Mappe
STR_FILE=Fil
STR_TYPE=Type
STR_NAME=Navn
STR_SIZE=Størrelse
STR_DATE=Dato
STR_NEW_FOLDER=Ny mappe
STR_RENAME=Gi nytt navn
STR_DELETE=Slett
STR_UPLOAD=Last opp
STR_DOWNLOAD=Last ned
STR_SELECT_ALL=Marker alle
STR_CLEAR_ALL=Fjern alle
STR_UPLOADING=Laster opp
STR_DOWNLOADING=Laster ned
STR_OVERWRITE=Skriv over
STR_DONT_OVERWRITE=Ikke skriv over
STR_ASK_FOR_CONFIRM=Spør om bekreftelse
STR_DONT_ASK_CONFIRM=Ikke spør om bekreftelse
STR_ALLWAYS_USE_OPTION=Bruk alltid dette valget og ikke spør igjen
STR_ACTIONS=Handlinger
STR_CONFIRM=Bekreft
STR_OVERWRITE_OPTIONS=Overskriv innstillinger
STR_PROPERTIES=Egenskaper
STR_PROGRESS=Framdrift
STR_UPDATES=Oppdateringer
STR_DEL_CONFIRM_MSG=Er du sikker på at du vil slette filen(e)/mappen(e)?
STR_CANCEL_ACTION_MSG=Avbryter. Venter på at siste handling skal fullføres
STR_FAIL_UPLOAD_MSG=Opplasting av fil mislykkes
STR_FAIL_DOWNLOAD_MSG=Nedlasting av fil mislykkes
STR_FAIL_READ_LOCAL_DIR_MSG=Lesing av mappe mislykkes, eller mappen finnes ikke.
STR_CONNECTION_CLOSE_ERR_MSG=426 Tilkobling Lukket.
STR_REMOTE_TERM_CONN_MSG=426 Ekstern Tjener har lukket tilkoblingen.
STR_FAIL_LOGIN_MSG=300 Innlogging Mislykkes. Vennligst sjekk ditt brukernavn og passord.
STR_FAIL_TIMEOUT_MSG=426 Mislykkes. Tilkoblingen timet ut.
STR_FAIL_DEL_DIR_MSG=Sletting av mappe mislykkes
STR_DELETING=Sletter
STR_FAIL_DEL_FILE_MSG=Sletting av fil mislykkes
STR_DELETED=Slettet
STR_LINK=Lenke
STR_SHARE=Del
STR_FAILED=310 Mislykket
STR_FAIL_CREATE_LOCAL_FILE_MSG=310 Oppretting av lokal fil mislykkes
STR_INSTALL=Installér
STR_INSTALLING=Installerer
STR_INSTALL_SUCCESS=Vellykket
STR_INSTALL_FAILED=Mislykket
STR_INSTALL_SKIPPED=Hoppet over
STR_CHECK_HTTP_MSG=Sjekker tilkobling til ekstern HTTP-tjener
STR_FAILED_HTTP_CHECK=Mislykket tilkobling til HTTP-tjener
STR_REMOTE_NOT_HTTP=Ekstern tjener er ikke en HTTP-tjener
STR_INSTALL_FROM_DATA_MSG=Pakke finnes ikke i mappene /data eller /mnt/usbX
STR_ALREADY_INSTALLED_MSG=Pakken er allerede installert
STR_INSTALL_FROM_URL=Installer fra URL
STR_CANNOT_READ_PKG_HDR_MSG=Kunne ikke lese pakkens header
STR_FAVORITE_URLS=Favoritt-URLer
STR_SLOT=Spor
STR_EDIT=Redigér
STR_ONETIME_URL=Engangs-URL
STR_NOT_A_VALID_PACKAGE=Ikke en gyldig pakke
STR_WAIT_FOR_INSTALL_MSG=Venter på at pakke skal bli ferdig å installere
STR_FAIL_INSTALL_TMP_PKG_MSG=Installasjon av PKG-fil mislykkes. Vennligst slett den midlertidlige PKG-filen manuelt
STR_FAIL_TO_OBTAIN_GG_DL_MSG=Kunne ikke hente nedlastings-URL
STR_AUTO_DELETE_TMP_PKG=Automatisk slett midlertidig nedlastet PKG-fil etter installasjon
STR_PROTOCOL_NOT_SUPPORTED=Protokollen er ikke støttet
STR_COULD_NOT_RESOLVE_HOST=Kunne ikke koble til tjenernavnet
STR_EXTRACT=Pakk ut
STR_EXTRACTING=Pakker ut
STR_FAILED_TO_EXTRACT=Utpakking mislykkes
STR_EXTRACT_LOCATION=Utpakkingsbane
STR_COMPRESS=Komprimér
STR_ZIP_FILE_PATH=ZIP-filnavn
STR_COMPRESSING=Komprimerer
STR_ERROR_CREATE_ZIP=Oppretting av ZIP mislykket
STR_UNSUPPORTED_FILE_FORMAT=Arkivformatet er ikke støttet
STR_CUT=Klipp ut
STR_COPY=Kopiér
STR_PASTE=Lim inn
STR_MOVING=Flytter
STR_COPYING=Kopierer
STR_FAIL_MOVE_MSG=Flytting av fil mislykkes
STR_FAIL_COPY_MSG=Kopiering av fil mislykkes
STR_CANT_MOVE_TO_SUBDIR_MSG=Kan ikke flytte overordnet mappe til undermappe
STR_CANT_COPY_TO_SUBDIR_MSG=Kan ikke kopiere overordnet mappe til undermappe
STR_UNSUPPORTED_OPERATION_MSG=Handling ikke støttet
STR_HTTP_PORT=HTTP-port
STR_REINSTALL_CONFIRM_MSG=Innholdet er allerede installert. Vil du fortsette installasjonen
STR_REMOTE_NOT_SUPPORT_MSG=Fjerninstallasjon av pakker er ikke støttet for beskyttede tjenere.
STR_CANNOT_CONNECT_REMOTE_MSG=Ekstern HTTP-tjener kan ikke nås.
STR_DOWNLOAD_INSTALL_MSG=Fjerninstallasjon er ikke mulig. Vil du laste ned pakken og installere den istedet?
STR_CHECKING_REMOTE_SERVER_MSG=Sjekker tjener for fjerninstallasjon av pakke.
STR_ENABLE_RPI=FIP
STR_ENABLE_RPI_FTP_SMB_MSG=Dette valget skrur på fjerninstallasjon av pakke via innebygd Web-tjenerproxy.
STR_ENABLE_RPI_WEBDAV_MSG=Dette valget skrur på fjerninstallasjon av pakke via innebygd Web-tjenerproxy.
STR_FILES=Filer
STR_EDITOR=Redigeringsprogram
STR_SAVE=Lagre
STR_MAX_EDIT_FILE_SIZE_MSG=Kan ikke redigere filer større enn
STR_DELETE_LINE=Slett markert linje
STR_INSERT_LINE=Sett inn under markert linje
STR_MODIFIED=Endret
STR_FAIL_GET_TOKEN_MSG=Kunne ikke hente en tilgangstoken fra
STR_GET_TOKEN_SUCCESS_MSG=Innlogging vellykket. Du kan lukke nettleseren og gå tilbake til applikasjonen
STR_PERM_DRIVE=Se, endre, opprette og slette dine Google Drive-filer
STR_PERM_DRIVE_APPDATA=Se, opprette og slette dens egen konfigurasjonsdata i din Google Drive
STR_PERM_DRIVE_FILE=Se, endre, opprette og slette kun de spesifikke Google Drive-filene du bruker med denne appen
STR_PERM_DRIVE_METADATA=Vise og behandle metadataen til filer i din Google Drive
STR_PERM_DRIVE_METADATA_RO=Se informasjon om dine Google Drive-filer
STR_GOOGLE_LOGIN_FAIL_MSG=Google-innlogging mislykkes
STR_GOOGLE_LOGIN_TIMEOUT_MSG=Google-innlogging timet ut
STR_NEW_FILE=Ny Fil
STR_SETTINGS=Innstillinger
STR_CLIENT_ID=Klient-ID
STR_CLIENT_SECRET=Klienthemmelighet (Client Secret)
STR_GLOBAL=Global
STR_GOOGLE=Google
STR_COPY_LINE=Kopier markert linje
STR_PASTE_LINE=Lim inn i markert linje
STR_SHOW_HIDDEN_FILES=Vis skjulte filer
STR_SET_DEFAULT_DIRECTORY=Sett oppstartsmappe
STR_SET_DEFAULT_DIRECTORY_MSG=har blitt satt som oppstartsmappe
STR_VIEW_IMAGE=Vis bilde
STR_VIEW_PKG_INFO=Pakkeinformasjon
STR_NFS_EXP_PATH_MISSING_MSG=NFS-eksportbane mangler fra URL
STR_FAIL_INIT_NFS_CONTEXT=Initialisering av NFS-kontekst mislykkes
STR_FAIL_MOUNT_NFS_MSG=Montering av NFS-share mislykkes
STR_WEB_SERVER=Web-tjener
STR_ENABLE=Skru på
STR_COMPRESSED_FILE_PATH=Lokasjon for komprimerte filer
STR_COMPRESSED_FILE_PATH_MSG=Lokasjon for komprimerte filer på Web-tjener
STR_ALLDEBRID=AllDebrid
STR_API_KEY=API-nøkkel
STR_CANT_EXTRACT_URL_MSG=Kunne ikke utvinne nedlastings-URL
STR_FAIL_INSTALL_FROM_URL_MSG=Installasjon fra URL mislykkes
STR_INVALID_URL=Ugyldig URL
STR_ALLDEBRID_API_KEY_MISSING_MSG=For å bruke denne funksjonen, må du konfigurere en API-nøkkel i instillingene for ezRemote Client.
STR_LANGUAGE=Språk
STR_TEMP_DIRECTORY=Midlertidig mappe
STR_REALDEBRID=Real-Debrid
STR_BACKGROUND_INSTALL_INPROGRESS=Pakkeinstallasjon kjører i bakrunnen. Ikke lykk denne appen mens installasjonen pågår
STR_ENABLE_DISC_CACHE_MSG=Skru på disk-caching. Kan gjøre fjerninstallasjon av pakker kjappere når tilkoblingen er treg, men lar deg ikke fortsette en avbrutt installasjon
STR_ENABLE_ALLDEBRID_MSG=Installér via AllDebrid
STR_ENABLE_REALDEBRID_MSG=Installér via RealDebrid
STR_ENABLE_DISKCACHE_DESC=Skru på disk-cache
+98 -26
View File
@@ -1,8 +1,8 @@
STR_CONNECTION_SETTINGS=连接设置
STR_SITE=
STR_LOCAL=当地的
STR_REMOTE=偏僻的
STR_MESSAGES=留言
STR_SITE=
STR_LOCAL=本地
STR_REMOTE=远程路径
STR_MESSAGES=信息
STR_UPDATE_SOFTWARE=更新软件
STR_CONNECT=连接
STR_DISCONNECT=断开
@@ -11,51 +11,123 @@ STR_REFRESH=刷新
STR_SERVER=服务器
STR_USERNAME=用户名
STR_PASSWORD=密码
STR_PORT=
STR_PASV=帕夫
STR_PORT=
STR_PASV=被动模式
STR_DIRECTORY=目录
STR_FILTER=筛选
STR_YES=
STR_NO=
STR_FILTER=过滤器
STR_YES=
STR_NO=
STR_CANCEL=取消
STR_CONTINUE=继续
STR_CLOSE=关闭
STR_FOLDER=文件夹
STR_FILE=文件
STR_TYPE=类型
STR_NAME=
STR_SIZE=尺寸
STR_NAME=
STR_SIZE=大小
STR_DATE=日期
STR_NEW_FOLDER=新建文件夹
STR_RENAME=
STR_RENAME=重命
STR_DELETE=删除
STR_UPLOAD=上传
STR_DOWNLOAD=下载
STR_SELECT_ALL=全选
STR_CLEAR_ALL=全部清除
STR_UPLOADING=上传
STR_DOWNLOADING=下载
STR_CLEAR_ALL=取消全选
STR_UPLOADING=上传
STR_DOWNLOADING=下载
STR_OVERWRITE=覆盖
STR_DONT_OVERWRITE=覆盖
STR_ASK_FOR_CONFIRM=要求确认
STR_DONT_ASK_CONFIRM=要要求确认
STR_DONT_OVERWRITE=不覆盖
STR_ASK_FOR_CONFIRM=确认请求
STR_DONT_ASK_CONFIRM=不确认请求
STR_ALLWAYS_USE_OPTION=始终使用此选项,不再询问
STR_ACTIONS=行动
STR_CONFIRM=确认
STR_OVERWRITE_OPTIONS=覆盖选项
STR_PROPERTIES=
STR_PROGRESS=
STR_PROPERTIES=
STR_PROGRESS=
STR_UPDATES=更新
STR_DEL_CONFIRM_MSG=您确定要删除此文件/文件夹
STR_CANCEL_ACTION_MSG=取消等待最后一个动作完成
STR_DEL_CONFIRM_MSG=您确定要删除此文件/文件夹?
STR_CANCEL_ACTION_MSG=取消中。请等待最后一个操作结束
STR_FAIL_UPLOAD_MSG=上传文件失败
STR_FAIL_DOWNLOAD_MSG=下载文件失败
STR_FAIL_READ_LOCAL_DIR_MSG=读取目录内容失败或文件夹不存在。
STR_CONNECTION_CLOSE_ERR_MSG=426 连接已关闭。
STR_REMOTE_TERM_CONN_MSG=426 远程服务器已终止连接。
STR_FAIL_LOGIN_MSG=300 登录失败。 请检查您的用户名或密码。
STR_FAIL_TIMEOUT_MSG=426 失败。 连接超时。
STR_FAIL_LOGIN_MSG=300 登录失败。请检查您的用户名或密码。
STR_FAIL_TIMEOUT_MSG=426 失败。连接超时。
STR_FAIL_DEL_DIR_MSG=删除目录失败
STR_DELETING=删除
STR_DELETING=删除
STR_FAIL_DEL_FILE_MSG=删除文件失败
STR_DELETED=删除
STR_DELETED=删除完毕
STR_LINK=链接
STR_SHARE=分享
STR_FAILED=310 失败
STR_FAIL_CREATE_LOCAL_FILE_MSG=310 无法本地创建文件
STR_INSTALL=安装
STR_INSTALLING=正在安装中
STR_INSTALL_SUCCESS=成功
STR_INSTALL_FAILED=失败
STR_INSTALL_SKIPPED=已忽略
STR_CHECK_HTTP_MSG=正在检查与远程HTTP服务器的连接
STR_FAILED_HTTP_CHECK=连接到HTTP服务器失败
STR_REMOTE_NOT_HTTP=远程不是HTTP服务器
STR_INSTALL_FROM_DATA_MSG=文件包不在/data或/mnt/usbX文件夹中
STR_ALREADY_INSTALLED_MSG=文件包已经安装
STR_INSTALL_FROM_URL=从网址安装
STR_CANNOT_READ_PKG_HDR_MSG=无法读取包文件头信息
STR_FAVORITE_URLS=收藏网址
STR_SLOT=槽位
STR_EDIT=编辑
STR_ONETIME_URL=一次性网址
STR_NOT_A_VALID_PACKAGE=不是有效的程序包
STR_WAIT_FOR_INSTALL_MSG=正在等待包完成安装
STR_FAIL_INSTALL_TMP_PKG_MSG=未能安装pkg文件。请手动删除tmp pkg
STR_AUTO_DELETE_TMP_PKG=安装后自动删除临时下载的pkg文件
STR_PROTOCOL_NOT_SUPPORTED=不支持该协议
STR_COULD_NOT_RESOLVE_HOST=无法解析主机名
STR_EXTRACT=提取
STR_EXTRACTING=提取中
STR_FAILED_TO_EXTRACT=提取失败
STR_EXTRACT_LOCATION=提取位置
STR_COMPRESS=压缩
STR_ZIP_FILE_PATH=Zip 文件名
STR_COMPRESSING=压缩中
STR_ERROR_CREATE_ZIP=正在创建zip文件时出现错误
STR_UNSUPPORTED_FILE_FORMAT=不支持的压缩文件格式
STR_CUT=剪切
STR_COPY=复制
STR_PASTE=粘贴
STR_MOVING=移动中
STR_COPYING=复制中
STR_FAIL_MOVE_MSG=移动文件失败
STR_FAIL_COPY_MSG=复制文件事变
STR_CANT_MOVE_TO_SUBDIR_MSG=无法将父目录移动到子目录
STR_CANT_COPY_TO_SUBDIR_MSG=无法将父目录复制到子目录
STR_UNSUPPORTED_OPERATION_MSG=不支持操作
STR_HTTP_PORT=Http 端口
STR_REINSTALL_CONFIRM_MSG=内容已安装。是否要继续安装
STR_REMOTE_NOT_SUPPORT_MSG=受保护的服务器不支持远程程序包安装。
STR_CANNOT_CONNECT_REMOTE_MSG=无法访问远程HTTP服务器。
STR_DOWNLOAD_INSTALL_MSG=无法安装远程程序包。是否下载软件包并进行安装?
STR_CHECKING_REMOTE_SERVER_MSG=正在检查远程服务器的远程包安装。
STR_FILES=文件
STR_EDITOR=编辑器
STR_SAVE=保存
STR_MAX_EDIT_FILE_SIZE_MSG=无法编辑大于全部的文件。
STR_DELETE_LINE=删除所选行
STR_INSERT_LINE=在所选行下方插入
STR_MODIFIED=已修改
STR_FAIL_GET_TOKEN_MSG=无法从获取访问令牌
STR_GET_TOKEN_SUCCESS_MSG=登录成功。您可以关闭浏览器并返回应用程序
STR_NEW_FILE=新文件
STR_SETTINGS=设置
STR_GLOBAL=全局
STR_COPY_LINE=复制所选行
STR_PASTE_LINE=粘贴到所选行
STR_SHOW_HIDDEN_FILES=显示隐藏文件
STR_SET_DEFAULT_DIRECTORY=设置默认文件夹
STR_SET_DEFAULT_DIRECTORY_MSG=已设置为默认目录
STR_NFS_EXP_PATH_MISSING_MSG=URL中缺少NFS导出路径
STR_FAIL_INIT_NFS_CONTEXT=无法初始化NFS上下文
STR_FAIL_MOUNT_NFS_MSG=挂在 NFS 共享失败
STR_VIEW_IMAGE=查看图片
+94 -36
View File
@@ -1,75 +1,133 @@
STR_CONNECTION_SETTINGS=Bağlantı Ayarları
STR_SITE=Site
STR_LOCAL=Yerel
STR_REMOTE=Uzaktan
STR_REMOTE=Uzak
STR_MESSAGES=Mesajlar
STR_UPDATE_SOFTWARE=Yazılımı Güncelle
STR_CONNECT=Bağlan
STR_DISCONNECT=Bağlantıyı kes
STR_SEARCH=Ara
STR_DISCONNECT=Bağlantıyı Kes
STR_SEARCH=Arama
STR_REFRESH=Yenile
STR_SERVER=Sunucu
STR_USERNAME=Kullanıcı Adı
STR_PASSWORD=Şifre
STR_PASSWORD=Parola
STR_PORT=Port
STR_PASV=Pasv
STR_PASV=Pasif
STR_DIRECTORY=Dizin
STR_FILTER=Filtre
STR_YES=Evet
STR_NO=Hayır
STR_CANCEL=İptal
STR_CONTINUE=Devam
STR_CONTINUE=Devam Et
STR_CLOSE=Kapat
STR_FOLDER=Klasör
STR_FILE=Dosya
STR_TYPE=Tip
STR_TYPE=Tür
STR_NAME=Ad
STR_SIZE=Boyut
STR_DATE=Tarih
STR_NEW_FOLDER=Yeni Klasör
STR_RENAME=Yeniden Adlandır
STR_DELETE=Sil
STR_UPLOAD=Karşıya Yükle
STR_UPLOAD=Yükle
STR_DOWNLOAD=İndir
STR_SELECT_ALL=Tümünü Seç
STR_CLEAR_ALL=Tümünü Temizle
STR_UPLOADING=Karşıya Yükleniyor
STR_SELECT_ALL=Hepsini Seç
STR_CLEAR_ALL=Hepsini Temizle
STR_UPLOADING=Yükleniyor
STR_DOWNLOADING=İndiriliyor
STR_OVERWRITE=Üzerine yaz
STR_DONT_OVERWRITE=Üzerine yazma
STR_ASK_FOR_CONFIRM=Onaylamak için sor
STR_DONT_ASK_CONFIRM=Onaylamak için sorma
STR_ALLWAYS_USE_OPTION=Daima bu seçeneği kullan ve bir daha sorma
STR_ACTIONS=Eylemler
STR_OVERWRITE=Üzerine Yaz
STR_DONT_OVERWRITE=Üzerine Yazma
STR_ASK_FOR_CONFIRM=Onay İste
STR_DONT_ASK_CONFIRM=Onay İsteme
STR_ALLWAYS_USE_OPTION=Bu seçeneği her zaman kullan ve bir daha sorma
STR_ACTIONS=İşlemler
STR_CONFIRM=Onayla
STR_OVERWRITE_OPTIONS=Ayarların üzerine yaz
STR_OVERWRITE_OPTIONS=Üzerine Yazma Seçenekleri
STR_PROPERTIES=Özellikler
STR_PROGRESS=Durum
STR_PROGRESS=İlerleme
STR_UPDATES=Güncellemeler
STR_DEL_CONFIRM_MSG=Bu dosya(ları)/klasör(leri) silmek istediğinizden emin misiniz?
STR_CANCEL_ACTION_MSG=İptal ediliyor. Son lemin tamamlanması bekleniyor
STR_FAIL_UPLOAD_MSG=Dosya karşıya yükleme başarısız
STR_FAIL_DOWNLOAD_MSG=Dosya indirme başarısız
STR_FAIL_READ_LOCAL_DIR_MSG=Dizindeki içerikler okunamadı ya da öyle bir klasör yok
STR_CONNECTION_CLOSE_ERR_MSG=426 Bağlantı kesildi.
STR_REMOTE_TERM_CONN_MSG=426 Uzaktan Sunucu bağlantıyı kesti.
STR_FAIL_LOGIN_MSG=300 Giriş başarısız. Lütfen kullanıcı adınızı ve şifrenizi kontrol edin.
STR_CANCEL_ACTION_MSG=İptal ediliyor. Son eylemin tamamlanması bekleniyor
STR_FAIL_UPLOAD_MSG=Dosya yüklenemedi
STR_FAIL_DOWNLOAD_MSG=Dosya indirilemedi
STR_FAIL_READ_LOCAL_DIR_MSG=Yerel dizinin içeriği okunamadı veya klasör mevcut değil.
STR_CONNECTION_CLOSE_ERR_MSG=426 Bağlantı kapatıldı.
STR_REMOTE_TERM_CONN_MSG=426 Uzak Sunucu bağlantıyı sonlandırdı.
STR_FAIL_LOGIN_MSG=300 Giriş Başarısız. Lütfen kullanıcı adınızı veya şifrenizi kontrol edin.
STR_FAIL_TIMEOUT_MSG=426 Başarısız. Bağlantı zaman aşımına uğradı.
STR_FAIL_DEL_DIR_MSG=Dizin silme başarısız
STR_FAIL_DEL_DIR_MSG=Dizin silinemedi
STR_DELETING=Siliniyor
STR_FAIL_DEL_FILE_MSG=Dosya silme başarısız
STR_FAIL_DEL_FILE_MSG=Dosya silinemedi
STR_DELETED=Silindi
STR_LINK=Link
STR_LINK=Bağlantı
STR_SHARE=Paylaş
STR_FAILED=310 Başarısız
STR_FAIL_CREATE_LOCAL_FILE_MSG=310 Yerelde dosya oluşturulumu başarısız
STR_INSTALL=Yükle
STR_INSTALLING=Yükleniyor
STR_FAIL_CREATE_LOCAL_FILE_MSG=310 Yerelde dosya oluşturulamadı
STR_INSTALL=Kur
STR_INSTALLING=Kuruluyor
STR_INSTALL_SUCCESS=Başarılı
STR_INSTALL_FAILED=Başarısız
STR_INSTALL_SKIPPED=Atlandı
STR_CHECK_HTTP_MSG=Uzaktan HTTP Sunucusu bağlantısı kontrol ediliyor
STR_FAILED_HTTP_CHECK=HTTP Sunucusuna bağlantı başarısız
STR_REMOTE_NOT_HTTP=Uzaktaki HTTP Sunucusu değil
STR_INSTALL_FROM_DATA_MSG=Paket /data ya da /mnt/usbX dizininde değil
STR_CHECK_HTTP_MSG=Uzak HTTP Sunucusuna bağlantı kontrol ediliyor
STR_FAILED_HTTP_CHECK=HTTP Sunucusuna bağlanılamadı
STR_REMOTE_NOT_HTTP=Uzak bir HTTP Sunucusu değil
STR_INSTALL_FROM_DATA_MSG=Paket /data veya /mnt/usbX klasöründe değil
STR_ALREADY_INSTALLED_MSG=Paket zaten kurulu
STR_INSTALL_FROM_URL=URL'den Kur
STR_CANNOT_READ_PKG_HDR_MSG=Paket başlık bilgisi okunamadı
STR_FAVORITE_URLS=Favori URL'ler
STR_SLOT=Yuva
STR_EDIT=Düzenle
STR_ONETIME_URL=Tek Seferlik URL
STR_NOT_A_VALID_PACKAGE=Geçerli bir Paket değil
STR_WAIT_FOR_INSTALL_MSG=Paketin kurulmasının tamamlanması bekleniyor
STR_FAIL_INSTALL_TMP_PKG_MSG=Geçici paketin kurulumu başarısız. Lütfen geçici paketi manuel olarak silin
STR_AUTO_DELETE_TMP_PKG=Kurulumdan sonra geçici indirilen paketi otomatik olarak sil
STR_PROTOCOL_NOT_SUPPORTED=Protokol desteklenmiyor
STR_COULD_NOT_RESOLVE_HOST=Ana bilgisayar adı çözülemedi
STR_EXTRACT=Çıkart
STR_EXTRACTING=Çıkartılıyor
STR_FAILED_TO_EXTRACT=Çıkartma başarısız oldu
STR_EXTRACT_LOCATION=Çıkartılacak Konum
STR_COMPRESS=Sıkıştır
STR_ZIP_FILE_PATH=Zip Dosya Adı
STR_COMPRESSING=Sıkıştırılıyor
STR_ERROR_CREATE_ZIP=Zip oluşturulurken hata oluştu
STR_UNSUPPORTED_FILE_FORMAT=Desteklenmeyen sıkıştırılmış dosya formatı
STR_CUT=Kes
STR_COPY=Kopyala
STR_PASTE=Yapıştır
STR_MOVING=Taşınıyor
STR_COPYING=Kopyalanıyor
STR_FAIL_MOVE_MSG=Dosya taşınamadı
STR_FAIL_COPY_MSG=Dosya kopyalanamadı
STR_CANT_MOVE_TO_SUBDIR_MSG=Ana dizin alt dizinine taşınamaz
STR_CANT_COPY_TO_SUBDIR_MSG=Ana dizin alt dizinine kopyalanamaz
STR_UNSUPPORTED_OPERATION_MSG=Desteklenmeyen işlem
STR_HTTP_PORT=Http Portu
STR_REINSTALL_CONFIRM_MSG=İçerik zaten kurulu. Kuruluma devam etmek istiyor musunuz?
STR_REMOTE_NOT_SUPPORT_MSG=Korunan sunucular için uzak paket kurulumu desteklenmiyor.
STR_CANNOT_CONNECT_REMOTE_MSG=Uzak HTTP Sunucusuna bağlanılamıyor.
STR_DOWNLOAD_INSTALL_MSG=Uzak Paket Kurulumu mümkün değil. Paketi indirip kurmak ister misiniz?
STR_CHECKING_REMOTE_SERVER_MSG=Uzak Paket Kurulumu için uzak sunucu kontrol ediliyor.
STR_FILES=Dosyalar
STR_EDITOR=Düzenleyici
STR_SAVE=Kaydet
STR_MAX_EDIT_FILE_SIZE_MSG=Boyutu şu büyüklükten büyük dosyalar düzenlenemez
STR_DELETE_LINE=Seçili Satırı Sil
STR_INSERT_LINE=Seçili Satırın Altına Ekle
STR_MODIFIED=Değiştirildi
STR_FAIL_GET_TOKEN_MSG=Erişim token'ı alınamadı
STR_GET_TOKEN_SUCCESS_MSG=Giriş Başarılı. Tarayıcıyı kapatıp uygulamaya dönebilirsiniz
STR_NEW_FILE=Yeni Dosya
STR_SETTINGS=Ayarlar
STR_GLOBAL=Genel
STR_COPY_LINE=Seçili satırı kopyala
STR_PASTE_LINE=Seçili satıra yapıştır
STR_SHOW_HIDDEN_FILES=Gizli dosyaları göster
STR_SET_DEFAULT_DIRECTORY=Varsayılan Klasörü Ayarla
STR_SET_DEFAULT_DIRECTORY_MSG=varsayılan dizin olarak ayarlandı
STR_NFS_EXP_PATH_MISSING_MSG=URL'de NFS dışa aktarma yolu eksik
STR_FAIL_INIT_NFS_CONTEXT=NFS bağlamı başlatılamadı
STR_FAIL_MOUNT_NFS_MSG=NFS paylaşımı bağlanamadı
STR_VIEW_IMAGE=Görüntüyü Görüntüle
+133
View File
@@ -0,0 +1,133 @@
STR_CONNECTION_SETTINGS=Cài đặt kết nối
STR_SITE=Vị trí
STR_LOCAL=Thiết bị
STR_REMOTE=Máy đích
STR_MESSAGES=Tin nhắn
STR_UPDATE_SOFTWARE=Cập nhật phần mềm
STR_CONNECT=Kết nối
STR_DISCONNECT=Ngắt kết nối
STR_SEARCH=Tìm kiếm
STR_REFRESH=Làm mới
STR_SERVER=Máy chủ
STR_USERNAME=Tên đăng nhập
STR_PASSWORD=Mật khẩu
STR_PORT=Cổng
STR_PASV=Pasv
STR_DIRECTORY=Thư mục
STR_FILTER=Bộ lọc
STR_YES=Đồng ý
STR_NO=Không
STR_CANCEL=Hủy bỏ
STR_CONTINUE=Tiếp tục
STR_CLOSE=Đóng
STR_FOLDER=Thư mục
STR_FILE=Tập tin
STR_TYPE=Loại
STR_NAME=Tên
STR_SIZE=Kích thước
STR_DATE=Ngày tháng
STR_NEW_FOLDER=Thư mục mới
STR_RENAME=Đổi tên
STR_DELETE=Xóa
STR_UPLOAD=Tải lên
STR_DOWNLOAD=Tải xuống
STR_SELECT_ALL=Chọn tất cả
STR_CLEAR_ALL=Bỏ chọn tất cả
STR_UPLOADING=Đang tải lên
STR_DOWNLOADING=Đang tải xuống
STR_OVERWRITE=Ghi đè
STR_DONT_OVERWRITE=Không ghi đè
STR_ASK_FOR_CONFIRM=Hỏi xác nhận
STR_DONT_ASK_CONFIRM=Không hỏi xác nhận
STR_ALLWAYS_USE_OPTION=Luôn dùng tùy chọn này và không hỏi lại
STR_ACTIONS=Hành động
STR_CONFIRM=Xác nhận
STR_OVERWRITE_OPTIONS=Tùy chọn ghi đè
STR_PROPERTIES=Thuộc tính
STR_PROGRESS=Tiến trình
STR_UPDATES=Cập nhật
STR_DEL_CONFIRM_MSG=Bạn có chắc chắn muốn xóa (những) tập tin / thư mục này không?
STR_CANCEL_ACTION_MSG=Hủy bỏ. Chờ hành động cuối cùng hoàn tất.Canceling.
STR_FAIL_UPLOAD_MSG=Không thể tải file lên
STR_FAIL_DOWNLOAD_MSG=Không thể tải file
STR_FAIL_READ_LOCAL_DIR_MSG=Không đọc được nội dung của thư mục hoặc thư mục không tồn tại.
STR_CONNECTION_CLOSE_ERR_MSG=426 Kết nối đã đóng.
STR_REMOTE_TERM_CONN_MSG=426 Máy chủ đã ngắt kết nối.
STR_FAIL_LOGIN_MSG=300 Đăng nhập thất bại. Vui lòng kiểm tra lại tên đăng nhập hoặc mật khẩu.
STR_FAIL_TIMEOUT_MSG=426 Thất bại. Quá thời gian kết nối.
STR_FAIL_DEL_DIR_MSG=Không thể xóa thư mục
STR_DELETING=Đang xóa
STR_FAIL_DEL_FILE_MSG=Không thể xóa tập tin
STR_DELETED=Đã xóa
STR_LINK=Liên kết
STR_SHARE=Chia sẻ
STR_FAILED=310 Lỗi
STR_FAIL_CREATE_LOCAL_FILE_MSG=310 Không thể tạo file trên máy này
STR_INSTALL=Cài đặt
STR_INSTALLING=Đang cài đặt
STR_INSTALL_SUCCESS=Thành công
STR_INSTALL_FAILED=Thất bại
STR_INSTALL_SKIPPED=Bỏ qua
STR_CHECK_HTTP_MSG=Đang kiểm tra kết nối tới máy chủ HTTP
STR_FAILED_HTTP_CHECK=Không thể kết nối tới máy chủ HTTP
STR_REMOTE_NOT_HTTP=Máy đích không phải máy chủ HTTP
STR_INSTALL_FROM_DATA_MSG=Package không có trong thư mục /data hoặc /mnt/usbX
STR_ALREADY_INSTALLED_MSG=Package đã được cài đặt
STR_INSTALL_FROM_URL=Cài từ địa chỉ URL
STR_CANNOT_READ_PKG_HDR_MSG=Không thể đọc được thông tin header của package
STR_FAVORITE_URLS=URLs yêu thích
STR_SLOT=Vị trí
STR_EDIT=Sửa
STR_ONETIME_URL=Url một lần
STR_NOT_A_VALID_PACKAGE=Package không đúng
STR_WAIT_FOR_INSTALL_MSG=Đợi Package kết thúc cài đặt
STR_FAIL_INSTALL_TMP_PKG_MSG=Không thể cài file pkg. Vui lòng xóa tmp pkg thủ công
STR_AUTO_DELETE_TMP_PKG=Tự động xóa file pkg được tải về tạm thời sau khi cài xong
STR_PROTOCOL_NOT_SUPPORTED=Protocol không được hỗ trợ
STR_COULD_NOT_RESOLVE_HOST=Không thể phân giải tên máy chủ
STR_EXTRACT=Giải nén
STR_EXTRACTING=Đang giải nén
STR_FAILED_TO_EXTRACT=Giải nén thất bại
STR_EXTRACT_LOCATION=Vị trí giải nén
STR_COMPRESS=Nén
STR_ZIP_FILE_PATH=Tên file Zip
STR_COMPRESSING=Đang nén
STR_ERROR_CREATE_ZIP=Lỗi khi tạo file zip
STR_UNSUPPORTED_FILE_FORMAT=Phần mở rộng file không được hỗ trợ
STR_CUT=Cắt
STR_COPY=Sao chép
STR_PASTE=Dán
STR_MOVING=Đang di chuyển
STR_COPYING=Đang copy
STR_FAIL_MOVE_MSG=Không thể di chuyển file
STR_FAIL_COPY_MSG=Không thể sao chép file
STR_CANT_MOVE_TO_SUBDIR_MSG=Không thể di chuyển thư mục cha vào bên trong thư mục con
STR_CANT_COPY_TO_SUBDIR_MSG=Không thể sao chép thư mục cha vào bên trong thư mục con
STR_UNSUPPORTED_OPERATION_MSG=Hành động không được hỗ trợ
STR_HTTP_PORT=Cổng Http
STR_REINSTALL_CONFIRM_MSG=Nội dung đã được cài đặt. Bạn có muốn tiếp tục cài đặt không?
STR_REMOTE_NOT_SUPPORT_MSG=Cài đặt gói từ xa không được hỗ trợ cho các máy chủ được bảo vệ.
STR_CANNOT_CONNECT_REMOTE_MSG=Máy chủ HTTP đích không thể truy cập được.
STR_DOWNLOAD_INSTALL_MSG=Không thể cài đặt package từ xa. Bạn có muốn tải package xuống và cài đặt không?
STR_CHECKING_REMOTE_SERVER_MSG=Đang kiểm tra máy chủ đích để cài đặt package từ xa.
STR_FILES=Tập tin
STR_EDITOR=Trình soạn thảo
STR_SAVE=Lưu
STR_MAX_EDIT_FILE_SIZE_MSG=Không thể chỉnh sửa các tập tin lớn hơn
STR_DELETE_LINE=Xóa dòng đã chọn
STR_INSERT_LINE=Chèn bên dưới dòng đã chọn
STR_MODIFIED=Đã sửa đổi
STR_FAIL_GET_TOKEN_MSG=Không thể lấy được access token từ
STR_GET_TOKEN_SUCCESS_MSG=Đăng nhập thành công. Bạn có thể đóng trình duyệt và quay lại ứng dụng
STR_NEW_FILE=Tập tin mới
STR_SETTINGS=Cài đặt
STR_GLOBAL=Toàn cục
STR_COPY_LINE=Sao chép dòng đã chọn
STR_PASTE_LINE=Dán vào dòng đã chọn
STR_SHOW_HIDDEN_FILES=Hiển thị các tập tin ẩn
STR_SET_DEFAULT_DIRECTORY=Đặt thư mục mặc định
STR_SET_DEFAULT_DIRECTORY_MSG=đã được thiết lập làm thư mục mặc định
STR_NFS_EXP_PATH_MISSING_MSG=Đường dẫn NFS bị thiếu trong URL
STR_FAIL_INIT_NFS_CONTEXT=Không khởi tạo được ngữ cảnh NFS
STR_FAIL_MOUNT_NFS_MSG=Không thể mount NFS share
STR_PROMOTING=Promoting
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

+130 -14
View File
@@ -1,6 +1,7 @@
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <json-c/json.h>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <minizip/unzip.h>
@@ -10,6 +11,8 @@
#include "clients/smbclient.h"
#include "clients/webdav.h"
#include "clients/apache.h"
#include "clients/archiveorg.h"
#include "clients/myrient.h"
#include "clients/nginx.h"
#include "clients/npxserve.h"
#include "clients/nfsclient.h"
@@ -17,6 +20,7 @@
#include "clients/rclone.h"
#include "clients/sftpclient.h"
#include "filehost/filehost.h"
#include "server/http_server.h"
#include "common.h"
#include "fs.h"
#include "config.h"
@@ -364,6 +368,7 @@ namespace Actions
if (confirm_state == CONFIRM_YES)
{
sceRtcGetCurrentTick(&prev_tick);
return remoteclient->Put(src, dest);
}
@@ -409,6 +414,7 @@ namespace Actions
snprintf(activity_message, 1024, "%s %s", lang_strings[STR_UPLOADING], entries[i].path);
bytes_to_download = entries[i].file_size;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
ret = UploadFile(entries[i].path, new_path);
if (ret <= 0)
{
@@ -486,6 +492,7 @@ namespace Actions
int DownloadFile(const char *src, const char *dest)
{
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
if (!remoteclient->Size(src, &bytes_to_download))
{
remoteclient->Quit();
@@ -517,6 +524,7 @@ namespace Actions
if (confirm_state == CONFIRM_YES)
{
sceRtcGetCurrentTick(&prev_tick);
return remoteclient->Get(dest, src);
}
@@ -708,20 +716,46 @@ namespace Actions
}
else
{
std::string url = INSTALLER::getRemoteUrl(it->path, true);
std::string title = INSTALLER::GetRemotePkgTitle(remoteclient, it->path, &header);
if (remote_settings->enable_disk_cache)
{
SplitPkgInstallData *install_data = (SplitPkgInstallData*) malloc(sizeof(SplitPkgInstallData));
memset(install_data, 0, sizeof(SplitPkgInstallData));
if (INSTALLER::InstallRemotePkg(url, &header, title, true) == 0)
failed++;
OrbisTick tick;
sceRtcGetCurrentTick(&tick);
std::string install_pkg_path = std::string(temp_folder) + "/" + std::to_string(tick.mytick) + ".pkg";
SplitFile *sp = new SplitFile(install_pkg_path, INSTALL_ARCHIVE_PKG_SPLIT_SIZE/2);
install_data->split_file = sp;
install_data->remote_client = remoteclient;
install_data->path = it->path;
remoteclient->Size(it->path, &install_data->size);
install_data->stop_write_thread = false;
install_data->delete_client = false;
int ret = pthread_create(&install_data->thread, NULL, DownloadSplitPkg, install_data);
if (INSTALLER::InstallSplitPkg(it->path, install_data, false) == 0)
failed++;
else
success++;
}
else
success++;
{
std::string url = INSTALLER::getRemoteUrl(it->path, true);
std::string title = INSTALLER::GetRemotePkgTitle(remoteclient, it->path, &header);
if (INSTALLER::InstallRemotePkg(url, &header, title, true) == 0)
failed++;
else
success++;
}
}
}
else
skipped++;
}
}
else if (Util::EndsWith(path,".zip") || Util::EndsWith(path,".rar") ||
else if (Util::EndsWith(path,".zip") || Util::EndsWith(path,".rar") || Util::EndsWith(path,".7z") ||
Util::EndsWith(path,".tar.xz") || Util::EndsWith(path,".tar.gz"))
{
ArchiveEntry *entry = ZipUtil::GetPackageEntry(it->path, remoteclient);
@@ -817,6 +851,18 @@ namespace Actions
return NULL;
}
void *DownloadSplitPkg(void *argp)
{
SplitPkgInstallData *install_data = (SplitPkgInstallData*) argp;
SplitFile *sp = install_data->split_file;
/* loop over file contents and write to fd */
sp->Open();
install_data->remote_client->Get(sp, install_data->path);
sp->Close();
return NULL;
}
void *InstallLocalPkgsThread(void *argp)
{
int failed = 0;
@@ -1064,9 +1110,10 @@ namespace Actions
}
}
void *InstallUrlPkgThread(void *argp)
void *InstallLocalUrlPkgThread(void *argp)
{
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
sprintf(status_message, "%s", "");
pkg_header header;
char filename[2000];
@@ -1074,10 +1121,10 @@ namespace Actions
OrbisTick tick;
sceRtcGetCurrentClockLocalTime(&now);
sceRtcGetTick(&now, &tick);
sprintf(filename, "%s/%lu.pkg", DATA_PATH, tick.mytick);
sprintf(filename, "%s/%lu.pkg", TMP_FOLDER_PATH, tick.mytick);
std::string full_url = std::string(install_pkg_url.url);
FileHost *filehost = FileHost::getFileHost(full_url);
FileHost *filehost = FileHost::getFileHost(full_url, install_pkg_url.enable_alldebrid, install_pkg_url.enable_realdebrid);
if (!filehost->IsValidUrl())
{
sprintf(status_message, "%s", lang_strings[STR_FAIL_TO_OBTAIN_GG_DL_MSG]);
@@ -1100,7 +1147,7 @@ namespace Actions
std::string host = full_url.substr(0, path_pos);
std::string path = full_url.substr(path_pos);
WebDAVClient tmp_client;
BaseClient tmp_client;
tmp_client.Connect(host.c_str(), install_pkg_url.username, install_pkg_url.password);
sprintf(activity_message, "%s URL to %s", lang_strings[STR_DOWNLOADING], filename);
@@ -1108,9 +1155,9 @@ namespace Actions
memset(&header, 0, s);
int ret = tmp_client.Size(path, &bytes_to_download);
if (!ret)
if (ret == 0)
{
sprintf(status_message, "%s - %s", lang_strings[STR_FAILED], lang_strings[STR_CANNOT_READ_PKG_HDR_MSG]);
sprintf(status_message, "%s", tmp_client.LastResponse());
tmp_client.Quit();
activity_inprogess = false;
Windows::SetModalMode(false);
@@ -1118,7 +1165,7 @@ namespace Actions
}
file_transfering = 1;
int is_performed = tmp_client.Get(path, filename);
int is_performed = tmp_client.Get(filename, path);
if (is_performed == 0)
{
@@ -1171,10 +1218,70 @@ namespace Actions
return NULL;
}
void *InstallRpiUrlPkgThread(void *argp)
{
json_object *params = json_object_new_object();
json_object_object_add(params, "url", json_object_new_string(install_pkg_url.url));
json_object_object_add(params, "use_alldebrid", json_object_new_boolean(install_pkg_url.enable_alldebrid));
json_object_object_add(params, "use_realdebrid", json_object_new_boolean(install_pkg_url.enable_realdebrid));
json_object_object_add(params, "use_disk_cache", json_object_new_boolean(install_pkg_url.enable_disk_cache));
const char *params_str = json_object_to_json_string(params);
char host[128];
sprintf(host, "http://127.0.0.1:%d", http_server_port);
httplib::Client tmp_client(host);
tmp_client.set_keep_alive(true);
tmp_client.set_follow_location(true);
tmp_client.set_connection_timeout(30);
tmp_client.set_read_timeout(30);
tmp_client.enable_server_certificate_verification(false);
auto res = tmp_client.Post("/__local__/install_url", params_str, strlen(params_str), "application/json");
if (res != nullptr && HTTP_SUCCESS(res->status))
{
json_object *jobj = json_tokener_parse(res->body.c_str());
if (jobj != nullptr)
{
json_object *result = json_object_object_get(jobj, "result");
if (result != nullptr)
{
bool success = json_object_get_boolean(json_object_object_get(result, "success"));
if (!success)
{
const char* error_message = json_object_get_string(json_object_object_get(result, "error"));
sprintf(status_message, "%s", error_message);
activity_inprogess = false;
Windows::SetModalMode(false);
}
}
}
else
{
activity_inprogess = false;
Windows::SetModalMode(false);
}
}
else
{
activity_inprogess = false;
Windows::SetModalMode(false);
}
return NULL;
}
void InstallUrlPkg()
{
int res;
sprintf(status_message, "%s", "");
int res = pthread_create(&bk_activity_thid, NULL, InstallUrlPkgThread, NULL);
if (!install_pkg_url.enable_rpi)
res = pthread_create(&bk_activity_thid, NULL, InstallLocalUrlPkgThread, NULL);
else
res = pthread_create(&bk_activity_thid, NULL, InstallRpiUrlPkgThread, NULL);
if (res != 0)
{
activity_inprogess = false;
@@ -1203,6 +1310,10 @@ namespace Actions
remoteclient = new NpxServeClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_RCLONE) == 0)
remoteclient = new RCloneClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_ARCHIVEORG) == 0)
remoteclient = new ArchiveOrgClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_MYRIENT) == 0)
remoteclient = new MyrientClient();
}
else if (strncmp(remote_settings->server, "webdavs://", 10) == 0 || strncmp(remote_settings->server, "webdav://", 9) == 0)
{
@@ -1337,6 +1448,7 @@ namespace Actions
if (confirm_state == CONFIRM_YES)
{
sceRtcGetCurrentTick(&prev_tick);
if (isCopy)
return FS::Copy(src, dest);
else
@@ -1384,6 +1496,7 @@ namespace Actions
snprintf(activity_message, 1024, "%s %s", isCopy ? lang_strings[STR_COPYING] : lang_strings[STR_MOVING], entries[i].path);
bytes_to_download = entries[i].file_size;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
ret = CopyOrMoveLocalFile(entries[i].path, new_path, isCopy);
if (ret <= 0)
{
@@ -1538,6 +1651,7 @@ namespace Actions
if (confirm_state == CONFIRM_YES)
{
sceRtcGetCurrentTick(&prev_tick);
if (isCopy)
return remoteclient->Copy(src, dest);
else
@@ -1633,6 +1747,7 @@ namespace Actions
snprintf(activity_message, 1024, "%s %s", lang_strings[STR_COPYING], entries[i].path);
bytes_to_download = entries[i].file_size;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
ret = CopyOrMoveRemoteFile(entries[i].path, new_path, true);
if (ret <= 0)
{
@@ -1726,6 +1841,7 @@ namespace Actions
sprintf(activity_message, "%s %s to %s", lang_strings[STR_DOWNLOADING], filename.c_str(), local_file);
remoteclient->Size(filename, &bytes_to_download);
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
file_transfering = true;
int ret = remoteclient->Get(local_file, filename);
if (ret == 0)
+5 -3
View File
@@ -1,5 +1,5 @@
#ifndef ACTIONS_H
#define ACTIONS_H
#ifndef EZ_ACTIONS_H
#define EZ_ACTIONS_H
#include <pthread.h>
#include "installer.h"
@@ -99,7 +99,8 @@ namespace Actions
void InstallRemotePkgs();
void *InstallLocalPkgsThread(void *argp);
void InstallLocalPkgs();
void *InstallUrlPkgThread(void *argp);
void *InstallLocalUrlPkgThread(void *argp);
void *InstallRpiUrlPkgThread(void *argp);
void InstallUrlPkg();
void *KeepAliveThread(void *argp);
void *ExtractZipThread(void *argp);
@@ -120,6 +121,7 @@ namespace Actions
void CreateLocalFile(char *filename);
void CreateRemoteFile(char *filename);
void *ExtractArchivePkg(void *argp);
void *DownloadSplitPkg(void *argp);
}
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef BASE64_H_
#define BASE64_H_
#ifndef EZ_BASE64_H_
#define EZ_BASE64_H_
#include <string>
+23 -10
View File
@@ -128,18 +128,31 @@ std::vector<DirEntry> ApacheClient::ListDir(const std::string &path)
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("td") == 0)
{
value = lxb_dom_node_text_content(node, &value_len);
// get the child <a> element
lxb_dom_node_t *a_node = NextChildElement(lxb_dom_interface_element(node));
if (a_node == nullptr) continue;
value = lxb_dom_element_local_name(lxb_dom_interface_element(a_node), &value_len);
tmp_string = std::string((const char *)value, value_len);
tmp_string = Util::Rtrim(tmp_string, "/");
sprintf(entry.name, "%s", tmp_string.c_str());
sprintf(entry.directory, "%s", path.c_str());
if (path.length() > 0 && path[path.length() - 1] == '/')
if (tmp_string.compare("a") == 0)
{
sprintf(entry.path, "%s%s", path.c_str(), entry.name);
}
else
{
sprintf(entry.path, "%s/%s", path.c_str(), entry.name);
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(a_node), (const lxb_char_t *)"href", 4, &value_len);
tmp_string = std::string((const char *)value, value_len);
tmp_string = Util::Rtrim(tmp_string, "/");
tmp_string = BaseClient::UnEscape(tmp_string);
if (tmp_string.compare("..") != 0)
{
sprintf(entry.directory, "%s", path.c_str());
sprintf(entry.name, "%s", tmp_string.c_str());
if (path.length() > 0 && path[path.length() - 1] == '/')
{
sprintf(entry.path, "%s%s", path.c_str(), entry.name);
}
else
{
sprintf(entry.path, "%s/%s", path.c_str(), entry.name);
}
}
}
}
else continue; // not valid record
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef APACHE_H
#define APACHE_H
#ifndef EZ_APACHE_H
#define EZ_APACHE_H
#include <string>
#include <vector>
+239
View File
@@ -0,0 +1,239 @@
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <lexbor/dom/interfaces/node.h>
#include <fstream>
#include <map>
#include "common.h"
#include "clients/remote_client.h"
#include "clients/archiveorg.h"
#include "lang.h"
#include "util.h"
#include "system.h"
#include "windows.h"
using httplib::Client;
using httplib::Headers;
using httplib::Result;
static std::map<std::string, int> month_map = {{"Jan", 1}, {"Feb", 2}, {"Mar", 3}, {"Apr", 4}, {"May", 5}, {"Jun", 6}, {"Jul", 7}, {"Aug", 8}, {"Sep", 9}, {"Oct", 10}, {"Nov", 11}, {"Dec", 12}};
std::vector<DirEntry> ArchiveOrgClient::ListDir(const std::string &path)
{
std::vector<DirEntry> out;
DirEntry entry;
Util::SetupPreviousFolder(path, &entry);
out.push_back(entry);
std::string encoded_path = httplib::detail::encode_url(GetFullPath(path) + "/");
if (auto res = client->Get(encoded_path))
{
lxb_status_t status;
lxb_dom_attr_t *attr;
lxb_dom_element_t *table_element, *tr_element, *td_element;
lxb_html_document_t *document;
lxb_dom_collection_t *table_collection;
lxb_dom_collection_t *tr_collection;
lxb_dom_collection_t *td_collection;
std::string tmp_string;
const lxb_char_t *value;
size_t value_len;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
{
lxb_html_document_destroy(document);
goto finish;
}
table_collection = lxb_dom_collection_make(&document->dom_document, 1);
if (table_collection == NULL)
{
lxb_html_document_destroy(document);
goto finish;
}
tr_collection = lxb_dom_collection_make(&document->dom_document, 128);
if (tr_collection == NULL)
{
lxb_html_document_destroy(document);
goto finish;
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
table_collection, (const lxb_char_t *)"table", 5);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
if (lxb_dom_collection_length(table_collection) < 1)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
for (size_t i = 0; i < lxb_dom_collection_length(table_collection); i++)
{
table_element = lxb_dom_collection_element(table_collection, i);
value = lxb_dom_element_class(table_element, &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("directory-listing-table") == 0)
break;
table_element = nullptr;
}
if (table_element == nullptr)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
status = lxb_dom_elements_by_tag_name(table_element,
tr_collection, (const lxb_char_t *)"tr", 2);
if (status != LXB_STATUS_OK && lxb_dom_collection_length(tr_collection) < 2)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// skip row 0 , since it has the previous folder header
for (size_t i = 2; i < lxb_dom_collection_length(tr_collection); i++)
{
DirEntry entry;
std::string title, aclass;
memset(&entry.modified, 0, sizeof(DateTime));
tr_element = lxb_dom_collection_element(tr_collection, i);
td_collection = lxb_dom_collection_make(&document->dom_document, 5);
status = lxb_dom_elements_by_tag_name(tr_element,
td_collection, (const lxb_char_t *)"td", 2);
if (status != LXB_STATUS_OK || lxb_dom_collection_length(td_collection) < 3)
{
lxb_dom_collection_destroy(td_collection, true);
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// td0 contains the <a> tag
td_element = lxb_dom_collection_element(td_collection, 0);
lxb_dom_node_t *a_node = NextChildElement(td_element);
value = lxb_dom_element_local_name(lxb_dom_interface_element(a_node), &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("a") != 0)
{
lxb_dom_collection_destroy(td_collection, true);
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(a_node), (const lxb_char_t *)"href", 4, &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string[tmp_string.length()-1] == '/')
tmp_string = tmp_string.substr(0, tmp_string.length()-1);
tmp_string = BaseClient::UnEscape(tmp_string);
sprintf(entry.name, "%s", tmp_string.c_str());
sprintf(entry.directory, "%s", path.c_str());
if (path.length() > 0 && path[path.length() - 1] == '/')
{
sprintf(entry.path, "%s%s", path.c_str(), entry.name);
}
else
{
sprintf(entry.path, "%s/%s", path.c_str(), entry.name);
}
// next td contains the date
td_element = lxb_dom_collection_element(td_collection, 1);
value = lxb_dom_node_text_content(NextChildTextNode(td_element), &value_len);
tmp_string = std::string((const char *)value, value_len);
std::vector<std::string> date_time = Util::Split(tmp_string, " ");
if (date_time.size() > 1)
{
std::vector<std::string> adate = Util::Split(date_time[0], "-");
if (adate.size() == 3)
{
entry.modified.day = atoi(adate[0].c_str());
entry.modified.month = month_map[adate[1]];
entry.modified.year = atoi(adate[2].c_str());
}
std::vector<std::string> atime = Util::Split(date_time[1], ":");
if (atime.size() == 2)
{
entry.modified.hours = atoi(atime[0].c_str());
entry.modified.minutes = atoi(atime[1].c_str());
}
}
// next td contains file size, if fize size is "-", then it's a directory
td_element = lxb_dom_collection_element(td_collection, 2);
value = lxb_dom_node_text_content(NextChildTextNode(td_element), &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("-") == 0)
{
entry.isDir = true;
entry.selectable = true;
entry.file_size = 0;
sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]);
}
else
{
entry.isDir = false;
entry.selectable = true;
uint64_t multiplier = 0;
std::string size_formatted = tmp_string.substr(0, tmp_string.size()-1);
Util::ReplaceAll(size_formatted, ",", "");
float fsize = std::stof(size_formatted);
switch (tmp_string[tmp_string.size()-1]) {
case 'B':
multiplier = 1;
break;
case 'K':
multiplier = 1024;
break;
case 'M':
multiplier = 1048576;
break;
case 'G':
multiplier = 1073741824;
break;
default:
multiplier = 1;
}
entry.file_size = fsize * multiplier;
DirEntry::SetDisplaySize(&entry);
}
lxb_dom_collection_destroy(td_collection, true);
out.push_back(entry);
}
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
}
else
{
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
return out;
}
finish:
return out;
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef EZ_ARCHIVEORG_H
#define EZ_ARCHIVEORG_H
#include <string>
#include <vector>
#include "http/httplib.h"
#include "clients/remote_client.h"
#include "clients/baseclient.h"
#include "common.h"
class ArchiveOrgClient : public BaseClient
{
public:
std::vector<DirEntry> ListDir(const std::string &path);
};
#endif
+73
View File
@@ -90,6 +90,31 @@ int BaseClient::Size(const std::string &path, int64_t *size)
*size = atoll(content_length.c_str());
return 1;
}
else if (res->status == 405)// Server doesn't support HEAD request. Try get range with 0 bytes and grab size from the response header
// example: Content-Range: bytes 0-10/4372785
{
Headers headers = {{"Range", "bytes=0-1"}};
if (auto range_res = client->Get(GetFullPath(path), headers))
{
if (HTTP_SUCCESS(range_res->status))
{
if (range_res->has_header("Content-Range"))
{
std::string range = range_res->get_header_value("Content-Range");
std::vector<std::string> range_parts = Util::Split(range, "/");
if (range_parts.size() == 2)
{
*size = atoll(range_parts[1].c_str());
return 1;
}
}
}
}
}
else
{
sprintf(this->response, "%d - %s", res->status, detail::status_message(res->status));
}
}
else
{
@@ -102,6 +127,8 @@ int BaseClient::Get(const std::string &outputfile, const std::string &path, uint
{
std::ofstream file_stream(outputfile, std::ios::binary);
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
if (auto res = client->Get(GetFullPath(path),
[&](const char *data, size_t data_length)
{
@@ -120,6 +147,29 @@ int BaseClient::Get(const std::string &outputfile, const std::string &path, uint
return 0;
}
int BaseClient::Get(SplitFile *split_file, const std::string &path, uint64_t offset)
{
if (auto res = client->Get(GetFullPath(path),
[&](const char *data, size_t data_length)
{
if (!split_file->IsClosed())
{
split_file->Write((char*)data, data_length);
return true;
}
else
return false;
}))
{
return 1;
}
else
{
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
}
return 0;
}
int BaseClient::GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset)
{
char range_header[64];
@@ -345,3 +395,26 @@ std::string BaseClient::UnEscape(const std::string &url)
}
return "";
}
void *BaseClient::Open(const std::string &path, int flags)
{
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
return nullptr;
}
void BaseClient::Close(void *fp)
{
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
}
int BaseClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
{
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
return -1;
}
int BaseClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
{
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
return -1;
}
+8 -2
View File
@@ -1,5 +1,5 @@
#ifndef BASESERVER_H
#define BASESERVER_H
#ifndef EZ_BASESERVER_H
#define EZ_BASESERVER_H
#include <string>
#include <vector>
@@ -8,6 +8,7 @@
#include "http/httplib.h"
#include "clients/remote_client.h"
#include "http/httplib.h"
#include "split_file.h"
#include "common.h"
class BaseClient : public RemoteClient
@@ -21,8 +22,11 @@ public:
int Rmdir(const std::string &path, bool recursive);
int Size(const std::string &path, int64_t *size);
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
int Rename(const std::string &src, const std::string &dst);
int Delete(const std::string &path);
@@ -33,6 +37,8 @@ public:
std::vector<DirEntry> ListDir(const std::string &path);
std::string GetPath(std::string path1, std::string path2);
std::string GetFullPath(std::string path1);
void *Open(const std::string &path, int flags);
void Close(void *fp);
bool IsConnected();
bool Ping();
const char *LastResponse();
+56 -2
View File
@@ -880,6 +880,32 @@ int FtpClient::FtpXfer(const std::string &localfile, const std::string &path, ft
return FtpClose(nData);
}
/*
* FtpXfer - issue a command and transfer data
*
* return 1 if successful, 0 otherwise
*/
int FtpClient::FtpXfer(SplitFile *split_file, const std::string &path, ftphandle *nControl, accesstype type, transfermode mode)
{
int l, c;
char *dbuf;
ftphandle *nData;
if (!FtpAccess(path, type, mode, nControl, &nData))
{
return 0;
}
dbuf = static_cast<char *>(malloc(FTP_CLIENT_BUFSIZ));
while ((l = FtpRead(dbuf, FTP_CLIENT_BUFSIZ, nData)) > 0)
{
split_file->Write(dbuf, l);
}
free(dbuf);
return FtpClose(nData);
}
/*
* FtpWrite - write to a data connection
*/
@@ -1283,6 +1309,15 @@ int FtpClient::Get(const std::string &outputfile, const std::string &path, uint6
return FtpXfer(outputfile, path, mp_ftphandle, FtpClient::filereadappend, FtpClient::transfermode::image);
}
int FtpClient::Get(SplitFile *split_file, const std::string &path, uint64_t offset)
{
mp_ftphandle->offset = offset;
if (offset == 0)
return FtpXfer(split_file, path, mp_ftphandle, FtpClient::fileread, FtpClient::transfermode::image);
else
return FtpXfer(split_file, path, mp_ftphandle, FtpClient::filereadappend, FtpClient::transfermode::image);
}
int FtpClient::GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset)
{
ftphandle *nData;
@@ -1744,7 +1779,7 @@ ClientType FtpClient::clientType()
uint32_t FtpClient::SupportedActions()
{
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_CUT ^ REMOTE_ACTION_COPY ^ REMOTE_ACTION_PASTE;
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_CUT ^ REMOTE_ACTION_COPY ^ REMOTE_ACTION_PASTE ^ REMOTE_ACTION_RAW_READ;
}
std::string FtpClient::GetPath(std::string ppath1, std::string ppath2)
@@ -1783,4 +1818,23 @@ int FtpClient::Head(const std::string &path, void *buffer, uint64_t len)
if (l != len)
return 0;
return 1;
}
}
void *FtpClient::Open(const std::string &path, int flags)
{
return nullptr;
}
void FtpClient::Close(void *fp)
{
}
int FtpClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
{
return -1;
}
int FtpClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
{
return -1;
}
+8 -2
View File
@@ -1,5 +1,5 @@
#ifndef FTPCLIENT_H
#define FTPCLIENT_H
#ifndef EZ_FTPCLIENT_H
#define EZ_FTPCLIENT_H
#include <sys/socket.h>
#include <arpa/inet.h>
@@ -79,14 +79,19 @@ public:
int Rmdir(const std::string &path, bool recursive);
int Size(const std::string &path, int64_t *size);
int Get(const std::string &outputfile, const std::string &path, uint64_t offset = 0);
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
int Put(const std::string &inputfile, const std::string &path, uint64_t offset = 0);
int Rename(const std::string &src, const std::string &dst);
int Delete(const std::string &path);
int Copy(const std::string &from, const std::string &to);
int Move(const std::string &from, const std::string &to);
int Head(const std::string &path, void *buffer, uint64_t len);
void *Open(const std::string &path, int flags);
void Close(void *fp);
std::vector<DirEntry> ListDir(const std::string &path);
void SetCallbackXferFunction(FtpCallbackXfer pointer);
void SetCallbackArg(void *arg);
@@ -124,6 +129,7 @@ private:
int CorrectPasvResponse(int *v);
int FtpAccess(const std::string &path, accesstype type, transfermode mode, ftphandle *nControl, ftphandle **nData);
int FtpXfer(const std::string &localfile, const std::string &path, ftphandle *nControl, accesstype type, transfermode mode);
int FtpXfer(SplitFile *split_file, const std::string &path, ftphandle *nControl, accesstype type, transfermode mode);
int FtpWrite(void *buf, int len, ftphandle *nData);
int FtpRead(void *buf, int max, ftphandle *nData);
int FtpClose(ftphandle *nData);
+56 -4
View File
@@ -307,6 +307,7 @@ int GDriveClient::Get(const std::string &outputfile, const std::string &path, ui
{
std::ofstream file_stream(outputfile, std::ios::binary);
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
std::string id = GetValue(path_id_map, path);
std::string drive_id = GetDriveId(path);
@@ -331,6 +332,34 @@ int GDriveClient::Get(const std::string &outputfile, const std::string &path, ui
return 0;
}
int GDriveClient::Get(SplitFile *split_file, const std::string &path, uint64_t offset)
{
std::string id = GetValue(path_id_map, path);
std::string drive_id = GetDriveId(path);
std::string url = std::string("/drive/v3/files/") + BaseClient::Escape(id) + "?alt=media";
if (!drive_id.empty())
url += "&supportsAllDrives=true";
if (auto res = client->Get(url,
[&](const char *data, size_t data_length)
{
if (!split_file->IsClosed())
{
split_file->Write((char*)data, data_length);
return true;
}
else
return false;
}))
{
return 1;
}
else
{
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
}
return 0;
}
int GDriveClient::GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset)
{
size_t bytes_read = 0;
@@ -399,9 +428,9 @@ int GDriveClient::Update(const std::string &inputfile, const std::string &path)
{
bytes_to_download = FS::GetSize(inputfile);
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
std::ifstream file_stream(inputfile, std::ios::binary);
bytes_transfered = 0;
std::string id = GetValue(path_id_map, path);
std::string drive_id = GetDriveId(path);
@@ -473,9 +502,9 @@ int GDriveClient::Put(const std::string &inputfile, const std::string &path, uin
bytes_to_download = FS::GetSize(inputfile);
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
std::ifstream file_stream(inputfile, std::ios::binary);
bytes_transfered = 0;
size_t path_pos = path.find_last_of("/");
std::string parent_dir;
@@ -887,7 +916,7 @@ ClientType GDriveClient::clientType()
uint32_t GDriveClient::SupportedActions()
{
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_CUT ^ REMOTE_ACTION_COPY ^ REMOTE_ACTION_PASTE;
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_CUT ^ REMOTE_ACTION_COPY ^ REMOTE_ACTION_PASTE ^ REMOTE_ACTION_RAW_READ;
}
void *GDriveClient::RefreshTokenThread(void *argp)
@@ -941,4 +970,27 @@ void GDriveClient::SetAccessToken(const std::string &token)
{
if (this->client != nullptr)
this->client->set_bearer_token_auth(token);
}
}
void *GDriveClient::Open(const std::string &path, int flags)
{
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
return nullptr;
}
void GDriveClient::Close(void *fp)
{
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
}
int GDriveClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
{
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
return -1;
}
int GDriveClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
{
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
return -1;
}
+7 -2
View File
@@ -1,5 +1,5 @@
#ifndef GDRIVE_H
#define GDRIVE_H
#ifndef EZ_GDRIVE_H
#define EZ_GDRIVE_H
#include <string>
#include <vector>
@@ -20,8 +20,11 @@ public:
int Connect(const std::string &url, const std::string &user, const std::string &pass);
int Rename(const std::string &src, const std::string &dst);
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
int Head(const std::string &path, void *buffer, uint64_t len);
int Update(const std::string &inputfile, const std::string &path);
@@ -32,6 +35,8 @@ public:
bool FileExists(const std::string &path);
void SetAccessToken(const std::string &token);
std::vector<DirEntry> ListDir(const std::string &path);
void *Open(const std::string &path, int flags);
void Close(void *fp);
static void *RefreshTokenThread(void *argp);
static void StartRefreshToken();
static void StopRefreshToken();
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef IIS_H
#define IIS_H
#ifndef EZ_IIS_H
#define EZ_IIS_H
#include <string>
#include <vector>
+241
View File
@@ -0,0 +1,241 @@
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <lexbor/dom/interfaces/node.h>
#include <fstream>
#include <map>
#include "common.h"
#include "clients/remote_client.h"
#include "clients/myrient.h"
#include "lang.h"
#include "util.h"
#include "system.h"
#include "windows.h"
using httplib::Client;
using httplib::Headers;
using httplib::Result;
static std::map<std::string, int> month_map = {{"Jan", 1}, {"Feb", 2}, {"Mar", 3}, {"Apr", 4}, {"May", 5}, {"Jun", 6}, {"Jul", 7}, {"Aug", 8}, {"Sep", 9}, {"Oct", 10}, {"Nov", 11}, {"Dec", 12}};
std::vector<DirEntry> MyrientClient::ListDir(const std::string &path)
{
std::vector<DirEntry> out;
DirEntry entry;
Util::SetupPreviousFolder(path, &entry);
out.push_back(entry);
std::string encoded_path = httplib::detail::encode_url(GetFullPath(path) + "/");
if (auto res = client->Get(encoded_path))
{
lxb_status_t status;
lxb_dom_attr_t *attr;
lxb_dom_element_t *table_element, *tr_element, *td_element;
lxb_html_document_t *document;
lxb_dom_collection_t *table_collection;
lxb_dom_collection_t *tr_collection;
lxb_dom_collection_t *td_collection;
std::string tmp_string;
const lxb_char_t *value;
size_t value_len;
document = lxb_html_document_create();
status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length());
if (status != LXB_STATUS_OK)
{
lxb_html_document_destroy(document);
goto finish;
}
table_collection = lxb_dom_collection_make(&document->dom_document, 1);
if (table_collection == NULL)
{
lxb_html_document_destroy(document);
goto finish;
}
tr_collection = lxb_dom_collection_make(&document->dom_document, 128);
if (tr_collection == NULL)
{
lxb_html_document_destroy(document);
goto finish;
}
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
table_collection, (const lxb_char_t *)"table", 5);
if (status != LXB_STATUS_OK)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
if (lxb_dom_collection_length(table_collection) < 1)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
for (size_t i = 0; i < lxb_dom_collection_length(table_collection); i++)
{
table_element = lxb_dom_collection_element(table_collection, i);
value = lxb_dom_element_id(table_element, &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("list") == 0)
break;
table_element = nullptr;
}
if (table_element == nullptr)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
status = lxb_dom_elements_by_tag_name(table_element,
tr_collection, (const lxb_char_t *)"tr", 2);
if (status != LXB_STATUS_OK && lxb_dom_collection_length(tr_collection) < 2)
{
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// skip row 0 , since it has the previous folder header
for (size_t i = 2; i < lxb_dom_collection_length(tr_collection); i++)
{
DirEntry entry;
std::string title, aclass;
memset(&entry.modified, 0, sizeof(DateTime));
tr_element = lxb_dom_collection_element(tr_collection, i);
td_collection = lxb_dom_collection_make(&document->dom_document, 5);
status = lxb_dom_elements_by_tag_name(tr_element,
td_collection, (const lxb_char_t *)"td", 2);
if (status != LXB_STATUS_OK || lxb_dom_collection_length(td_collection) < 3)
{
lxb_dom_collection_destroy(td_collection, true);
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
// td0 contains the <a> tag
td_element = lxb_dom_collection_element(td_collection, 0);
lxb_dom_node_t *a_node = NextChildElement(td_element);
value = lxb_dom_element_local_name(lxb_dom_interface_element(a_node), &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("a") != 0)
{
lxb_dom_collection_destroy(td_collection, true);
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
goto finish;
}
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(a_node), (const lxb_char_t *)"href", 4, &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string[tmp_string.length()-1] == '/')
tmp_string = tmp_string.substr(0, tmp_string.length()-1);
tmp_string = BaseClient::UnEscape(tmp_string);
sprintf(entry.name, "%s", tmp_string.c_str());
sprintf(entry.directory, "%s", path.c_str());
if (path.length() > 0 && path[path.length() - 1] == '/')
{
sprintf(entry.path, "%s%s", path.c_str(), entry.name);
}
else
{
sprintf(entry.path, "%s/%s", path.c_str(), entry.name);
}
// next td contains file size, if fize size is "-", then it's a directory
td_element = lxb_dom_collection_element(td_collection, 1);
value = lxb_dom_node_text_content(NextChildTextNode(td_element), &value_len);
tmp_string = std::string((const char *)value, value_len);
if (tmp_string.compare("-") == 0)
{
entry.isDir = true;
entry.selectable = true;
entry.file_size = 0;
sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]);
}
else
{
entry.isDir = false;
entry.selectable = true;
uint64_t multiplier = 1;
std::vector<std::string> fsize_parts = Util::Split(tmp_string, " ");
float fsize = std::stof(fsize_parts[0]);
if (fsize_parts.size() > 1)
{
switch (fsize_parts[1][0])
{
case 'K':
multiplier = 1024;
break;
case 'M':
multiplier = 1048576;
break;
case 'G':
multiplier = 1073741824;
break;
default:
multiplier = 1;
}
}
entry.file_size = fsize * multiplier;
DirEntry::SetDisplaySize(&entry);
}
// next td contains the date
td_element = lxb_dom_collection_element(td_collection, 2);
value = lxb_dom_node_text_content(NextChildTextNode(td_element), &value_len);
tmp_string = std::string((const char *)value, value_len);
std::vector<std::string> date_time = Util::Split(tmp_string, " ");
if (date_time.size() > 1)
{
std::vector<std::string> adate = Util::Split(date_time[0], "-");
if (adate.size() == 3)
{
entry.modified.day = atoi(adate[0].c_str());
entry.modified.month = month_map[adate[1]];
entry.modified.year = atoi(adate[2].c_str());
}
std::vector<std::string> atime = Util::Split(date_time[1], ":");
if (atime.size() == 2)
{
entry.modified.hours = atoi(atime[0].c_str());
entry.modified.minutes = atoi(atime[1].c_str());
}
}
lxb_dom_collection_destroy(td_collection, true);
out.push_back(entry);
}
lxb_dom_collection_destroy(tr_collection, true);
lxb_dom_collection_destroy(table_collection, true);
lxb_html_document_destroy(document);
}
else
{
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
return out;
}
finish:
return out;
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef EZ_MYRIENT_H
#define EZ_MYRIENT_H
#include <string>
#include <vector>
#include "http/httplib.h"
#include "clients/remote_client.h"
#include "clients/baseclient.h"
#include "common.h"
class MyrientClient : public BaseClient
{
public:
std::vector<DirEntry> ListDir(const std::string &path);
};
#endif
+94 -38
View File
@@ -17,7 +17,7 @@
#include "util.h"
#include "system.h"
#define BUF_SIZE 256*1024
#define BUF_SIZE 256 * 1024
NfsClient::NfsClient()
{
@@ -37,7 +37,8 @@ int NfsClient::Connect(const std::string &url, const std::string &user, const st
}
struct nfs_url *nfsurl = nfs_parse_url_full(nfs, url.c_str());
if (nfsurl == nullptr) {
if (nfsurl == nullptr)
{
sprintf(response, "%s", nfs_get_error(nfs));
nfs_destroy_context(nfs);
return 0;
@@ -203,7 +204,7 @@ int NfsClient::Get(const std::string &outputfile, const std::string &ppath, uint
return 0;
}
FILE* out = FS::Create(outputfile);
FILE *out = FS::Create(outputfile);
if (out == NULL)
{
sprintf(response, "%s", lang_strings[STR_FAILED]);
@@ -213,6 +214,7 @@ int NfsClient::Get(const std::string &outputfile, const std::string &ppath, uint
void *buff = malloc(BUF_SIZE);
int count = 0;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
while ((count = nfs_read(nfs, nfsfh, BUF_SIZE, buff)) > 0)
{
if (count < 0)
@@ -220,7 +222,7 @@ int NfsClient::Get(const std::string &outputfile, const std::string &ppath, uint
sprintf(response, "%s", nfs_get_error(nfs));
FS::Close(out);
nfs_close(nfs, nfsfh);
free((void*)buff);
free((void *)buff);
return 0;
}
FS::Write(out, buff, count);
@@ -228,7 +230,36 @@ int NfsClient::Get(const std::string &outputfile, const std::string &ppath, uint
}
FS::Close(out);
nfs_close(nfs, nfsfh);
free((void*)buff);
free((void *)buff);
return 1;
}
int NfsClient::Get(SplitFile *split_file, const std::string &ppath, uint64_t offset)
{
struct nfsfh *nfsfh = nullptr;
int ret = nfs_open(nfs, ppath.c_str(), 0400, &nfsfh);
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
void *buff = malloc(BUF_SIZE);
int count = 0;
while ((count = nfs_read(nfs, nfsfh, BUF_SIZE, buff)) > 0)
{
if (count < 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
nfs_close(nfs, nfsfh);
free((void *)buff);
return 0;
}
split_file->Write((char *)buff, count);
}
nfs_close(nfs, nfsfh);
free((void *)buff);
return 1;
}
@@ -242,49 +273,51 @@ int NfsClient::GetRange(const std::string &path, DataSink &sink, uint64_t size,
return 0;
}
ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
ret = this->GetRange((void *)nfsfh, sink, size, offset);
nfs_close(nfs, nfsfh);
return ret;
}
int NfsClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
{
struct nfsfh *nfsfh = (struct nfsfh *)fp;
int ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
if (ret != 0)
{
return 0;
}
void *buff = malloc(BUF_SIZE);
int count = 0;
size_t bytes_remaining = size;
do
{
size_t bytes_to_read = std::min<size_t>(BUF_SIZE, bytes_remaining);
count = nfs_read(nfs, nfsfh, bytes_to_read, buff);
if (count > 0)
{
bytes_remaining -= count;
bool ok = sink.write((char*)buff, count);
int count = 0;
size_t bytes_remaining = size;
do
{
size_t bytes_to_read = std::min<size_t>(BUF_SIZE, bytes_remaining);
count = nfs_read(nfs, nfsfh, bytes_to_read, buff);
if (count > 0)
{
bytes_remaining -= count;
bool ok = sink.write((char *)buff, count);
if (!ok)
{
free((void *)buff);
nfs_close(nfs, nfsfh);
return 0;
}
}
else
{
break;
}
} while (1);
free((void *)buff);
nfs_close(nfs, nfsfh);
}
else
{
break;
}
} while (1);
free((void *)buff);
return 1;
}
int NfsClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, uint64_t offset)
{
if (!FileExists(ppath))
{
return 0;
}
struct nfsfh *nfsfh = nullptr;
int ret = nfs_open(nfs, ppath.c_str(), 0400, &nfsfh);
if (ret != 0)
@@ -293,7 +326,17 @@ int NfsClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, u
return 0;
}
ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
ret = this->GetRange(nfsfh, buffer, size, offset);
nfs_close(nfs, nfsfh);
return ret;
}
int NfsClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
{
struct nfsfh *nfsfh = (struct nfsfh *)fp;
int ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
@@ -301,7 +344,6 @@ int NfsClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, u
}
int count = nfs_read(nfs, nfsfh, size, buffer);
nfs_close(nfs, nfsfh);
if (count != size)
return 0;
@@ -346,13 +388,13 @@ int NfsClient::Put(const std::string &inputfile, const std::string &ppath, uint6
return 0;
}
FILE* in = FS::OpenRead(inputfile);
FILE *in = FS::OpenRead(inputfile);
if (in == NULL)
{
sprintf(response, "%s", lang_strings[STR_FAILED]);
return 0;
}
struct nfsfh *nfsfh = nullptr;
int ret;
if (!FileExists(ppath))
@@ -368,9 +410,10 @@ int NfsClient::Put(const std::string &inputfile, const std::string &ppath, uint6
return 0;
}
void* buff = malloc(BUF_SIZE);
void *buff = malloc(BUF_SIZE);
uint64_t count = 0;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
while ((count = FS::Read(in, buff, BUF_SIZE)) > 0)
{
if (count < 0)
@@ -446,7 +489,8 @@ std::vector<DirEntry> NfsClient::ListDir(const std::string &path)
struct nfsdirent *nfsdirent;
int ret = nfs_opendir(nfs, path.c_str(), &nfsdir);
if (ret != 0) {
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return out;
}
@@ -513,7 +557,6 @@ std::vector<DirEntry> NfsClient::ListDir(const std::string &path)
}
if (strcmp(entry.name, "..") != 0 && strcmp(entry.name, ".") != 0)
out.push_back(entry);
}
nfs_closedir(nfs, nfsdir);
@@ -553,6 +596,19 @@ int NfsClient::Head(const std::string &ppath, void *buffer, uint64_t len)
return 1;
}
void *NfsClient::Open(const std::string &path, int flags)
{
struct nfsfh *nfsfh = nullptr;
nfs_open(nfs, path.c_str(), 0400, &nfsfh);
;
return nfsfh;
}
void NfsClient::Close(void *fp)
{
nfs_close(nfs, (struct nfsfh *)fp);
}
ClientType NfsClient::clientType()
{
return CLIENT_TYPE_NFS;
+7 -2
View File
@@ -1,5 +1,5 @@
#ifndef NFSCLIENT_H
#define NFSCLIENT_H
#ifndef EZ_NFSCLIENT_H
#define EZ_NFSCLIENT_H
#include <sys/socket.h>
#include <arpa/inet.h>
@@ -23,8 +23,11 @@ public:
int Rmdir(const std::string &path, bool recursive);
int Size(const std::string &path, int64_t *size);
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
int Rename(const std::string &src, const std::string &dst);
int Delete(const std::string &path);
@@ -32,6 +35,8 @@ public:
int Copy(const std::string &from, const std::string &to);
int Move(const std::string &from, const std::string &to);
std::vector<DirEntry> ListDir(const std::string &path);
void *Open(const std::string &path, int flags);
void Close(void *fp);
bool IsConnected();
bool Ping();
const char *LastResponse();
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef NGINX_H
#define NGINX_H
#ifndef EZ_NGINX_H
#define EZ_NGINX_H
#include <string>
#include <vector>
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef NPXSERVE_H
#define NPXSERVE_H
#ifndef EZ_NPXSERVE_H
#define EZ_NPXSERVE_H
#include <string>
#include <vector>
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef RCLONE_H
#define RCLONE_H
#ifndef EZ_RCLONE_H
#define EZ_RCLONE_H
#include <string>
#include <vector>
+10 -3
View File
@@ -1,10 +1,11 @@
#ifndef REMOTECLIENT_H
#define REMOTECLIENT_H
#ifndef EZ_REMOTECLIENT_H
#define EZ_REMOTECLIENT_H
#include <string>
#include <vector>
#include "common.h"
#include "http/httplib.h"
#include "split_file.h"
enum RemoteActions
{
@@ -21,7 +22,8 @@ enum RemoteActions
REMOTE_ACTION_EDIT = 512,
REMOTE_ACTION_NEW_FILE = 1024,
REMOTE_ACTION_EXTRACT = 2048,
REMOTE_ACTION_ALL = 4095
REMOTE_ACTION_RAW_READ = 4096,
REMOTE_ACTION_ALL = 8191
};
enum ClientType
@@ -48,6 +50,7 @@ public:
virtual int Rmdir(const std::string &path, bool recursive) = 0;
virtual int Size(const std::string &path, int64_t *size) = 0;
virtual int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0) = 0;
virtual int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0) = 0;
virtual int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0) = 0;
virtual int Rename(const std::string &src, const std::string &dst) = 0;
virtual int Delete(const std::string &path) = 0;
@@ -56,8 +59,12 @@ public:
virtual int Head(const std::string &path, void *buffer, uint64_t len) = 0;
virtual int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset) = 0;
virtual int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset) = 0;
virtual int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset) = 0;
virtual int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset) = 0;
virtual bool FileExists(const std::string &path) = 0;
virtual std::vector<DirEntry> ListDir(const std::string &path) = 0;
virtual void *Open(const std::string &path, int flags) = 0;
virtual void Close(void *fp) = 0;
virtual std::string GetPath(std::string path1, std::string path2) = 0;
virtual bool IsConnected() = 0;
virtual bool Ping() = 0;
+65 -4
View File
@@ -284,6 +284,8 @@ int SFTPClient::Get(const std::string &outputfile, const std::string &path, uint
char *buff = (char *)malloc(FTP_CLIENT_BUFSIZ);
int rc, count = 0;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
do
{
rc = libssh2_sftp_read(sftp_handle, buff, FTP_CLIENT_BUFSIZ);
@@ -304,6 +306,36 @@ int SFTPClient::Get(const std::string &outputfile, const std::string &path, uint
return 1;
}
int SFTPClient::Get(SplitFile *split_file, const std::string &path, uint64_t offset)
{
LIBSSH2_SFTP_HANDLE *sftp_handle = libssh2_sftp_open(sftp_session, path.c_str(), LIBSSH2_FXF_READ, 0);
if (!sftp_handle)
{
sprintf(response, "Unable to open file with SFTP: %ld", libssh2_sftp_last_error(sftp_session));
return 0;
}
char *buff = (char *)malloc(FTP_CLIENT_BUFSIZ);
int rc, count = 0;
do
{
rc = libssh2_sftp_read(sftp_handle, buff, FTP_CLIENT_BUFSIZ);
if (rc > 0)
{
split_file->Write(buff, rc);
}
else
{
break;
}
} while (1);
free((char *)buff);
libssh2_sftp_close(sftp_handle);
return 1;
}
int SFTPClient::GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset)
{
LIBSSH2_SFTP_HANDLE *sftp_handle = libssh2_sftp_open(sftp_session, path.c_str(), LIBSSH2_FXF_READ, 0);
@@ -313,6 +345,16 @@ int SFTPClient::GetRange(const std::string &path, DataSink &sink, uint64_t size,
return 0;
}
int ret = this->GetRange((void *)sftp_handle, sink, size, offset);
libssh2_sftp_close(sftp_handle);
return ret;
}
int SFTPClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
{
LIBSSH2_SFTP_HANDLE *sftp_handle = (LIBSSH2_SFTP_HANDLE *)fp;
libssh2_sftp_seek64(sftp_handle, offset);
char *buff = (char *)malloc(FTP_CLIENT_BUFSIZ);
@@ -329,7 +371,6 @@ int SFTPClient::GetRange(const std::string &path, DataSink &sink, uint64_t size,
if (!ok)
{
free((char *)buff);
libssh2_sftp_close(sftp_handle);
return 0;
}
}
@@ -340,9 +381,8 @@ int SFTPClient::GetRange(const std::string &path, DataSink &sink, uint64_t size,
} while (1);
free((char *)buff);
libssh2_sftp_close(sftp_handle);
return 1;
return 1;
}
int SFTPClient::GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset)
@@ -359,9 +399,18 @@ int SFTPClient::GetRange(const std::string &path, void *buffer, uint64_t size, u
return 0;
}
int ret = this->GetRange(sftp_handle, buffer, size, offset);
libssh2_sftp_close(sftp_handle);
return ret;
}
int SFTPClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
{
LIBSSH2_SFTP_HANDLE *sftp_handle = (LIBSSH2_SFTP_HANDLE *)fp;
libssh2_sftp_seek64(sftp_handle, offset);
int count = libssh2_sftp_read(sftp_handle, (char *)buffer, size);
libssh2_sftp_close(sftp_handle);
if (count != size)
return 0;
@@ -401,6 +450,8 @@ int SFTPClient::Put(const std::string &inputfile, const std::string &path, uint6
buff = (char *)malloc(FTP_CLIENT_BUFSIZ);
int nread, count = 0;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
do
{
nread = FS::Read(in, buff, FTP_CLIENT_BUFSIZ);
@@ -642,6 +693,16 @@ int SFTPClient::Quit()
return 1;
}
void *SFTPClient::Open(const std::string &path, int flags)
{
return libssh2_sftp_open(sftp_session, path.c_str(), LIBSSH2_FXF_READ, 0);
}
void SFTPClient::Close(void *fp)
{
libssh2_sftp_close((LIBSSH2_SFTP_HANDLE *)fp);
}
ClientType SFTPClient::clientType()
{
return CLIENT_TYPE_SFTP;
+7 -2
View File
@@ -1,5 +1,5 @@
#ifndef SFTPCLIENT_H
#define SFTPCLIENT_H
#ifndef EZ_SFTPCLIENT_H
#define EZ_SFTPCLIENT_H
#include <libssh2.h>
#include <libssh2_sftp.h>
@@ -20,8 +20,11 @@ public:
int Rmdir(const std::string &path);
int Size(const std::string &path, int64_t *size);
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
int Rename(const std::string &src, const std::string &dst);
int Delete(const std::string &path);
@@ -30,6 +33,8 @@ public:
int Head(const std::string &path, void *buffer, uint64_t len);
bool FileExists(const std::string &path);
std::vector<DirEntry> ListDir(const std::string &path);
void *Open(const std::string &path, int flags);
void Close(void *fp);
std::string GetPath(std::string path1, std::string path2);
bool IsConnected();
bool Ping();
+123 -43
View File
@@ -197,23 +197,25 @@ int SmbClient::Get(const std::string &outputfile, const std::string &ppath, uint
return 0;
}
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
if (in == NULL)
{
sprintf(response, "%s", smb2_get_error(smb2));
return 0;
}
FILE* out = FS::Create(outputfile);
FILE *out = FS::Create(outputfile);
if (out == NULL)
{
sprintf(response, "%s", lang_strings[STR_FAILED]);
return 0;
}
uint8_t *buff = (uint8_t*)malloc(max_read_size);
uint8_t *buff = (uint8_t *)malloc(max_read_size);
int count = 0;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
while ((count = smb2_read(smb2, in, buff, max_read_size)) > 0)
{
if (count < 0)
@@ -221,7 +223,7 @@ int SmbClient::Get(const std::string &outputfile, const std::string &ppath, uint
sprintf(response, "%s", smb2_get_error(smb2));
FS::Close(out);
smb2_close(smb2, in);
free((void*)buff);
free((void *)buff);
return 0;
}
FS::Write(out, buff, count);
@@ -229,7 +231,39 @@ int SmbClient::Get(const std::string &outputfile, const std::string &ppath, uint
}
FS::Close(out);
smb2_close(smb2, in);
free((void*)buff);
free((void *)buff);
return 1;
}
int SmbClient::Get(SplitFile *split_file, const std::string &ppath, uint64_t offset)
{
std::string path = std::string(ppath);
path = Util::Trim(path, "/");
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
if (in == NULL)
{
sprintf(response, "%s", smb2_get_error(smb2));
return 0;
}
uint8_t *buff = (uint8_t *)malloc(max_read_size);
int count = 0;
while ((count = smb2_read(smb2, in, buff, max_read_size)) > 0)
{
if (count < 0)
{
sprintf(response, "%s", smb2_get_error(smb2));
smb2_close(smb2, in);
free((void *)buff);
return 0;
}
split_file->Write((char*)buff, count);
}
smb2_close(smb2, in);
free((void *)buff);
return 1;
}
@@ -237,40 +271,48 @@ int SmbClient::GetRange(const std::string &ppath, DataSink &sink, uint64_t size,
{
std::string path = std::string(ppath);
path = Util::Trim(path, "/");
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
if (in == NULL)
{
return 0;
}
smb2_lseek(smb2, in, offset, SEEK_SET, NULL);
int ret = this->GetRange((void *)in, sink, size, offset);
smb2_close(smb2, in);
uint8_t *buff = (uint8_t*)malloc(max_read_size);
int count = 0;
size_t bytes_remaining = size;
do
{
size_t bytes_to_read = std::min<size_t>(max_read_size, bytes_remaining);
count = smb2_read(smb2, in, buff, bytes_to_read);
if (count > 0)
{
bytes_remaining -= count;
bool ok = sink.write((char*)buff, count);
return ret;
}
int SmbClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
{
struct smb2fh *in = (struct smb2fh *)fp;
smb2_lseek(smb2, in, offset, SEEK_SET, NULL);
uint8_t *buff = (uint8_t *)malloc(max_read_size);
int count = 0;
size_t bytes_remaining = size;
do
{
size_t bytes_to_read = std::min<size_t>(max_read_size, bytes_remaining);
count = smb2_read(smb2, in, buff, bytes_to_read);
if (count > 0)
{
bytes_remaining -= count;
bool ok = sink.write((char *)buff, count);
if (!ok)
{
free((uint8_t *)buff);
smb2_close(smb2, in);
return 0;
}
}
else
{
break;
}
} while (1);
}
else
{
break;
}
} while (1);
free((char *)buff);
smb2_close(smb2, in);
free((char *)buff);
return 1;
}
@@ -285,18 +327,41 @@ int SmbClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, u
return 0;
}
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
if (in == NULL)
{
return 0;
}
int ret = this->GetRange(in, buffer, size, offset);
smb2_close(smb2, in);
return ret;
}
int SmbClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
{
struct smb2fh *in = (struct smb2fh *)fp;
smb2_lseek(smb2, in, offset, SEEK_SET, NULL);
int count = smb2_read(smb2, in, (uint8_t*)buffer, size);
smb2_close(smb2, in);
if (count != size)
return 0;
uint8_t *buff = (uint8_t *)buffer;
int count = 0;
size_t bytes_remaining = size;
do
{
size_t bytes_to_read = std::min<size_t>(max_read_size, bytes_remaining);
count = smb2_read(smb2, in, buff, bytes_to_read);
if (count > 0)
{
bytes_remaining -= count;
buff += count;
}
else
{
break;
}
} while (1);
return 1;
}
@@ -323,14 +388,14 @@ int SmbClient::CopyToSocket(const std::string &ppath, int socket_fd)
return 0;
}
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
if (in == NULL)
{
sprintf(response, "%s", smb2_get_error(smb2));
return 0;
}
uint8_t *buff = (uint8_t*)malloc(max_read_size);
uint8_t *buff = (uint8_t *)malloc(max_read_size);
int count = 0;
while ((count = smb2_read(smb2, in, buff, max_read_size)) > 0)
{
@@ -338,7 +403,7 @@ int SmbClient::CopyToSocket(const std::string &ppath, int socket_fd)
{
sprintf(response, "%s", smb2_get_error(smb2));
smb2_close(smb2, in);
free((void*)buff);
free((void *)buff);
return 0;
}
int ret = sceNetSend(socket_fd, buff, count, 0);
@@ -348,7 +413,7 @@ int SmbClient::CopyToSocket(const std::string &ppath, int socket_fd)
}
}
smb2_close(smb2, in);
free((void*)buff);
free((void *)buff);
return 1;
}
@@ -384,23 +449,25 @@ int SmbClient::Put(const std::string &inputfile, const std::string &ppath, uint6
return 0;
}
FILE* in = FS::OpenRead(inputfile);
FILE *in = FS::OpenRead(inputfile);
if (in == NULL)
{
sprintf(response, "%s", lang_strings[STR_FAILED]);
return 0;
}
struct smb2fh* out = smb2_open(smb2, path.c_str(), O_WRONLY | O_CREAT | O_TRUNC);
struct smb2fh *out = smb2_open(smb2, path.c_str(), O_WRONLY | O_CREAT | O_TRUNC);
if (out == NULL)
{
sprintf(response, "%s", smb2_get_error(smb2));
return 0;
}
uint8_t* buff = (uint8_t*)malloc(max_write_size);
uint8_t *buff = (uint8_t *)malloc(max_write_size);
int count = 0;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
while ((count = FS::Read(in, buff, max_write_size)) > 0)
{
if (count < 0)
@@ -419,7 +486,6 @@ int SmbClient::Put(const std::string &inputfile, const std::string &ppath, uint6
free(buff);
return 1;
}
int SmbClient::Rename(const std::string &src, const std::string &dst)
@@ -553,13 +619,13 @@ int SmbClient::Head(const std::string &ppath, void *buffer, uint64_t len)
return 0;
}
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
if (in == NULL)
{
return 0;
}
int count = smb2_read(smb2, in, (uint8_t*)buffer, len);
int count = smb2_read(smb2, in, (uint8_t *)buffer, len);
smb2_close(smb2, in);
if (count != len)
return 0;
@@ -567,6 +633,20 @@ int SmbClient::Head(const std::string &ppath, void *buffer, uint64_t len)
return 1;
}
void *SmbClient::Open(const std::string &ppath, int flags)
{
std::string path = std::string(ppath);
path = Util::Trim(path, "/");
struct smb2fh *in = smb2_open(smb2, path.c_str(), flags);
return in;
}
void SmbClient::Close(void *fp)
{
smb2_close(smb2, (struct smb2fh *)fp);
}
ClientType SmbClient::clientType()
{
return CLIENT_TYPE_SMB;
+7 -2
View File
@@ -1,5 +1,5 @@
#ifndef SMBCLIENT_H
#define SMBCLIENT_H
#ifndef EZ_SMBCLIENT_H
#define EZ_SMBCLIENT_H
#include <sys/socket.h>
#include <arpa/inet.h>
@@ -24,8 +24,11 @@ public:
int Rmdir(const std::string &path, bool recursive);
int Size(const std::string &path, int64_t *size);
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
int Rename(const std::string &src, const std::string &dst);
int Delete(const std::string &path);
@@ -34,6 +37,8 @@ public:
int Move(const std::string &from, const std::string &to);
int CopyToSocket(const std::string &path, int socket_fd);
std::vector<DirEntry> ListDir(const std::string &path);
void *Open(const std::string &path, int flags);
void Close(void *fp);
bool IsConnected();
bool Ping();
const char *LastResponse();
+55 -14
View File
@@ -10,10 +10,10 @@
#include "windows.h"
using httplib::Client;
using httplib::ContentProvider;
using httplib::Headers;
using httplib::Progress;
using httplib::Result;
using httplib::ContentProvider;
static const char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
@@ -43,6 +43,50 @@ Result WebDAVClient::PropFind(const std::string &path, int depth)
return client->send(req);
}
int WebDAVClient::Size(const std::string &path, int64_t *size)
{
std::string encoded_path = httplib::detail::encode_url(GetFullPath(path));
if (auto res = PropFind(encoded_path, 0))
{
if (HTTP_SUCCESS(res->status))
{
pugi::xml_document document;
document.load_buffer(res->body.c_str(), res->body.length());
auto multistatus = document.select_node("*[local-name()='multistatus']").node();
auto responses = multistatus.select_nodes("*[local-name()='response']");
for (auto response : responses)
{
pugi::xml_node href = response.node().select_node("*[local-name()='href']").node();
std::string resource_path = httplib::detail::decode_url(href.first_child().value(), true);
auto target_path_without_sep = GetFullPath(path);
if (!target_path_without_sep.empty() && target_path_without_sep.back() == '/')
target_path_without_sep.resize(target_path_without_sep.length() - 1);
auto resource_path_without_sep = resource_path.erase(resource_path.find_last_not_of('/') + 1);
size_t pos = resource_path_without_sep.find(this->host_url);
if (pos != std::string::npos)
resource_path_without_sep.erase(pos, this->host_url.length());
if (resource_path_without_sep != target_path_without_sep)
continue;
auto propstat = response.node().select_node("*[local-name()='propstat']").node();
auto prop = propstat.select_node("*[local-name()='prop']").node();
std::string content_length = prop.select_node("*[local-name()='getcontentlength']").node().first_child().value();
*size = std::strtoll(content_length.c_str(), nullptr, 10);
return 1;
}
}
}
else
{
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
}
return 0;
}
std::vector<DirEntry> WebDAVClient::ListDir(const std::string &path)
{
std::vector<DirEntry> out;
@@ -151,12 +195,12 @@ int WebDAVClient::Put(const std::string &inputfile, const std::string &path, uin
{
size_t bytes_remaining = FS::GetSize(inputfile);
bytes_transfered = 0;
FILE* in = FS::OpenRead(inputfile);
sceRtcGetCurrentTick(&prev_tick);
if (auto res = client->Put(GetFullPath(path),
[&](size_t offset, DataSink &sink)
{
FILE *in = FS::OpenRead(inputfile);
if (auto res = client->Put(GetFullPath(path), [&](size_t offset, DataSink &sink)
{
size_t buf_size = MIN(bytes_remaining, CPPHTTPLIB_RECV_BUFSIZ);
char* buf = (char*) malloc(buf_size);
FS::Seek(in, offset);
@@ -170,9 +214,7 @@ int WebDAVClient::Put(const std::string &inputfile, const std::string &path, uin
}
sink.done();
free(buf);
return true;
},
"application/octet-stream"))
return true; }, "application/octet-stream"))
{
if (HTTP_SUCCESS(res->status))
{
@@ -229,15 +271,14 @@ int WebDAVClient::Delete(const std::string &path)
if (HTTP_SUCCESS(res->status))
return 1;
}
return 0;
return 0;
}
int WebDAVClient::Copy(const std::string &from, const std::string &to)
{
Request req;
Headers header = {{"Accept", "*/*"}, {"Destination", httplib::detail::encode_url(GetFullPath(to)) }};
Headers header = {{"Accept", "*/*"}, {"Destination", httplib::detail::encode_url(GetFullPath(to))}};
req.method = "COPY";
req.path = httplib::detail::encode_url(GetFullPath(from));
@@ -256,7 +297,7 @@ int WebDAVClient::Copy(const std::string &from, const std::string &to)
int WebDAVClient::Move(const std::string &from, const std::string &to)
{
Request req;
Headers header = {{"Accept", "*/*"}, {"Destination", httplib::detail::encode_url(GetFullPath(to)) }};
Headers header = {{"Accept", "*/*"}, {"Destination", httplib::detail::encode_url(GetFullPath(to))}};
req.method = "MOVE";
req.path = httplib::detail::encode_url(GetFullPath(from));
@@ -279,5 +320,5 @@ ClientType WebDAVClient::clientType()
uint32_t WebDAVClient::SupportedActions()
{
return REMOTE_ACTION_ALL;
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_RAW_READ;
}
+3 -2
View File
@@ -1,5 +1,5 @@
#ifndef WEBDAV_H
#define WEBDAV_H
#ifndef EZ_WEBDAV_H
#define EZ_WEBDAV_H
#include <string>
#include <vector>
@@ -19,6 +19,7 @@ public:
int Copy(const std::string &from, const std::string &to);
int Move(const std::string &from, const std::string &to);
int Put(const std::string &inputfile, const std::string &path, uint64_t offset = 0);
int Size(const std::string &path, int64_t *size);
std::vector<DirEntry> ListDir(const std::string &path);
ClientType clientType();
uint32_t SupportedActions();
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef COMMON_H
#define COMMON_H
#ifndef EZ_COMMON_H
#define EZ_COMMON_H
#include <string>
#include <vector>
+10 -3
View File
@@ -152,14 +152,17 @@ namespace CONFIG
FS::MkDirs(DATA_PATH);
}
memset(&install_pkg_url, 0, sizeof(install_pkg_url));
install_pkg_url.enable_rpi = true;
sites = {"Site 1", "Site 2", "Site 3", "Site 4", "Site 5", "Site 6", "Site 7", "Site 8", "Site 9", "Site 10",
"Site 11", "Site 12", "Site 13", "Site 14", "Site 15", "Site 16", "Site 17", "Site 18", "Site 19", "Site 20"};
langs = { "Default", "Arabic", "Catalan", "Croatian", "Dutch", "English", "Euskera", "French", "Galego", "German", "Greek",
"Hungarian", "Indonesian", "Italiano", "Japanese", "Korean", "Polish", "Portuguese_BR", "Russian", "Romanian", "Ryukyuan", "Spanish", "Turkish",
"Simplified Chinese", "Traditional Chinese", "Thai", "Ukrainian"};
"Hungarian", "Indonesian", "Italiano", "Japanese", "Korean", "Norwegian", "Polish", "Portuguese_BR", "Russian",
"Romanian", "Ryukyuan", "Spanish", "Turkish", "Simplified Chinese", "Traditional Chinese", "Thai", "Ukrainian", "Vietnamese"};
http_servers = {HTTP_SERVER_APACHE, HTTP_SERVER_MS_IIS, HTTP_SERVER_NGINX, HTTP_SERVER_NPX_SERVE, HTTP_SERVER_RCLONE};
http_servers = {HTTP_SERVER_APACHE, HTTP_SERVER_MS_IIS, HTTP_SERVER_NGINX, HTTP_SERVER_NPX_SERVE, HTTP_SERVER_RCLONE, HTTP_SERVER_ARCHIVEORG, HTTP_SERVER_MYRIENT};
text_file_extensions = { ".txt", ".ini", ".log", ".json", ".xml", ".html", ".xhtml", ".conf", ".config" };
image_file_extensions = { ".bmp", ".jpg", ".jpeg", ".png", ".webp" };
@@ -298,6 +301,9 @@ namespace CONFIG
setting.enable_rpi = ReadBool(sites[i].c_str(), CONFIG_ENABLE_RPI, true);
WriteBool(sites[i].c_str(), CONFIG_ENABLE_RPI, setting.enable_rpi);
setting.enable_disk_cache = ReadBool(sites[i].c_str(), CONFIG_REMOTE_ENABLE_DISK_CACHE, false);
WriteBool(sites[i].c_str(), CONFIG_REMOTE_ENABLE_DISK_CACHE, setting.enable_disk_cache);
sprintf(setting.http_server_type, "%s", ReadString(sites[i].c_str(), CONFIG_REMOTE_HTTP_SERVER_TYPE, HTTP_SERVER_APACHE));
WriteString(sites[i].c_str(), CONFIG_REMOTE_HTTP_SERVER_TYPE, setting.http_server_type);
@@ -371,6 +377,7 @@ namespace CONFIG
WriteString(last_site, CONFIG_REMOTE_SERVER_USER, remote_settings->username);
WriteString(last_site, CONFIG_REMOTE_SERVER_PASSWORD, encrypted_text.c_str());
WriteBool(last_site, CONFIG_ENABLE_RPI, remote_settings->enable_rpi);
WriteBool(last_site, CONFIG_REMOTE_ENABLE_DISK_CACHE, remote_settings->enable_disk_cache);
WriteString(last_site, CONFIG_REMOTE_HTTP_SERVER_TYPE, remote_settings->http_server_type);
WriteString(last_site, CONFIG_REMOTE_DEFAULT_DIRECTORY, remote_settings->default_directory);
WriteString(CONFIG_GLOBAL, CONFIG_LAST_SITE, last_site);
+10 -2
View File
@@ -1,5 +1,5 @@
#ifndef LAUNCHER_CONFIG_H
#define LAUNCHER_CONFIG_H
#ifndef EZ_CONFIG_H
#define EZ_CONFIG_H
#include <string>
#include <vector>
@@ -57,6 +57,7 @@
#define CONFIG_ENABLE_RPI "remote_server_enable_rpi"
#define CONFIG_REMOTE_HTTP_SERVER_TYPE "remote_server_http_server_type"
#define CONFIG_REMOTE_DEFAULT_DIRECTORY "remote_server_default_directory"
#define CONFIG_REMOTE_ENABLE_DISK_CACHE "remote_server_enable_disk_cache"
#define CONFIG_ALLDEBRID_API_KEY "alldebrid_api_key"
#define CONFIG_REALDEBRID_API_KEY "realdebrid_api_key"
@@ -81,6 +82,8 @@
#define HTTP_SERVER_NGINX "Nginx"
#define HTTP_SERVER_NPX_SERVE "Serve"
#define HTTP_SERVER_RCLONE "RClone"
#define HTTP_SERVER_ARCHIVEORG "Archive.org"
#define HTTP_SERVER_MYRIENT "Myrient"
#define MAX_EDIT_FILE_SIZE 32768
@@ -110,6 +113,7 @@ struct RemoteSettings
char http_server_type[24];
GoogleAccountInfo gg_account;
char default_directory[256];
bool enable_disk_cache;
};
struct PackageUrlInfo
@@ -117,6 +121,10 @@ struct PackageUrlInfo
char url[512];
char username[33];
char password[25];
bool enable_alldebrid;
bool enable_realdebrid;
bool enable_disk_cache;
bool enable_rpi;
};
extern std::vector<std::string> sites;
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef FICHIER_HOST_H
#define FICHIER_HOST_H
#ifndef EZ_FICHIER_HOST_H
#define EZ_FICHIER_HOST_H
#include "filehost.h"
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef ALLDEBRID_HOST_H
#define ALLDEBRID_HOST_H
#ifndef EZ_ALLDEBRID_HOST_H
#define EZ_ALLDEBRID_HOST_H
#include "filehost.h"
-2
View File
@@ -1,6 +1,4 @@
#include <regex>
#include <lexbor/html/parser.h>
#include <lexbor/dom/interfaces/element.h>
#include <http/httplib.h>
#include "common.h"
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef DIRECT_HOST_H
#define DIRECT_HOST_H
#ifndef EZ_DIRECT_HOST_H
#define EZ_DIRECT_HOST_H
#include "filehost.h"
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef FILEHOST_H
#define FILEHOST_H
#ifndef EZ_FILEHOST_H
#define EZ_FILEHOST_H
#include <string>
#include <vector>
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef GDRIVE_HOST_H
#define GDRIVE_HOST_H
#ifndef EZ_GDRIVE_HOST_H
#define EZ_GDRIVE_HOST_H
#include "filehost.h"
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef MEDIAFIRE_HOST_H
#define MEDIAFIRE_HOST_H
#ifndef EZ_MEDIAFIRE_HOST_H
#define EZ_MEDIAFIRE_HOST_H
#include "filehost.h"
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef PIXELDRAIN_HOST_H
#define PIXELDRAIN_HOST_H
#ifndef EZ_PIXELDRAIN_HOST_H
#define EZ_PIXELDRAIN_HOST_H
#include "filehost.h"
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef REALDEBRID_HOST_H
#define REALDEBRID_HOST_H
#ifndef EZ_REALDEBRID_HOST_H
#define EZ_REALDEBRID_HOST_H
#include "filehost.h"
+2
View File
@@ -510,6 +510,8 @@ namespace FS
size_t bytes_read = 0;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
const size_t buf_size = 0x10000;
unsigned char *buf = new unsigned char[buf_size];
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef LAUNCHER_FS_H
#define LAUNCHER_FS_H
#ifndef EZ_FS_H
#define EZ_FS_H
#pragma once
#include <string.h>
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef LAUNCHER_GUI_H
#define LAUNCHER_GUI_H
#ifndef EZ_GUI_H
#define EZ_GUI_H
#include <string>
#include "SDL2/SDL.h"
+2
View File
@@ -1898,6 +1898,8 @@ make_basic_authentication_header(const std::string &username,
namespace detail {
const char *status_message(int status);
std::string encode_query_param(const std::string &value);
std::string encode_url(const std::string &s);
+2 -2
View File
@@ -16,8 +16,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __IME_DIALOG_H__
#define __IME_DIALOG_H__
#ifndef __EZ_IME_DIALOG_H__
#define __EZ_IME_DIALOG_H__
#define IME_DIALOG_RESULT_NONE 0
#define IME_DIALOG_RESULT_RUNNING 1
+9
View File
@@ -84,6 +84,8 @@
#define BUTTON_RIGHT 0x00000020
#define BUTTON_UP 0x00000040
#define BUTTON_DOWN 0x00000080
#define BUTTON_C 0x00000100
#define BUTTON_D 0x00000200
static uint32_t previous_down = 0;
static int repeat_count = 0;
@@ -531,8 +533,15 @@ static void ImGui_ImplSDL2_UpdateGamepads()
down |= BUTTON_DOWN;
else if (SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_LEFTY) < -ANALOG_THRESHOLD)
down |= BUTTON_UP;
else if (SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) > ANALOG_THRESHOLD)
down |= BUTTON_C;
else if (SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) > ANALOG_THRESHOLD)
down |= BUTTON_D;
uint32_t pressed = down & ~previous_down;
io.AddKeyEvent(ImGuiKey_C, (pressed & BUTTON_C) != 0);
io.AddKeyEvent(ImGuiKey_D, (pressed & BUTTON_D) != 0);
if (previous_down == down)
{
uint64_t delay = 300;
+258 -45
View File
@@ -26,7 +26,8 @@
struct BgProgressCheck
{
ArchivePkgInstallData* pkg_data;
ArchivePkgInstallData *archive_pkg_data;
SplitPkgInstallData *split_pkg_data;
int task_id;
std::string hash;
};
@@ -36,6 +37,7 @@ static OrbisBgftInitParams s_bgft_init_params;
static bool s_bgft_initialized = false;
static std::map<std::string, ArchivePkgInstallData *> archive_pkg_install_data_list;
static std::map<std::string, SplitPkgInstallData *> split_pkg_install_data_list;
namespace INSTALLER
{
@@ -107,22 +109,22 @@ namespace INSTALLER
s_bgft_initialized = false;
}
std::string GetRemotePkgTitle(RemoteClient *client, const std::string &path, pkg_header *header)
{
std::string GetRemotePkgTitle(RemoteClient *client, const std::string &path, pkg_header *header)
{
size_t entry_count = BE32(header->pkg_entry_count);
uint32_t entry_table_offset = BE32(header->pkg_table_offset);
uint64_t entry_table_size = entry_count * sizeof(pkg_table_entry);
void *entry_table_data = malloc(entry_table_size);
int ret = client->GetRange(path, entry_table_data, entry_table_size, entry_table_offset);
if (ret == 0)
{
free(entry_table_data);
return "";
}
int ret = client->GetRange(path, entry_table_data, entry_table_size, entry_table_offset);
if (ret == 0)
{
free(entry_table_data);
return "";
}
pkg_table_entry *entries = (pkg_table_entry *)entry_table_data;
void* param_sfo_data = nullptr;
void *param_sfo_data = nullptr;
uint32_t param_sfo_offset = 0;
uint32_t param_sfo_size = 0;
for (size_t i = 0; i < entry_count; ++i)
@@ -132,7 +134,7 @@ namespace INSTALLER
param_sfo_offset = BE32(entries[i].offset);
param_sfo_size = BE32(entries[i].size);
break;
}
}
}
free(entry_table_data);
@@ -140,10 +142,10 @@ namespace INSTALLER
if (param_sfo_offset > 0 && param_sfo_size > 0)
{
param_sfo_data = malloc(param_sfo_size);
int ret = client->GetRange(path, param_sfo_data, param_sfo_size, param_sfo_offset);
if (ret)
int ret = client->GetRange(path, param_sfo_data, param_sfo_size, param_sfo_offset);
if (ret)
{
const char* tmp_title = SFO::GetString((const char*)param_sfo_data, param_sfo_size, "TITLE");
const char *tmp_title = SFO::GetString((const char *)param_sfo_data, param_sfo_size, "TITLE");
if (tmp_title != nullptr)
title = std::string(tmp_title);
}
@@ -151,7 +153,7 @@ namespace INSTALLER
}
return title;
}
}
std::string GetLocalPkgTitle(const std::string &path, pkg_header *header)
{
@@ -165,7 +167,7 @@ namespace INSTALLER
FS::Read(fd, entry_table_data, entry_table_size);
pkg_table_entry *entries = (pkg_table_entry *)entry_table_data;
void* param_sfo_data = NULL;
void *param_sfo_data = NULL;
uint32_t param_sfo_offset = 0;
uint32_t param_sfo_size = 0;
void *icon0_png_data = NULL;
@@ -188,7 +190,7 @@ namespace INSTALLER
param_sfo_data = malloc(param_sfo_size);
FS::Seek(fd, param_sfo_offset);
FS::Read(fd, param_sfo_data, param_sfo_size);
const char* tmp_title = SFO::GetString((const char*)param_sfo_data, param_sfo_size, "TITLE");
const char *tmp_title = SFO::GetString((const char *)param_sfo_data, param_sfo_size, "TITLE");
if (tmp_title != nullptr)
title = std::string(tmp_title);
free(param_sfo_data);
@@ -219,8 +221,8 @@ namespace INSTALLER
}
else
{
std::string encoded_path = httplib::detail::encode_url(path);
std::string encoded_site_name = httplib::detail::encode_url(remote_settings->site_name);
std::string encoded_path = httplib::detail::encode_url(path);
std::string encoded_site_name = httplib::detail::encode_url(remote_settings->site_name);
std::string full_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst/" + encoded_site_name + encoded_path;
return full_url;
}
@@ -232,7 +234,7 @@ namespace INSTALLER
{
bool completed = false;
OrbisBgftTaskProgress progress_info;
BgProgressCheck *bg_check_data = (BgProgressCheck*) argp;
BgProgressCheck *bg_check_data = (BgProgressCheck *)argp;
int ret;
while (!completed)
@@ -253,15 +255,27 @@ namespace INSTALLER
sceKernelUsleep(500000);
}
finish:
if (bg_check_data->pkg_data != nullptr)
if (bg_check_data->archive_pkg_data != nullptr)
{
bg_check_data->pkg_data->stop_write_thread = true;
pthread_join(bg_check_data->pkg_data->thread, NULL);
delete(bg_check_data->pkg_data->split_file);
free(bg_check_data->pkg_data);
bg_check_data->archive_pkg_data->stop_write_thread = true;
pthread_join(bg_check_data->archive_pkg_data->thread, NULL);
delete (bg_check_data->archive_pkg_data->split_file);
free(bg_check_data->archive_pkg_data);
RemoveArchivePkgInstallData(bg_check_data->hash);
free(bg_check_data);
}
else if (bg_check_data->split_pkg_data != nullptr)
{
bg_check_data->split_pkg_data->stop_write_thread = true;
bg_check_data->split_pkg_data->split_file->Close();
pthread_join(bg_check_data->split_pkg_data->thread, NULL);
delete (bg_check_data->split_pkg_data->split_file);
if (bg_check_data->split_pkg_data->delete_client)
delete (bg_check_data->split_pkg_data->remote_client);
free(bg_check_data->split_pkg_data);
RemoveSplitPkgInstallData(bg_check_data->hash);
free(bg_check_data);
}
activity_inprogess = false;
file_transfering = false;
Windows::SetModalMode(false);
@@ -385,19 +399,20 @@ namespace INSTALLER
}
Util::Notify("%s queued", display_title.c_str());
if (prompt)
{
file_transfering = true;
bytes_to_download = 100;
bytes_to_download = header->pkg_content_size;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
while (!completed)
{
memset(&progress_info, 0, sizeof(progress_info));
ret = sceBgftServiceDownloadGetProgress(task_id, &progress_info);
if (ret || (progress_info.transferred > 0 && progress_info.errorResult != 0))
return 0;
if (progress_info.length > 0)
{
completed = progress_info.transferred == progress_info.length;
@@ -409,9 +424,10 @@ namespace INSTALLER
}
else
{
BgProgressCheck *bg_check_data = (BgProgressCheck*) malloc(sizeof(BgProgressCheck));
BgProgressCheck *bg_check_data = (BgProgressCheck *)malloc(sizeof(BgProgressCheck));
memset(bg_check_data, 0, sizeof(BgProgressCheck));
bg_check_data->pkg_data = nullptr;
bg_check_data->archive_pkg_data = nullptr;
bg_check_data->split_pkg_data = nullptr;
bg_check_data->task_id = task_id;
bg_check_data->hash = "";
ret = pthread_create(&bk_install_thid, NULL, CheckBgInstallTaskThread, bg_check_data);
@@ -488,8 +504,10 @@ namespace INSTALLER
Util::Notify("%s queued", display_title.c_str());
file_transfering = true;
bytes_to_download = 100;
bytes_to_download = header.pkg_content_size;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
while (!completed)
{
memset(&progress_info, 0, sizeof(progress_info));
@@ -515,13 +533,13 @@ namespace INSTALLER
{
int ret;
bool completed = false;
if (strncmp(path.c_str(), "/data/", 6) != 0 &&
strncmp(path.c_str(), "/user/data/", 11) != 0 &&
strncmp(path.c_str(), "/mnt/usb", 8) != 0)
return -1;
std::string filename = path.substr(path.find_last_of("/")+1);
std::string filename = path.substr(path.find_last_of("/") + 1);
char filepath[1024];
snprintf(filepath, 1023, "%s", path.c_str());
if (strncmp(path.c_str(), "/data/", 6) == 0)
@@ -599,8 +617,10 @@ namespace INSTALLER
}
sprintf(activity_message, "%s", lang_strings[STR_WAIT_FOR_INSTALL_MSG]);
bytes_to_download = 1;
bytes_to_download = header->pkg_content_size;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
while (!completed)
{
memset(&progress_info, 0, sizeof(progress_info));
@@ -639,7 +659,7 @@ namespace INSTALLER
FS::Read(fd, entry_table_data, entry_table_size);
pkg_table_entry *entries = (pkg_table_entry *)entry_table_data;
void* param_sfo_data = NULL;
void *param_sfo_data = NULL;
uint32_t param_sfo_offset = 0;
uint32_t param_sfo_size = 0;
void *icon0_png_data = NULL;
@@ -710,7 +730,7 @@ namespace INSTALLER
return false;
pkg_table_entry *entries = (pkg_table_entry *)entry_table_data;
void* param_sfo_data = NULL;
void *param_sfo_data = NULL;
uint32_t param_sfo_offset = 0;
uint32_t param_sfo_size = 0;
void *icon0_png_data = NULL;
@@ -778,7 +798,7 @@ namespace INSTALLER
void AddArchivePkgInstallData(const std::string &hash, ArchivePkgInstallData *pkg_data)
{
std::pair<std::string, ArchivePkgInstallData*> pair = std::make_pair(hash, pkg_data);
std::pair<std::string, ArchivePkgInstallData *> pair = std::make_pair(hash, pkg_data);
archive_pkg_install_data_list.erase(hash);
archive_pkg_install_data_list.insert(pair);
}
@@ -788,10 +808,10 @@ namespace INSTALLER
archive_pkg_install_data_list.erase(hash);
}
bool InstallArchivePkg(const std::string &path, ArchivePkgInstallData* pkg_data, bool bg)
bool InstallArchivePkg(const std::string &path, ArchivePkgInstallData *pkg_data, bool bg)
{
pkg_header header;
pkg_data->split_file->Read((char*)&header, sizeof(pkg_header), 0);
pkg_data->split_file->Read((char *)&header, sizeof(pkg_header), 0);
int ret;
std::string cid = std::string((char *)header.pkg_content_id);
@@ -915,8 +935,10 @@ namespace INSTALLER
if (!bg)
{
file_transfering = true;
bytes_to_download = 100;
bytes_to_download = header.pkg_content_size;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
while (!completed)
{
memset(&progress_info, 0, sizeof(progress_info));
@@ -926,7 +948,6 @@ namespace INSTALLER
ret = 0;
goto finish;
}
bytes_transfered = (uint32_t)(((float)progress_info.transferred / progress_info.length) * 100.f);
if (progress_info.length > 0)
{
completed = progress_info.transferred == progress_info.length;
@@ -938,9 +959,10 @@ namespace INSTALLER
}
else
{
BgProgressCheck *bg_check_data = (BgProgressCheck*) malloc(sizeof(BgProgressCheck));
BgProgressCheck *bg_check_data = (BgProgressCheck *)malloc(sizeof(BgProgressCheck));
memset(bg_check_data, 0, sizeof(BgProgressCheck));
bg_check_data->pkg_data = pkg_data;
bg_check_data->archive_pkg_data = pkg_data;
bg_check_data->split_pkg_data = nullptr;
bg_check_data->task_id = task_id;
bg_check_data->hash = hash;
ret = pthread_create(&bk_install_thid, NULL, CheckBgInstallTaskThread, bg_check_data);
@@ -950,11 +972,202 @@ namespace INSTALLER
finish:
pkg_data->stop_write_thread = true;
pthread_join(pkg_data->thread, NULL);
delete(pkg_data->split_file);
delete (pkg_data->split_file);
free(pkg_data);
RemoveArchivePkgInstallData(hash);
return ret;
}
SplitPkgInstallData *GetSplitPkgInstallData(const std::string &hash)
{
return split_pkg_install_data_list[hash];
}
void AddSplitPkgInstallData(const std::string &hash, SplitPkgInstallData *pkg_data)
{
std::pair<std::string, SplitPkgInstallData *> pair = std::make_pair(hash, pkg_data);
split_pkg_install_data_list.erase(hash);
split_pkg_install_data_list.insert(pair);
}
void RemoveSplitPkgInstallData(const std::string &hash)
{
split_pkg_install_data_list.erase(hash);
}
bool InstallSplitPkg(const std::string &path, SplitPkgInstallData *pkg_data, bool bg)
{
pkg_header header;
pkg_data->split_file->Read((char *)&header, sizeof(pkg_header), 0);
int ret;
std::string cid = std::string((char *)header.pkg_content_id);
cid = cid.substr(cid.find_first_of("-") + 1, 9);
std::string display_title = cid;
int user_id;
ret = sceUserServiceGetForegroundUser(&user_id);
const char *package_type;
uint32_t content_type = BE32(header.pkg_content_type);
uint32_t flags = BE32(header.pkg_content_flags);
bool is_patch = false;
bool completed = false;
switch (content_type)
{
case PKG_CONTENT_TYPE_GD:
package_type = "PS4GD";
break;
case PKG_CONTENT_TYPE_AC:
package_type = "PS4AC";
break;
case PKG_CONTENT_TYPE_AL:
package_type = "PS4AL";
break;
case PKG_CONTENT_TYPE_DP:
package_type = "PS4DP";
break;
default:
package_type = NULL;
return 0;
break;
}
if (flags & PKG_CONTENT_FLAGS_FIRST_PATCH ||
flags & PKG_CONTENT_FLAGS_SUBSEQUENT_PATCH ||
flags & PKG_CONTENT_FLAGS_DELTA_PATCH ||
flags & PKG_CONTENT_FLAGS_CUMULATIVE_PATCH)
{
is_patch = true;
}
std::string hash = Util::UrlHash(path);
std::string full_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/split_inst/" + hash;
AddSplitPkgInstallData(hash, pkg_data);
OrbisBgftTaskProgress progress_info;
OrbisBgftDownloadParam params;
memset(&params, 0, sizeof(params));
{
params.userId = user_id;
params.entitlementType = 5;
params.id = (char *)header.pkg_content_id;
params.contentUrl = full_url.c_str();
params.contentName = display_title.c_str();
params.iconPath = "";
params.playgoScenarioId = "0";
params.option = ORBIS_BGFT_TASK_OPT_DISABLE_CDN_QUERY_PARAM;
params.packageType = package_type;
params.packageSubType = "";
params.packageSize = BE64(header.pkg_size);
}
retry:
int task_id = -1;
if (!is_patch)
ret = sceBgftServiceIntDownloadRegisterTask(&params, &task_id);
else
ret = sceBgftServiceIntDebugDownloadRegisterPkg(&params, &task_id);
if (ret == 0x80990088 || ret == 0x80990015)
{
if (!bg)
{
sprintf(confirm_message, "%s - %s?", display_title.c_str(), lang_strings[STR_REINSTALL_CONFIRM_MSG]);
confirm_state = CONFIRM_WAIT;
action_to_take = selected_action;
activity_inprogess = false;
while (confirm_state == CONFIRM_WAIT)
{
sceKernelUsleep(100000);
}
activity_inprogess = true;
selected_action = action_to_take;
if (confirm_state == CONFIRM_YES)
{
ret = sceAppInstUtilAppUnInstall(cid.c_str());
if (ret != 0)
{
ret = 0;
goto finish;
}
goto retry;
}
}
else
{
ret = sceAppInstUtilAppUnInstall(cid.c_str());
if (ret != 0)
{
ret = 0;
goto finish;
}
goto retry;
}
}
else if (ret > 0)
{
ret = 0;
goto finish;
}
ret = sceBgftServiceDownloadStartTask(task_id);
if (ret)
{
ret = 0;
goto finish;
}
Util::Notify("%s queued", display_title.c_str());
if (!bg)
{
file_transfering = true;
bytes_to_download = pkg_data->size;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
while (!completed)
{
memset(&progress_info, 0, sizeof(progress_info));
ret = sceBgftServiceDownloadGetProgress(task_id, &progress_info);
if (ret || (progress_info.transferred > 0 && progress_info.errorResult != 0))
{
ret = 0;
goto finish;
}
if (progress_info.length > 0)
{
completed = progress_info.transferred == progress_info.length;
bytes_to_download = progress_info.length;
bytes_transfered = progress_info.transferred;
}
sceSystemServicePowerTick();
}
}
else
{
BgProgressCheck *bg_check_data = (BgProgressCheck *)malloc(sizeof(BgProgressCheck));
memset(bg_check_data, 0, sizeof(BgProgressCheck));
bg_check_data->split_pkg_data = pkg_data;
bg_check_data->archive_pkg_data = nullptr;
bg_check_data->task_id = task_id;
bg_check_data->hash = hash;
ret = pthread_create(&bk_install_thid, NULL, CheckBgInstallTaskThread, bg_check_data);
return 1;
}
ret = 1;
finish:
pkg_data->stop_write_thread = true;
pkg_data->split_file->Close();
pthread_join(pkg_data->thread, NULL);
delete (pkg_data->split_file);
if (pkg_data->delete_client)
delete (pkg_data->remote_client);
free(pkg_data);
RemoveSplitPkgInstallData(hash);
activity_inprogess = false;
file_transfering = false;
Windows::SetModalMode(false);
return ret;
}
}
+15
View File
@@ -129,6 +129,17 @@ struct ArchivePkgInstallData
bool stop_write_thread;
};
struct SplitPkgInstallData
{
SplitFile *split_file;
RemoteClient *remote_client;
std::string path;
int64_t size;
pthread_t thread;
bool stop_write_thread;
bool delete_client;
};
static pthread_t bk_install_thid;
namespace INSTALLER
@@ -149,4 +160,8 @@ namespace INSTALLER
void AddArchivePkgInstallData(const std::string &hash, ArchivePkgInstallData *pkg_data);
void RemoveArchivePkgInstallData(const std::string &hash);
bool InstallArchivePkg(const std::string &path, ArchivePkgInstallData* pkg_data, bool bg = false);
SplitPkgInstallData *GetSplitPkgInstallData(const std::string &hash);
void AddSplitPkgInstallData(const std::string &hash, SplitPkgInstallData *pkg_data);
void RemoveSplitPkgInstallData(const std::string &hash);
bool InstallSplitPkg(const std::string &path, SplitPkgInstallData* pkg_data, bool bg = false);
}
+8
View File
@@ -172,6 +172,11 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = {
"Temp Directory", // STR_TEMP_DIRECTORY
"Real-Debrid", // STR_REALDEBRID
"Package install is running in the background. Don't close the app while install is in progress", // STR_BACKGROUND_INSTALL_INPROGRESS
"Enable disk caching. Can improve package install speed in cases where connection to remote is slow, but breaks resuming of install", // STR_ENABLE_DISC_CACHE_MSG
"DC", // STR_ENABLE_DISK_CACHE
"Install Via AllDebrid", // STR_ENABLE_ALLDEBRID_MSG
"Install Via RealDebrid", // STR_ENABLE_REALDEBRID_MSG
"Enable Disk Cache", // STR_ENABLE_DISKCACHE_DESC
};
bool needs_extended_font = false;
@@ -253,6 +258,9 @@ namespace Lang
case ORBIS_SYSTEM_PARAM_LANG_ROMANIAN:
sprintf(langFile, "%s", "/app0/assets/langs/Romanian.ini");
break;
case ORBIS_SYSTEM_PARAM_LANG_NORWEGIAN:
sprintf(langFile, "%s", "/app0/assets/langs/Norwegian.ini");
break;
default:
sprintf(langFile, "%s", "/app0/assets/langs/English.ini");
break;
+9 -4
View File
@@ -1,5 +1,5 @@
#ifndef __LANG_H__
#define __LANG_H__
#ifndef __EZ_LANG_H__
#define __EZ_LANG_H__
#include "config.h"
@@ -165,7 +165,12 @@
FUNC(STR_LANGUAGE) \
FUNC(STR_TEMP_DIRECTORY) \
FUNC(STR_REALDEBRID) \
FUNC(STR_BACKGROUND_INSTALL_INPROGRESS)
FUNC(STR_BACKGROUND_INSTALL_INPROGRESS) \
FUNC(STR_ENABLE_DISC_CACHE_MSG) \
FUNC(STR_ENABLE_DISK_CACHE) \
FUNC(STR_ENABLE_ALLDEBRID_MSG) \
FUNC(STR_ENABLE_REALDEBRID_MSG) \
FUNC(STR_ENABLE_DISKCACHE_DESC)
#define GET_VALUE(x) x,
#define GET_STRING(x) #x,
@@ -175,7 +180,7 @@ enum
FOREACH_STR(GET_VALUE)
};
#define LANG_STRINGS_NUM 162
#define LANG_STRINGS_NUM 167
#define LANG_ID_SIZE 64
#define LANG_STR_SIZE 384
extern char lang_identifiers[LANG_STRINGS_NUM][LANG_ID_SIZE];
+10 -8
View File
@@ -139,41 +139,43 @@ void InitImgui()
sceSystemServiceParamGetInt( ORBIS_SYSTEM_SERVICE_PARAM_ID_LANG, &lang_idx );
lang = Util::Trim(lang, " ");
if (lang.compare("Korean") == 0 || (lang.empty() && lang_idx == ORBIS_SYSTEM_PARAM_LANG_KOREAN))
bool use_system_lang = lang.empty() || lang.compare("Default") == 0;
if (lang.compare("Korean") == 0 || (use_system_lang && lang_idx == ORBIS_SYSTEM_PARAM_LANG_KOREAN))
{
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/Roboto_ext.ttf", 26.0f, NULL, io.Fonts->GetGlyphRangesKorean());
}
else if (lang.compare("Simplified Chinese") == 0 || (lang.empty() && lang_idx == ORBIS_SYSTEM_PARAM_LANG_CHINESE_S))
else if (lang.compare("Simplified Chinese") == 0 || (use_system_lang && lang_idx == ORBIS_SYSTEM_PARAM_LANG_CHINESE_S))
{
ImFontConfig config;
config.OversampleH = 1;
config.OversampleV = 1;
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/Roboto_ext.ttf", 26.0f, &config, io.Fonts->GetGlyphRangesChineseFull());
}
else if (lang.compare("Traditional Chinese") == 0 || (lang.empty() && lang_idx == ORBIS_SYSTEM_PARAM_LANG_CHINESE_T))
else if (lang.compare("Traditional Chinese") == 0 || (use_system_lang && lang_idx == ORBIS_SYSTEM_PARAM_LANG_CHINESE_T))
{
ImFontConfig config;
config.OversampleH = 1;
config.OversampleV = 1;
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/Roboto_ext.ttf", 26.0f, &config, io.Fonts->GetGlyphRangesChineseFull());
}
else if (lang.compare("Japanese") == 0 || lang.compare("Ryukyuan") == 0 || (lang.empty() && lang_idx == ORBIS_SYSTEM_PARAM_LANG_JAPANESE))
else if (lang.compare("Japanese") == 0 || lang.compare("Ryukyuan") == 0 || (use_system_lang && lang_idx == ORBIS_SYSTEM_PARAM_LANG_JAPANESE))
{
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/Roboto_ext.ttf", 26.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
}
else if (lang.compare("Thai") == 0 || (lang.empty() && lang_idx == ORBIS_SYSTEM_PARAM_LANG_THAI))
else if (lang.compare("Thai") == 0 || (use_system_lang && lang_idx == ORBIS_SYSTEM_PARAM_LANG_THAI))
{
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/Roboto_ext.ttf", 26.0f, NULL, io.Fonts->GetGlyphRangesThai());
}
else if (lang.compare("Vietnamese") == 0 || (lang.empty() && lang_idx == ORBIS_SYSTEM_PARAM_LANG_VIETNAMESE))
else if (lang.compare("Vietnamese") == 0 || (use_system_lang && lang_idx == ORBIS_SYSTEM_PARAM_LANG_VIETNAMESE))
{
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/Roboto_ext.ttf", 26.0f, NULL, io.Fonts->GetGlyphRangesVietnamese());
}
else if (lang.compare("Greek") == 0 || (lang.empty() && lang_idx == ORBIS_SYSTEM_PARAM_LANG_GREEK))
else if (lang.compare("Greek") == 0 || (use_system_lang && lang_idx == ORBIS_SYSTEM_PARAM_LANG_GREEK))
{
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/Roboto_ext.ttf", 26.0f, NULL, io.Fonts->GetGlyphRangesGreek());
}
else if (lang.compare("Arabic") == 0 || (lang.empty() && lang_idx == ORBIS_SYSTEM_PARAM_LANG_ARABIC))
else if (lang.compare("Arabic") == 0 || (use_system_lang && lang_idx == ORBIS_SYSTEM_PARAM_LANG_ARABIC))
{
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/Roboto_ext.ttf", 26.0f, NULL, arabic);
}
+197
View File
@@ -0,0 +1,197 @@
#include <stdio.h>
#include <stdio.h>
#include <string>
#include "common.h"
#include "mem_file.h"
MemFile::MemFile(const std::string &path, size_t block_size)
{
this->block_size = block_size;
this->complete = false;
sem_init(&this->block_ready, 0, 0);
}
MemFile::~MemFile()
{
for (int i = 0; i < this->mem_blocks.size(); i++)
{
if (this->mem_blocks[i] != nullptr && this->mem_blocks[i]->status != MEM_BLOCK_STATUS_DELETED)
{
if (this->mem_blocks[i]->buf != nullptr)
{
free(this->mem_blocks[i]->buf);
this->mem_blocks[i]->buf = nullptr;
}
free(this->mem_blocks[i]);
}
}
sem_destroy(&this->block_ready);
};
int MemFile::Open()
{
this->block_in_progress = NewBlock();
this->block_in_progress->buf = malloc(block_size);
return (block_in_progress->buf == nullptr);
}
size_t MemFile::Read(char *buf, size_t buf_size, size_t offset)
{
int first_block_num, block_num;
size_t block_offset;
size_t remaining;
size_t bytes_read;
size_t total_bytes_read;
MemBlock *block;
char *p;
first_block_num= offset / this->block_size;
block_num = first_block_num;
block_offset = offset % this->block_size;
while ((block_num >= this->mem_blocks.size() && !this->complete) ||
(block_num < this->mem_blocks.size() && this->mem_blocks[block_num]->status == MEM_BLOCK_STATUS_NOT_EXISTS))
{
sem_wait(&this->block_ready);
}
block = this->mem_blocks[block_num];
if (block->status == MEM_BLOCK_STATUS_DELETED)
{
return -1;
}
if (block_offset > block->size - 1 && this->complete)
{
// requested offset is pass the end of split file
return 0;
}
remaining = buf_size;
bool eof = false;
total_bytes_read = 0;
p = buf;
while (remaining > 0 && !eof)
{
uint8_t *src = (uint8_t*)block->buf;
src += block_offset;
bytes_read = block_size - block_offset;
memcpy(p, src, bytes_read);
if (bytes_read == remaining)
{
p += bytes_read;
total_bytes_read += bytes_read;
}
else
{
p += bytes_read;
total_bytes_read += bytes_read;
if (block->is_last)
{
eof = true;
continue;
}
}
remaining -= bytes_read;
if (remaining == 0)
continue;
block_num++;
block_offset = 0;
while ((block_num > this->mem_blocks.size() - 1 && !this->complete) ||
this->mem_blocks[block_num]->status == MEM_BLOCK_STATUS_NOT_EXISTS)
{
sem_wait(&this->block_ready);
}
block = this->mem_blocks[block_num];
}
// delete blocks before the first read offset block. Assumuption, that reads are always
// forward and won't read previously already read blocks. For safety, keeping only current block and 2 previous blocks
for (int j=0; j < first_block_num - 2; j++)
{
if (this->mem_blocks[j]->status == MEM_BLOCK_STATUS_CREATED)
{
if (this->mem_blocks[j]->buf != nullptr)
{
free(this->mem_blocks[j]->buf);
this->mem_blocks[j]->buf = nullptr;
}
this->mem_blocks[j]->status = MEM_BLOCK_STATUS_DELETED;
}
}
return total_bytes_read;
}
size_t MemFile::Write(char *buf, size_t buf_size)
{
size_t bytes_written;
size_t block_space_remaining;
size_t bytes_to_write;
char *p = buf;
size_t total_bytes_written = 0;
size_t remaining_to_write = buf_size;
while (remaining_to_write > 0)
{
block_space_remaining = this->block_size - block_in_progress->size;
bytes_to_write = MIN(remaining_to_write, block_space_remaining);
memcpy(block_in_progress->buf, p, bytes_to_write);
bytes_written = bytes_to_write;
block_in_progress->size += bytes_written;
total_bytes_written += bytes_written;
remaining_to_write -= bytes_written;
block_space_remaining -= bytes_written;
p += bytes_written;
// error if bytes_to_write != bytes_written
if (bytes_written != bytes_to_write)
{
break;
}
if (block_space_remaining == 0)
{
block_in_progress->status = MEM_BLOCK_STATUS_CREATED;
this->mem_blocks.push_back(block_in_progress);
sem_post(&this->block_ready);
block_in_progress = NewBlock();
}
}
return total_bytes_written;
}
int MemFile::Close()
{
block_in_progress->status = MEM_BLOCK_STATUS_CREATED;
block_in_progress->is_last = true;
this->mem_blocks.push_back(block_in_progress);
this->complete = true;
sem_post(&this->block_ready);
return 0;
}
MemBlock *MemFile::NewBlock()
{
MemBlock *block = (MemBlock *)malloc(sizeof(MemBlock));
memset(block, 0, sizeof(MemBlock));
block->is_last = false;
block->size = 0;
block->buf = malloc(block_size);
return block;
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef EZ_MEM_FILE_H
#define EZ_MEM_FILE_H
#include <string>
#include <vector>
#include <mutex>
#include <pthread.h>
enum MemBlockStatus
{
MEM_BLOCK_STATUS_NOT_EXISTS,
MEM_BLOCK_STATUS_CREATED,
MEM_BLOCK_STATUS_DELETED
};
typedef struct
{
size_t size;
void* buf;
bool is_last;
MemBlockStatus status;
} MemBlock;
class MemFile
{
public:
MemFile(const std::string& path, size_t block_size);
~MemFile();
size_t Read(char* buf, size_t buf_size, size_t offset);
size_t Write(char* buf, size_t buf_size);
int Open();
int Close();
private:
std::vector<MemBlock*> mem_blocks;
size_t write_offset;
size_t block_size;
int write_error;
bool complete;
MemBlock *block_in_progress;
sem_t block_ready;
MemBlock *NewBlock();
};
#endif
+340 -171
View File
@@ -8,6 +8,13 @@
#include "clients/smbclient.h"
#include "clients/ftpclient.h"
#include "clients/nfsclient.h"
#include "clients/webdav.h"
#include "clients/apache.h"
#include "clients/archiveorg.h"
#include "clients/iis.h"
#include "clients/nginx.h"
#include "clients/npxserve.h"
#include "clients/rclone.h"
#include "filehost/filehost.h"
#include "config.h"
#include "fs.h"
@@ -24,9 +31,18 @@
#define SUCCESS_MSG "{ \"result\": { \"success\": true, \"error\": null } }"
#define FAILURE_MSG "{ \"result\": { \"success\": false, \"error\": \"%s\" } }"
#define SUCCESS_MSG_LEN 48
#define PKG_INITIAL_REQUEST_SIZE 8388608ul
using namespace httplib;
struct RemoteDownloadData
{
RemoteClient *client = nullptr;
std::map<std::string, void *> fp_handles;
};
static RemoteDownloadData remote_data[100];
Server *svr;
int http_server_port = 8080;
char compressed_file_path[1024];
@@ -91,22 +107,22 @@ namespace HttpServer
return s;
}
void failed(Response & res, int status, const std::string &msg)
void failed(Response &res, int status, const std::string &msg)
{
res.status = status;
char response_msg[msg.length()+strlen(FAILURE_MSG)+2];
char response_msg[msg.length() + strlen(FAILURE_MSG) + 2];
snprintf(response_msg, sizeof(response_msg), "{ \"result\": { \"success\": false, \"error\": \"%s\" } }", msg.c_str());
res.set_content(response_msg, strlen(response_msg), "application/json");
return;
}
void bad_request(Response & res, const std::string &msg)
void bad_request(Response &res, const std::string &msg)
{
failed(res, 200, msg);
return;
}
void success(Response & res)
void success(Response &res)
{
res.status = 200;
res.set_content(SUCCESS_MSG, SUCCESS_MSG_LEN, "application/json");
@@ -182,15 +198,89 @@ namespace HttpServer
return 1;
}
static RemoteClient *GetRemoteClient(int site_idx, bool new_client)
{
RemoteClient *tmp_client;
RemoteSettings *tmp_settings = &site_settings[sites[site_idx]];
if (!new_client)
{
tmp_client = remote_data[site_idx].client;
if (tmp_client != nullptr)
return tmp_client;
}
if (tmp_settings->type == CLIENT_TYPE_SFTP)
{
tmp_client = new SFTPClient();
}
else if (tmp_settings->type == CLIENT_TYPE_SMB)
{
tmp_client = new SmbClient();
}
else if (tmp_settings->type == CLIENT_TYPE_FTP)
{
tmp_client = new FtpClient();
}
else if (tmp_settings->type == CLIENT_TYPE_NFS)
{
tmp_client = new NfsClient();
}
else if (tmp_settings->type == CLIENT_TYPE_WEBDAV)
{
tmp_client = new WebDAVClient();
}
else if (tmp_settings->type == CLIENT_TYPE_GOOGLE)
{
if (remoteclient != nullptr && remoteclient->clientType() == CLIENT_TYPE_GOOGLE)
tmp_client = remoteclient;
else
tmp_client = new GDriveClient();
tmp_client->Connect("", "", "");
}
else if (tmp_settings->type == CLIENT_TYPE_HTTP_SERVER)
{
if (strcmp(remote_settings->http_server_type, HTTP_SERVER_APACHE) == 0)
tmp_client = new ApacheClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_MS_IIS) == 0)
tmp_client = new IISClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_NGINX) == 0)
tmp_client = new NginxClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_NPX_SERVE) == 0)
tmp_client = new NpxServeClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_RCLONE) == 0)
tmp_client = new RCloneClient();
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_ARCHIVEORG) == 0)
tmp_client = new ArchiveOrgClient();
}
if (tmp_client->clientType() != CLIENT_TYPE_GOOGLE)
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
if (!new_client && tmp_client->clientType() != CLIENT_TYPE_FTP)
{
remote_data[site_idx].client = tmp_client;
}
return tmp_client;
}
static void DeleteRemoteClient(RemoteClient *tmp_client, int site_idx)
{
if (tmp_client != nullptr && tmp_client->clientType() != CLIENT_TYPE_GOOGLE)
{
tmp_client->Quit();
delete tmp_client;
}
}
void *ServerThread(void *argp)
{
svr->Get("/", [&](const Request & req, Response & res)
{
res.set_redirect("/index.html");
});
svr->Get("/", [&](const Request &req, Response &res)
{ res.set_redirect("/index.html"); });
svr->Get("/index.html", [&](const Request & req, Response & res)
{
svr->Get("/index.html", [&](const Request &req, Response &res)
{
FILE *in = FS::OpenRead("/mnt/sandbox/pfsmnt/RMTC00001-app0/assets/index.html");
size_t size = FS::GetSize("/mnt/sandbox/pfsmnt/RMTC00001-app0/assets/index.html");
res.set_content_provider(
@@ -206,11 +296,10 @@ namespace HttpServer
},
[in](bool success) {
FS::Close(in);
});
});
}); });
svr->Get("/favicon.ico", [&](const Request & req, Response & res)
{
svr->Get("/favicon.ico", [&](const Request &req, Response &res)
{
FILE *in = FS::OpenRead("/mnt/sandbox/pfsmnt/RMTC00001-app0/assets/favicon.ico");
size_t size = FS::GetSize("/mnt/sandbox/pfsmnt/RMTC00001-app0/assets/favicon.ico");
res.set_content_provider(
@@ -226,11 +315,10 @@ namespace HttpServer
},
[in](bool success) {
FS::Close(in);
});
});
}); });
svr->Post("/__local__/list", [&](const Request & req, Response & res)
{
svr->Post("/__local__/list", [&](const Request &req, Response &res)
{
const char *path;
bool onlyFolders = false;
json_object *jobj = json_tokener_parse(req.body.c_str());
@@ -276,11 +364,10 @@ namespace HttpServer
json_object_object_add(results, "result", json_files);
const char *results_str = json_object_to_json_string(results);
res.status = 200;
res.set_content(results_str, strlen(results_str), "application/json");
});
res.set_content(results_str, strlen(results_str), "application/json"); });
svr->Post("/__local__/rename", [&](const Request & req, Response & res)
{
svr->Post("/__local__/rename", [&](const Request &req, Response &res)
{
const char *item;
const char *newItemPath;
json_object *jobj = json_tokener_parse(req.body.c_str());
@@ -302,11 +389,10 @@ namespace HttpServer
FS::Rename(item, newItemPath);
success(res);
return;
});
return; });
svr->Post("/__local__/move", [&](const Request & req, Response & res)
{
svr->Post("/__local__/move", [&](const Request &req, Response &res)
{
const json_object *items;
const char *newPath;
json_object *jobj = json_tokener_parse(req.body.c_str());
@@ -357,11 +443,10 @@ namespace HttpServer
failed(res, 200, error_msg);
}
else
success(res);
});
success(res); });
svr->Post("/__local__/copy", [&](const Request & req, Response & res)
{
svr->Post("/__local__/copy", [&](const Request &req, Response &res)
{
const json_object *items;
const char *newPath;
const char *singleFilename;
@@ -432,11 +517,10 @@ namespace HttpServer
failed(res, 200, error_msg);
}
else
success(res);
});
success(res); });
svr->Post("/__local__/remove", [&](const Request & req, Response & res)
{
svr->Post("/__local__/remove", [&](const Request &req, Response &res)
{
json_object *items;
json_object *jobj = json_tokener_parse(req.body.c_str());
if (jobj != nullptr)
@@ -472,11 +556,10 @@ namespace HttpServer
failed(res, 200, error_msg);
}
else
success(res);
});
success(res); });
svr->Post("/__local__/install", [&](const Request & req, Response & res)
{
svr->Post("/__local__/install", [&](const Request &req, Response &res)
{
json_object *items;
json_object *jobj = json_tokener_parse(req.body.c_str());
if (jobj != nullptr)
@@ -509,11 +592,10 @@ namespace HttpServer
failed(res, 200, error_msg);
}
else
success(res);
});
success(res); });
svr->Post("/__local__/edit", [&](const Request & req, Response & res)
{
svr->Post("/__local__/edit", [&](const Request &req, Response &res)
{
const char *item;
const char *content;
size_t content_len;
@@ -543,11 +625,10 @@ namespace HttpServer
return;
}
success(res);
});
success(res); });
svr->Post("/__local__/getContent", [&](const Request & req, Response & res)
{
svr->Post("/__local__/getContent", [&](const Request &req, Response &res)
{
const char *item;
json_object *jobj = json_tokener_parse(req.body.c_str());
if (jobj != nullptr)
@@ -570,11 +651,10 @@ namespace HttpServer
json_object_object_add(result, "result", json_object_new_string(content.data()));
const char *result_str = json_object_to_json_string(result);
res.status = 200;
res.set_content(result_str, strlen(result_str), "application/json");
});
res.set_content(result_str, strlen(result_str), "application/json"); });
svr->Post("/__local__/createFolder", [&](const Request & req, Response & res)
{
svr->Post("/__local__/createFolder", [&](const Request &req, Response &res)
{
const char *newPath;
json_object *jobj = json_tokener_parse(req.body.c_str());
if (jobj != nullptr)
@@ -593,16 +673,13 @@ namespace HttpServer
}
FS::MkDirs(newPath);
success(res);
});
success(res); });
svr->Post("/__local__/permission", [&](const Request & req, Response & res)
{
failed(res, 200, "Operation not supported");
});
svr->Post("/__local__/permission", [&](const Request &req, Response &res)
{ failed(res, 200, "Operation not supported"); });
svr->Post("/__local__/compress", [&](const Request & req, Response & res)
{
svr->Post("/__local__/compress", [&](const Request &req, Response &res)
{
json_object *items;
const char* destination;
const char* compressedFilename;
@@ -652,11 +729,10 @@ namespace HttpServer
else
{
failed(res, 200, "Failed to create zip");
}
});
} });
svr->Post("/__local__/extract", [&](const Request & req, Response & res)
{
svr->Post("/__local__/extract", [&](const Request &req, Response &res)
{
const char* item;
const char* destination;
const char* folderName;
@@ -692,11 +768,10 @@ namespace HttpServer
else if (ret == -1)
failed(res, 200, "Unsupported compressed file format");
else
success(res);
});
success(res); });
svr->Get("/__local__/uploadResumeSize", [&](const Request &req, Response &res)
{
{
std::string destination = req.get_param_value("destination");
std::string filename = req.get_param_value("filename");
std::string file_path = destination + "/" + filename;
@@ -705,11 +780,10 @@ namespace HttpServer
size = FS::GetSize(file_path);
std::string result_str = "{\"size\":" + std::to_string(size) + "}";
res.status = 200;
res.set_content(result_str.c_str(), result_str.length(), "application/json");
});
res.set_content(result_str.c_str(), result_str.length(), "application/json"); });
svr->Post("/__local__/upload", [&](const Request &req, Response &res, const ContentReader &content_reader)
{
{
MultipartFormDataItems items;
std::string destination;
size_t chunk_size = 0;
@@ -775,12 +849,11 @@ namespace HttpServer
{
FS::Close(out);
}
success(res);
});
success(res); });
// Download multiple files as ZIP
svr->Get("/__local__/downloadMultiple", [&](const Request & req, Response & res)
{
svr->Get("/__local__/downloadMultiple", [&](const Request &req, Response &res)
{
if (req.get_param_value_count("items") == 0 || req.get_param_value_count("toFilename") == 0)
{
failed(res, 200, "Required items and toFilename parameter missing");
@@ -834,12 +907,11 @@ namespace HttpServer
else
{
failed(res, 200, "Failed to create zip");
}
});
} });
// Download single file
svr->Get("/__local__/downloadFile", [&](const Request & req, Response & res)
{
svr->Get("/__local__/downloadFile", [&](const Request &req, Response &res)
{
std::string path = req.get_param_value("path", 0);
if (path.empty())
{
@@ -869,11 +941,10 @@ namespace HttpServer
},
[in](bool success) {
FS::Close(in);
});
});
}); });
svr->Get("/google_auth", [](const Request &req, Response &res)
{
{
std::string auth_code = req.get_param_value("code");
Client client(GOOGLE_OAUTH_HOST);
client.set_follow_location(true);
@@ -919,12 +990,11 @@ namespace HttpServer
}
login_state = -1;
std::string str = std::string(lang_strings[STR_FAIL_GET_TOKEN_MSG]) + " Google";
res.set_content(str.c_str(), "text/plain");
});
res.set_content(str.c_str(), "text/plain"); });
svr->Get("/rmt_inst/Site (\\d+)(/)(.*)", [&](const Request & req, Response & res)
{
RemoteClient *tmp_client;
svr->Get("/rmt_inst/Site (\\d+)(/)(.*)", [&](const Request &req, Response &res)
{
RemoteClient *tmp_client = nullptr;
RemoteSettings *tmp_settings;
auto site_idx = std::stoi(req.matches[1])-1;
std::string path;
@@ -932,33 +1002,6 @@ namespace HttpServer
if (site_idx != 98)
{
path = std::string("/") + std::string(req.matches[3]);
tmp_settings = &site_settings[sites[site_idx]];
if (tmp_settings->type == CLIENT_TYPE_SFTP)
{
tmp_client = new SFTPClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_SMB)
{
tmp_client = new SmbClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_FTP)
{
tmp_client = new FtpClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else if (tmp_settings->type == CLIENT_TYPE_NFS)
{
tmp_client = new NfsClient();
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
}
else
{
tmp_client = remoteclient;
}
}
else
{
@@ -973,33 +1016,34 @@ namespace HttpServer
tmp_client->Connect(host, "", "");
}
if (tmp_client == nullptr || !tmp_client->IsConnected())
{
res.status = 404;
return;
}
if (req.method == "HEAD")
{
int64_t file_size;
int ret;
if (site_idx != 98)
tmp_client = GetRemoteClient(site_idx, true);
ret = tmp_client->Size(path, &file_size);
if (!ret)
{
res.status = 500;
DeleteRemoteClient(tmp_client, site_idx);
return;
}
res.status = 204;
res.set_header("Content-Length", std::to_string(file_size));
res.set_header("Accept-Ranges", "bytes");
DeleteRemoteClient(tmp_client, site_idx);
return;
}
if (req.ranges.empty())
{
res.status = 200;
if (site_idx != 98)
tmp_client = GetRemoteClient(site_idx, true);
res.set_content_provider(
(1024*128), "application/octet-stream",
[tmp_client, path](size_t offset, size_t length, DataSink &sink) {
@@ -1007,15 +1051,7 @@ namespace HttpServer
return (ret == 1);
},
[tmp_client, path, site_idx](bool success) {
if (tmp_client != nullptr && (tmp_client->clientType() == CLIENT_TYPE_SFTP
|| tmp_client->clientType() == CLIENT_TYPE_SMB
|| tmp_client->clientType() == CLIENT_TYPE_FTP
|| tmp_client->clientType() == CLIENT_TYPE_NFS
|| (tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98)))
{
tmp_client->Quit();
delete tmp_client;
}
DeleteRemoteClient(tmp_client, site_idx);
});
}
else
@@ -1024,33 +1060,61 @@ namespace HttpServer
size_t range_len = (req.ranges[0].second - req.ranges[0].first) + 1;
if (req.ranges[0].second >= 18000000000000000000ul)
{
range_len = 524288ul;
range_len = PKG_INITIAL_REQUEST_SIZE;
res.set_header("Content-Length", std::to_string(range_len));
res.set_header("Content-Range", std::string("bytes ") + std::to_string(req.ranges[0].first)+"-" + std::to_string(req.ranges[0].first+524288ul-1) + "/"+std::to_string(range_len));
res.set_header("Content-Range", std::string("bytes ") + std::to_string(req.ranges[0].first)+"-" + std::to_string(req.ranges[0].first+PKG_INITIAL_REQUEST_SIZE-1) + "/"+std::to_string(range_len));
sceRtcGetCurrentTick(&prev_tick);
if (site_idx != 98)
tmp_client = GetRemoteClient(site_idx, true);
}
else
{
if (site_idx != 98)
tmp_client = GetRemoteClient(site_idx, false);
}
std::pair<ssize_t, ssize_t> range = req.ranges[0];
res.set_content_provider(
range_len, "application/octet-stream",
[tmp_client, path, range, range_len](size_t offset, size_t length, DataSink &sink) {
int ret = tmp_client->GetRange(path, sink, range_len, range.first);
return (ret == 1);
},
[tmp_client, site_idx, path, range, range_len](bool success) {
if (tmp_client != nullptr && (tmp_client->clientType() == CLIENT_TYPE_SFTP
|| tmp_client->clientType() == CLIENT_TYPE_SMB
|| tmp_client->clientType() == CLIENT_TYPE_FTP
|| tmp_client->clientType() == CLIENT_TYPE_NFS
|| (tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98)))
[tmp_client, path, range, range_len, site_idx](size_t offset, size_t length, DataSink &sink) {
int ret;
if (range_len == PKG_INITIAL_REQUEST_SIZE)
{
tmp_client->Quit();
delete tmp_client;
ret = tmp_client->GetRange(path, sink, range_len, range.first);
}
else if ((tmp_client->SupportedActions() & REMOTE_ACTION_RAW_READ) == 0)
{
ret = tmp_client->GetRange(path, sink, range_len, range.first);
}
else
{
std::map<std::string, void *>::iterator it = remote_data[site_idx].fp_handles.find(path);
void *fp;
if (it == remote_data[site_idx].fp_handles.end())
{
fp = tmp_client->Open(path, O_RDONLY);
remote_data[site_idx].fp_handles[path] = fp;
}
else
{
fp = it->second;
}
ret = tmp_client->GetRange(fp, sink, range_len, range.first);
}
return (ret==1);
},
[tmp_client, path, range, site_idx](bool success) {
if (range.second >= 18000000000000000000ul ||
(tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98) ||
tmp_client->clientType() == CLIENT_TYPE_FTP)
{
DeleteRemoteClient(tmp_client, site_idx);
}
});
}
});
} });
svr->Get("/archive_inst/(.*)", [&](const Request & req, Response & res)
{
svr->Get("/archive_inst/(.*)", [&](const Request &req, Response &res)
{
RemoteClient *tmp_client;
RemoteSettings *tmp_settings;
std::string hash = req.matches[1];
@@ -1087,9 +1151,10 @@ namespace HttpServer
size_t range_len = (req.ranges[0].second - req.ranges[0].first) + 1;
if (req.ranges[0].second >= 18000000000000000000ul)
{
range_len = 524288ul;
range_len = PKG_INITIAL_REQUEST_SIZE;
res.set_header("Content-Length", std::to_string(range_len));
res.set_header("Content-Range", std::string("bytes ") + std::to_string(req.ranges[0].first)+"-" + std::to_string(req.ranges[0].first+524288ul-1) + "/"+std::to_string(range_len));
res.set_header("Content-Range", std::string("bytes ") + std::to_string(req.ranges[0].first)+"-" + std::to_string(req.ranges[0].first+PKG_INITIAL_REQUEST_SIZE-1) + "/"+std::to_string(range_len));
sceRtcGetCurrentTick(&prev_tick);
}
std::pair<ssize_t, ssize_t> range = req.ranges[0];
res.set_content_provider(
@@ -1104,15 +1169,77 @@ namespace HttpServer
[](bool success) {
return true;
});
}
});
} });
svr->Post("/__local__/install_url", [&](const Request & req, Response & res)
svr->Get("/split_inst/(.*)", [&](const Request &req, Response &res)
{
std::string hash = req.matches[1];
SplitPkgInstallData *pkg_data = INSTALLER::GetSplitPkgInstallData(hash);
if (pkg_data == nullptr)
{
failed(res, 500, "Cannot resume split_inst");
return;
}
if (req.method == "HEAD")
{
res.status = 204;
res.set_header("Content-Length", std::to_string(pkg_data->size));
res.set_header("Accept-Ranges", "bytes");
return;
}
if (req.ranges.empty())
{
res.status = 200;
res.set_content_provider(
131072, "application/octet-stream",
[pkg_data](size_t offset, size_t length, DataSink &sink) {
char *buf = (char*) malloc(131072);
size_t bytes_read = pkg_data->split_file->Read(buf, 131072, offset);
sink.write(buf, bytes_read);
free(buf);
return true;
},
[](bool success) {
return true;
});
}
else
{
res.status = 206;
size_t range_len = (req.ranges[0].second - req.ranges[0].first) + 1;
if (req.ranges[0].second >= 18000000000000000000ul)
{
range_len = PKG_INITIAL_REQUEST_SIZE;
res.set_header("Content-Length", std::to_string(range_len));
res.set_header("Content-Range", std::string("bytes ") + std::to_string(req.ranges[0].first)+"-" + std::to_string(req.ranges[0].first+PKG_INITIAL_REQUEST_SIZE-1) + "/"+std::to_string(range_len));
sceRtcGetCurrentTick(&prev_tick);
}
std::pair<ssize_t, ssize_t> range = req.ranges[0];
res.set_content_provider(
range_len, "application/octet-stream",
[pkg_data, range, range_len](size_t offset, size_t length, DataSink &sink) {
char *buf = (char*) malloc(range_len);
size_t bytes_read = pkg_data->split_file->Read(buf, range_len, range.first);
sink.write(buf, bytes_read);
free(buf);
return true;
},
[](bool success) {
return true;
});
} });
svr->Post("/__local__/install_url", [&](const Request &req, Response &res)
{
std::string url;
const char *url_param;
bool use_alldebrid = false;
bool use_realdebrid = false;
bool use_disk_cache = false;
json_object *jobj = json_tokener_parse(req.body.c_str());
if (jobj != nullptr)
@@ -1120,6 +1247,8 @@ namespace HttpServer
url_param = json_object_get_string(json_object_object_get(jobj, "url"));
use_alldebrid = json_object_get_boolean(json_object_object_get(jobj, "use_alldebrid"));
use_realdebrid = json_object_get_boolean(json_object_object_get(jobj, "use_realdebrid"));
use_disk_cache = json_object_get_boolean(json_object_object_get(jobj, "use_disk_cache"));
if (url_param == nullptr)
{
bad_request(res, "Required url_param parameter missing");
@@ -1153,6 +1282,8 @@ namespace HttpServer
file_transfering = true;
bytes_to_download = 100;
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
Windows::SetModalMode(true);
std::string download_url = filehost->GetDownloadUrl();
@@ -1161,10 +1292,9 @@ namespace HttpServer
failed(res, 200, lang_strings[STR_CANT_EXTRACT_URL_MSG]);
activity_inprogess = false;
file_transfering = false;
Windows::SetModalMode(true);
Windows::SetModalMode(false);
return;
}
delete(filehost);
size_t scheme_pos = download_url.find("://");
@@ -1175,23 +1305,65 @@ namespace HttpServer
BaseClient *baseclient = new BaseClient();
baseclient->Connect(host, "", "");
if (!baseclient->FileExists(path))
{
failed(res, 200, baseclient->LastResponse());
activity_inprogess = false;
file_transfering = false;
Windows::SetModalMode(false);
return;
}
baseclient->Head(path, &header, sizeof(pkg_header));
if (BE32(header.pkg_magic) == 0x7F434E54)
{
{
bytes_to_download = header.pkg_content_size;
FileHost::AddCacheDownloadUrl(hash, download_url);
std::string title = INSTALLER::GetRemotePkgTitle(baseclient, path, &header);
delete(baseclient);
std::string remote_install_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst/Site%2099/" + hash;
int rc = INSTALLER::InstallRemotePkg(remote_install_url, &header, title, false);
if (rc == 0)
if (!use_disk_cache)
{
failed(res, 200, lang_strings[STR_FAIL_INSTALL_FROM_URL_MSG]);
activity_inprogess = false;
file_transfering = false;
Windows::SetModalMode(true);
return;
std::string remote_install_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst/Site%2099/" + hash;
int rc = INSTALLER::InstallRemotePkg(remote_install_url, &header, title, false);
if (rc == 0)
{
failed(res, 200, lang_strings[STR_FAIL_INSTALL_FROM_URL_MSG]);
activity_inprogess = false;
file_transfering = false;
Windows::SetModalMode(false);
return;
}
}
else
{
SplitPkgInstallData *install_data = (SplitPkgInstallData*) malloc(sizeof(SplitPkgInstallData));
memset(install_data, 0, sizeof(SplitPkgInstallData));
OrbisTick tick;
sceRtcGetCurrentTick(&tick);
std::string install_pkg_path = std::string(temp_folder) + "/" + std::to_string(tick.mytick) + ".pkg";
SplitFile *sp = new SplitFile(install_pkg_path, INSTALL_ARCHIVE_PKG_SPLIT_SIZE/2);
install_data->split_file = sp;
install_data->remote_client = baseclient;
install_data->path = path;
baseclient->Size(path, &install_data->size);
install_data->stop_write_thread = false;
install_data->delete_client = true;
int ret = pthread_create(&install_data->thread, NULL, Actions::DownloadSplitPkg, install_data);
ret = INSTALLER::InstallSplitPkg(download_url, install_data, true);
if (ret == 0)
{
failed(res, 200, lang_strings[STR_FAIL_INSTALL_FROM_URL_MSG]);
activity_inprogess = false;
file_transfering = false;
Windows::SetModalMode(false);
return;
}
}
}
else
@@ -1218,6 +1390,7 @@ namespace HttpServer
failed(res, 200, lang_strings[STR_FAIL_INSTALL_FROM_URL_MSG]);
activity_inprogess = false;
file_transfering = false;
free(install_data);
Windows::SetModalMode(false);
return;
}
@@ -1231,21 +1404,17 @@ namespace HttpServer
return;
}
}
success(res);
});
success(res); });
svr->Get("/stop", [&](const Request & /*req*/, Response & /*res*/)
{
svr->stop();
});
{ svr->stop(); });
svr->set_error_handler([](const Request & /*req*/, Response &res)
{
{
const char *fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
res.set_content(buf, "text/html"); });
/*
svr->set_logger([](const Request &req, const Response &res)
@@ -1257,7 +1426,7 @@ namespace HttpServer
svr->set_payload_max_length(1024 * 1024 * 12);
svr->set_tcp_nodelay(true);
svr->set_mount_point("/", "/");
if (web_server_enabled)
svr->listen("0.0.0.0", http_server_port);
else
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef HTTP_SERVER_H
#define HTTP_SERVER_H
#ifndef EZ_HTTP_SERVER_H
#define EZ_HTTP_SERVER_H
#include "http/httplib.h"
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef LAUNCHER_SFO_H
#define LAUNCHER_SFO_H
#ifndef EZ_SFO_H
#define EZ_SFO_H
#pragma once
+9 -1
View File
@@ -155,7 +155,7 @@ size_t SplitFile::Write(char *buf, size_t buf_size)
size_t total_bytes_written = 0;
size_t remaining_to_write = buf_size;
while (remaining_to_write > 0)
while (remaining_to_write > 0 && !this->complete)
{
block_space_remaining = this->block_size - block_in_progress->size;
bytes_to_write = MIN(remaining_to_write, block_space_remaining);
@@ -192,6 +192,9 @@ size_t SplitFile::Write(char *buf, size_t buf_size)
int SplitFile::Close()
{
if (this->complete)
return 0;
if (block_in_progress->fd != nullptr)
{
fflush(block_in_progress->fd);
@@ -207,6 +210,11 @@ int SplitFile::Close()
return 0;
}
bool SplitFile::IsClosed()
{
return this->complete;
}
FileBlock *SplitFile::NewBlock()
{
FileBlock *block = (FileBlock *)malloc(sizeof(FileBlock));
+3 -2
View File
@@ -1,5 +1,5 @@
#ifndef SPLIT_FILE_H
#define SPLIT_FILE_H
#ifndef EZ_SPLIT_FILE_H
#define EZ_SPLIT_FILE_H
#include <string>
#include <vector>
@@ -31,6 +31,7 @@ public:
size_t Write(char* buf, size_t buf_size);
int Open();
int Close();
bool IsClosed();
private:
std::vector<FileBlock*> file_blocks;
+5
View File
@@ -1,3 +1,6 @@
#ifndef EZ_SYSTEM_H
#define EZ_SYSTEM_H
#include <stdint.h>
#ifdef __cplusplus
@@ -42,3 +45,5 @@ void convertLocalTimeToUtc(const OrbisDateTime *local_time, OrbisDateTime *utc);
#ifdef __cplusplus
}
#endif
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef LAUNCHER_TEXTURES_H
#define LAUNCHER_TEXTURES_H
#ifndef EZ_TEXTURES_H
#define EZ_TEXTURES_H
#include <string>
#include <SDL2/SDL.h>
+165 -13
View File
@@ -14,10 +14,11 @@
#include "util.h"
#include "lang.h"
#include "ime_dialog.h"
#include "IconsFontAwesome6.h"
#include "IconsFontAwesome6.h"
#include "OpenFontIcons.h"
#include "textures.h"
#include "sfo.h"
#include "system.h"
#define MAX_IMAGE_HEIGHT 980
#define MAX_IMAGE_WIDTH 1820
@@ -30,6 +31,9 @@ extern "C"
bool paused = false;
int view_mode;
static float scroll_direction = 0.0f;
static int selected_local_position = -1;
static int selected_remote_position = -1;
static ime_callback_t ime_callback = nullptr;
static ime_callback_t ime_after_update = nullptr;
static ime_callback_t ime_before_update = nullptr;
@@ -43,6 +47,8 @@ static char txt_http_server_port[6];
bool handle_updates = false;
int64_t bytes_transfered;
int64_t bytes_to_download;
OrbisTick prev_tick;
std::vector<DirEntry> local_files;
std::vector<DirEntry> remote_files;
std::set<DirEntry> multi_selected_local_files;
@@ -321,11 +327,13 @@ namespace Windows
if (ImGui::BeginCombo("##Site", display_site, ImGuiComboFlags_PopupAlignLeft | ImGuiComboFlags_HeightLargest | ImGuiComboFlags_NoArrowButton))
{
static char site_id[64];
static char site_display[512];
for (int n = 0; n < sites.size(); n++)
{
const bool is_selected = strcmp(sites[n].c_str(), last_site) == 0;
sprintf(site_id, "%s %d", lang_strings[STR_SITE], n + 1);
if (ImGui::Selectable(site_id, is_selected))
sprintf(site_display, "%s %d %s", lang_strings[STR_SITE], n + 1, site_settings[sites[n]].server);
if (ImGui::Selectable(site_display, is_selected))
{
sprintf(last_site, "%s", sites[n].c_str());
sprintf(display_site, "%s", site_id);
@@ -442,13 +450,33 @@ namespace Windows
}
if (ImGui::IsItemHovered())
{
ImGui::SetNextWindowSize(ImVec2(450, 70));
ImGui::SetNextWindowSize(ImVec2(450, 110));
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 440);
ImGui::Text("%s", lang_strings[STR_ENABLE_RPI_FTP_SMB_MSG]);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s:", lang_strings[STR_ENABLE_DISK_CACHE]);
ImGui::SameLine();
if (ImGui::Checkbox("###enable_disk_cache", &remote_settings->enable_disk_cache))
{
CONFIG::SaveConfig();
}
if (ImGui::IsItemHovered())
{
ImGui::SetNextWindowSize(ImVec2(550, 110));
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 540);
ImGui::Text("%s", lang_strings[STR_ENABLE_DISC_CACHE_MSG]);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
ImGui::PopStyleVar();
ImGui::SameLine();
@@ -614,6 +642,22 @@ namespace Windows
ImGui::Text("%s", item.name);
ImGui::EndTooltip();
}
if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadUp) && !paused)
{
if (j == 0)
{
selected_local_position = local_files.size()-1;
scroll_direction = 0.0f;
}
}
else if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadDown) && !paused)
{
if (j == local_files.size()-1)
{
selected_local_position = 0;
scroll_direction = 1.0f;
}
}
}
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
{
@@ -623,6 +667,12 @@ namespace Windows
ImGui::SetScrollHereY(0.5f);
sprintf(local_file_to_select, "");
}
if (selected_local_position == j && !paused)
{
SetNavFocusHere();
ImGui::SetScrollHereY(scroll_direction);
selected_local_position = -1;
}
selected_browser |= LOCAL_BROWSER;
}
ImGui::NextColumn();
@@ -779,6 +829,22 @@ namespace Windows
ImGui::Text("%s", item.name);
ImGui::EndTooltip();
}
if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadUp) && !paused)
{
if (j == 0)
{
selected_remote_position = remote_files.size()-1;
scroll_direction = 0.0f;
}
}
else if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadDown) && !paused)
{
if (j == remote_files.size()-1)
{
selected_remote_position = 0;
scroll_direction = 1.0f;
}
}
}
ImGui::PopID();
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
@@ -789,6 +855,12 @@ namespace Windows
ImGui::SetScrollHereY(0.5f);
sprintf(remote_file_to_select, "");
}
if (selected_remote_position == j && !paused)
{
SetNavFocusHere();
ImGui::SetScrollHereY(scroll_direction);
selected_remote_position = -1;
}
selected_browser |= REMOTE_BROWSER;
}
ImGui::NextColumn();
@@ -806,6 +878,23 @@ namespace Windows
ImGui::Columns(1);
ImGui::EndChild();
EndGroupPanel();
if (ImGui::IsKeyPressed(ImGuiKey_C) && !paused)
{
if (selected_browser & LOCAL_BROWSER)
{
selected_local_file = local_files[0];
selected_action = ACTION_CHANGE_LOCAL_DIRECTORY;
}
else if (selected_browser & REMOTE_BROWSER)
{
if (remoteclient != nullptr && remote_files.size() > 0)
{
selected_remote_file = remote_files[0];
selected_action = ACTION_CHANGE_REMOTE_DIRECTORY;
}
}
}
}
void StatusPanel()
@@ -1356,8 +1445,19 @@ namespace Windows
if (file_transfering)
{
static float progress = 0.0f;
static double transfer_speed = 0.0f;
static char progress_text[32];
static OrbisTick cur_tick;
static double tick_delta;
sceRtcGetCurrentTick(&cur_tick);
tick_delta = (cur_tick.mytick - prev_tick.mytick) * 1.0f / 1000000.0f;
progress = bytes_transfered * 1.0f / (float)bytes_to_download;
ImGui::ProgressBar(progress, ImVec2(625, 0));
transfer_speed = (bytes_transfered * 1.0f / tick_delta) / 1048576.0f;
sprintf(progress_text, "%.2f MB/s", transfer_speed);
ImGui::ProgressBar(progress, ImVec2(625, 0), progress_text);
}
ImGui::Separator();
@@ -1398,7 +1498,52 @@ namespace Windows
{
ImVec2 cur_pos = ImGui::GetCursorPos();
char id[128];
if (ImGui::Button(lang_strings[STR_ONETIME_URL], ImVec2(535, 0)))
ImGui::Checkbox("##enable_alldebrid_install_uril", &install_pkg_url.enable_alldebrid);
ImGui::SameLine();
ImGui::Text("%s", lang_strings[STR_ENABLE_ALLDEBRID_MSG]);
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+40);
ImGui::Checkbox("##enable_realdebrid_install_uril", &install_pkg_url.enable_realdebrid);
ImGui::SameLine();
ImGui::Text("%s", lang_strings[STR_ENABLE_REALDEBRID_MSG]);
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+40);
ImGui::Checkbox("##enable_rpi_install_url", &install_pkg_url.enable_rpi);
if (ImGui::IsItemHovered())
{
ImGui::SetNextWindowSize(ImVec2(550, 110));
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 540);
ImGui::Text("%s", lang_strings[STR_ENABLE_RPI_WEBDAV_MSG]);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
ImGui::SameLine();
ImGui::Text("%s", lang_strings[STR_ENABLE_RPI]);
if (install_pkg_url.enable_rpi)
{
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+40);
ImGui::Checkbox("##enable_diskcache_install_uril", &install_pkg_url.enable_disk_cache);
if (ImGui::IsItemHovered())
{
ImGui::SetNextWindowSize(ImVec2(550, 110));
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 540);
ImGui::Text("%s", lang_strings[STR_ENABLE_DISC_CACHE_MSG]);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
ImGui::SameLine();
ImGui::Text("%s", lang_strings[STR_ENABLE_DISKCACHE_DESC]);
}
ImGui::Separator();
if (ImGui::Button(lang_strings[STR_ONETIME_URL], ImVec2(1070, 0)))
{
ResetImeCallbacks();
sprintf(install_pkg_url.url, "%s", "");
@@ -1412,14 +1557,6 @@ namespace Windows
SetModalMode(false);
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
sprintf(id, "%s##favoriteurl", lang_strings[STR_CANCEL]);
if (ImGui::Button(id, ImVec2(535, 0)))
{
select_url_inprogress = false;
SetModalMode(false);
ImGui::CloseCurrentPopup();
}
ImGui::Separator();
for (int j = 0; j < MAX_FAVORITE_URLS; j++)
@@ -1467,6 +1604,13 @@ namespace Windows
}
}
if (ImGui::IsKeyPressed(ImGuiKey_GamepadFaceRight, false))
{
select_url_inprogress = false;
SetModalMode(false);
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
@@ -2495,6 +2639,14 @@ namespace Windows
if (ime_result == IME_DIALOG_RESULT_FINISHED)
{
CONFIG::SetClientType(remote_settings);
if (strncasecmp(remote_settings->server, "https://archive.org/", 20) == 0)
{
sprintf(remote_settings->http_server_type, "%s", HTTP_SERVER_ARCHIVEORG);
}
else if (strncasecmp(remote_settings->server, "https://myrient.erista.me/", 26) == 0)
{
sprintf(remote_settings->http_server_type, "%s", HTTP_SERVER_MYRIENT);
}
}
}
+4 -2
View File
@@ -1,5 +1,5 @@
#ifndef LAUNCHER_WINDOWS_H
#define LAUNCHER_WINDOWS_H
#ifndef EZ_WINDOWS_H
#define EZ_WINDOWS_H
#define IMGUI_DEFINE_MATH_OPERATORS
#include <set>
@@ -7,6 +7,7 @@
#include "imgui_internal.h"
#include "common.h"
#include "actions.h"
#include "system.h"
#include "SDL2/SDL.h"
#define LOCAL_BROWSER 1
@@ -16,6 +17,7 @@ extern int view_mode;
extern bool handle_updates;
extern int64_t bytes_transfered;
extern int64_t bytes_to_download;
extern OrbisTick prev_tick;
extern std::vector<DirEntry> local_files;
extern std::vector<DirEntry> remote_files;
extern std::set<DirEntry> multi_selected_local_files;
+71 -21
View File
@@ -72,6 +72,8 @@ namespace ZipUtil
convertToZipTime(file_stat.st_mtim.tv_sec, &zi.tmz_date);
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
bytes_to_download = file_stat.st_size;
// Large file?
@@ -288,8 +290,9 @@ namespace ZipUtil
static int extract2fd(struct archive *a, const std::string &pathname, int fd)
{
ssize_t len;
unsigned char *buffer = (unsigned char *) malloc(ARCHIVE_TRANSFER_SIZE);
unsigned char *buffer = (unsigned char *)malloc(ARCHIVE_TRANSFER_SIZE);
bytes_transfered = 0;
sceRtcGetCurrentTick(&prev_tick);
/* loop over file contents and write to fd */
for (int n = 0;; n++)
@@ -309,7 +312,7 @@ namespace ZipUtil
return 0;
}
bytes_transfered += len;
if (write(fd, buffer, len) != len)
{
sprintf(status_message, "error write('%s')", pathname.c_str());
@@ -451,6 +454,10 @@ namespace ZipUtil
client->Size(file, &data->size);
data->client = client;
data->path = file;
if (client->SupportedActions() & REMOTE_ACTION_RAW_READ)
{
data->fp = client->Open(file, O_RDONLY);
}
return data;
}
@@ -468,7 +475,11 @@ namespace ZipUtil
return 0;
to_read = MIN(to_read, ARCHIVE_TRANSFER_SIZE);
ret = data->client->GetRange(data->path, data->buf, to_read, data->offset);
if (data->client->SupportedActions() & REMOTE_ACTION_RAW_READ)
ret = data->client->GetRange((data->fp), data->buf, to_read, data->offset);
else
ret = data->client->GetRange(data->path, data->buf, to_read, data->offset);
if (ret == 0)
return -1;
data->offset = data->offset + to_read;
@@ -479,10 +490,46 @@ namespace ZipUtil
static int CloseRemoteArchive(struct archive *a, void *client_data)
{
if (client_data != nullptr)
{
RemoteArchiveData *data = (RemoteArchiveData *)client_data;
if (data->client->SupportedActions() & REMOTE_ACTION_RAW_READ)
data->client->Close(data->fp);
free(client_data);
}
return 0;
}
int64_t SeekRemoteArchive(struct archive *, void *client_data, int64_t offset, int whence)
{
RemoteArchiveData *data = (RemoteArchiveData *)client_data;
if (whence == SEEK_SET)
{
data->offset = offset;
}
else if (whence == SEEK_CUR)
{
data->offset = data->offset + offset - 1;
}
else if (whence == SEEK_END)
{
data->offset = data->size - 1;
}
else
return ARCHIVE_FATAL;
return data->offset;
}
int64_t SkipRemoteArchive(struct archive *, void *client_data, int64_t request)
{
RemoteArchiveData *data = (RemoteArchiveData *)client_data;
data->offset = data->offset + request - 1;
return request;
}
/*
* Main loop: open the zipfile, iterate over its contents and decide what
* to do with each entry.
@@ -520,13 +567,16 @@ namespace ZipUtil
return 0;
}
ret = archive_read_open(a, client_data, NULL, ReadRemoteArchive, CloseRemoteArchive);
ret = archive_read_set_seek_callback(a, SeekRemoteArchive);
if (ret < ARCHIVE_OK)
{
sprintf(status_message, "archive_read_set_seek_callback failed - %s", archive_error_string(a));
return 0;
}
ret = archive_read_open2(a, client_data, NULL, ReadRemoteArchive, SkipRemoteArchive, CloseRemoteArchive);
if (ret < ARCHIVE_OK)
{
if (client_data != nullptr)
{
free(client_data);
}
sprintf(status_message, "%s", "archive_read_open failed");
return 0;
}
@@ -568,7 +618,10 @@ namespace ZipUtil
int ret;
if ((a = archive_read_new()) == NULL)
{
sprintf(status_message, "%s", "archive_read_new failed");
return nullptr;
}
archive_read_support_format_all(a);
archive_read_support_filter_all(a);
@@ -592,13 +645,16 @@ namespace ZipUtil
return nullptr;
}
ret = archive_read_open(a, client_data, NULL, ReadRemoteArchive, CloseRemoteArchive);
ret = archive_read_set_seek_callback(a, SeekRemoteArchive);
if (ret < ARCHIVE_OK)
{
sprintf(status_message, "archive_read_set_seek_callback failed - %s", archive_error_string(a));
return 0;
}
ret = archive_read_open2(a, client_data, NULL, ReadRemoteArchive, SkipRemoteArchive, CloseRemoteArchive);
if (ret < ARCHIVE_OK)
{
if (client_data != nullptr)
{
free(client_data);
}
sprintf(status_message, "%s", "archive_read_open_filename failed");
return nullptr;
}
@@ -611,16 +667,14 @@ namespace ZipUtil
if (ret < ARCHIVE_OK)
{
sprintf(status_message, "%s", "archive_read_next_header failed");
if (client_data != nullptr)
{
free(client_data);
}
archive_read_free(a);
return nullptr;
}
if (ret == ARCHIVE_EOF)
{
break;
}
if ((pathname = pathdup(archive_entry_pathname(e))) == NULL)
{
@@ -689,10 +743,6 @@ namespace ZipUtil
if (ret < ARCHIVE_OK)
{
sprintf(status_message, "%s", "archive_read_next_header failed");
if (client_data != nullptr)
{
free(client_data);
}
archive_read_free(a);
return nullptr;
}
+4 -3
View File
@@ -1,5 +1,5 @@
#ifndef ZIP_UTIL_H
#define ZIP_UTIL_H
#ifndef EZ_ZIP_UTIL_H
#define EZ_ZIP_UTIL_H
#include <string.h>
#include <stdlib.h>
@@ -10,7 +10,7 @@
#include "common.h"
#include "fs.h"
#define ARCHIVE_TRANSFER_SIZE 5242880
#define ARCHIVE_TRANSFER_SIZE 20971520
static uint8_t MAGIC_ZIP_1[4] = {0x50, 0x4B, 0x03, 0x04};
static uint8_t MAGIC_ZIP_2[4] = {0x50, 0x4B, 0x05, 0x06};
@@ -30,6 +30,7 @@ enum CompressFileType {
struct RemoteArchiveData
{
void *fp;
std::string path;
ssize_t size;
ssize_t offset;