From 14441b7f0d6dd0a101b38a4500fe1f662ae00215 Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Tue, 13 Apr 2021 09:56:28 -0400 Subject: Releases page and file/dir listing works great on Linux. Should work on BSD hosts as well. --- captain/external.f90 | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 2 deletions(-) (limited to 'captain') diff --git a/captain/external.f90 b/captain/external.f90 index c4dcb5a..3ffa819 100644 --- a/captain/external.f90 +++ b/captain/external.f90 @@ -248,6 +248,92 @@ contains end subroutine get_job_page_title + function generate_releases_gemini(req) result(res) + use utilities + use server_response + use config + implicit none + + type(request), intent(in)::req + character(len=:), pointer::res + character(len=DIR_LIST_STRING_LENGTH), dimension(:), pointer::directories + character(len=DIR_LIST_STRING_LENGTH), dimension(:), pointer::files + + character(1024)::public_path, local_path, subpath + integer::allocation_size, i + character(1)::nl = new_line(' ') + character(4)::folder_icon = char(240)//char(159)//char(147)//char(129) + + if(.not. associated(req%query_string)) then + public_path = "/releases" + local_path = release_dir + else + call combine_paths("/releases", req%query_string, public_path) + call combine_paths(release_dir, req%query_string, local_path) + end if + + res => null() + + ! Easy safety check - no relative paths + if(index(local_path, '..') > 0) then + allocate(character(len=64)::res) + res = "None Found" + return + end if + + directories => get_directories_in_directory(local_path) + files => get_files_in_directory(local_path) + + allocation_size = 1024 + if(associated(directories)) then + allocation_size = allocation_size + size(directories) * DIR_LIST_STRING_LENGTH + end if + if(associated(files)) then + allocation_size = allocation_size + size(files) * DIR_LIST_STRING_LENGTH + end if + allocate(character(len=allocation_size) :: res) + res = "## Listing for "//trim(public_path) + + ! Add an "Up" link + if(trim(public_path) /= "/releases") then + i = index(req%query_string, "/", back=.true.) + if(i > 0) then + res = trim(res)//nl//"=> /releases.gmi?"//req%query_string(1:(i-1))//" Up a directory" + else + res = trim(res)//nl//"=> /releases.gmi Up a directory" + end if + end if + + if(associated(directories)) then + + do i = 1, size(directories) + + if(associated(req%query_string)) then + call combine_paths(req%query_string, trim(directories(i)), subpath) + else + subpath = trim(directories(i)) + end if + + res = trim(res)//nl//"=> /releases.gmi?"//trim(subpath)//" "//folder_icon//" "//trim(directories(i)) + end do + + deallocate(directories) + + end if + + if(associated(files)) then + + do i = 1, size(files) + call combine_paths(public_path, trim(files(i)), subpath) + res = trim(res)//nl//"=> "//trim(subpath)//" "//trim(files(i)) + end do + + deallocate(files) + + end if + + end function generate_releases_gemini + function generate_players_gemini() result(res) use captain_db implicit none @@ -544,8 +630,8 @@ contains resp%code = GEMINI_CODE_REDIRECT call resp%set_url("/players.gmi") - else if(req%location == "/jobs.gmi") then - ! Used for paging - send it back + else if(req%location == "/jobs.gmi" .or. req%location == "/releases.gmi") then + ! Used for paging (jobs) or subdirs (releases) - send it back resp = external_request_templated(req) else if(trim(first) == "instructions") then @@ -701,6 +787,8 @@ contains else if(trim(req%location) == "/releases.gmi") then call page%assign('title', 'Releases') + contents => generate_releases_gemini(req) + call page%assign('contents', contents) else if(trim(req%location) == "/jobs.gmi") then -- cgit v1.2.3