program gemini use request use dumb_render use gemini_protocol use layout use file_handling use history #ifdef WINDOWS use wsa_network, only: windows_network_startup => startup #endif implicit none character(256)::initial_site character(1024)::current_url, input type(connection)::conn type(dumb_renderer)::r logical::running logical::loaded logical::populated integer::return_code integer, parameter::io = 100 type(line), pointer::first_line type(location), pointer::locations_visited #ifdef WINDOWS call windows_network_startup() #endif if(command_argument_count() > 0) then call get_command_argument(1, initial_site) if(index(initial_site, "//") > 0) then if(index(initial_site, "gemini://") /= 1) then Print *, "Please provide a gemini URL to start (or nothing at all)" stop end if else initial_site = "gemini://"//trim(initial_site) end if else initial_site = "gemini://gemini.circumlunar.space/" ! gemini://pon.ix.tc/ end if running = .true. loaded = .false. call r%initialize() locations_visited => null() current_url = initial_site open(unit=io, form="formatted", status="scratch", access='stream') do while(running) if(index(current_url, "gemini://") /= 1) then call r%draw_error("Only gemini:// URLs are supported") populated = .false. loaded = .true. return_code = STATUS_LOCALFAIL end if if(.not. loaded) then call r%report_status("Requesting "//trim(current_url)) return_code = request_url(current_url, io) populated = .true. call update_status(r, current_url, return_code) end if if(return_code == STATUS_REDIRECT) then call get_redirect_url(io, current_url) loaded = .false. populated = .false. else if(return_code == STATUS_INPUT) then if(handle_input(r, current_url, io)) then ! Should force a new load loaded = .false. else loaded = .true. end if else if(populated) then locations_visited => add_location(locations_visited, current_url) first_line => load_unit(io, file_type_gemini) loaded = .true. call r%new_page() call r%report_status("Performing Layout") call layout_lines(first_line, r) end if do while(loaded .and. running) select case(r%request_action(input)) case (render_action_quit) running = .false. case (render_action_back) call back_location(locations_visited, current_url) call free_lines(first_line) loaded = .false. case (render_action_layout) call r%report_status("Performing Layout") call layout_lines(first_line, r) case (render_action_goto) if(index(input, "://") > 0) then current_url = input else call handle_relative_url(current_url, input) end if call free_lines(first_line) loaded = .false. end select end do end do close(io) contains subroutine update_status(r, url, code) use gemini_protocol implicit none class(renderer)::r character(*), intent(in)::url integer, intent(in)::code select case (code) case (STATUS_LOCALFAIL) call r%report_status("Network failure loading "//trim(url)) case (STATUS_INPUT) call r%report_status("Ok (input)") case (STATUS_SUCCESS) call r%report_status("Ok") case (STATUS_REDIRECT) call r%report_status("Ok (redirect)") case (STATUS_TEMPFAIL) call r%report_status("Server reports temporary failure") case (STATUS_PERMFAIL) call r%report_status("Server reports permanent failure") case (STATUS_CERTREQ) call r%report_status("Server requesting certificate (unsupported)") end select end subroutine update_status end program gemini