#!/usr/bin/perl # $Id: prontobrowser,v 1.5 2001/04/12 06:58:58 muhri Exp $ BEGIN { $libpath = $0; $libpath =~ s!/[^/]+$!!; $libpath =~ s!/bin$!/lib/pronto!; if (! -e $libpath) { die _("Can't find required files in ") . $libpath . "\n"; }; } use lib "$libpath"; use lib "$libpath/modules/lib/perl5/site_perl/5.005"; my ($HTMLWIDGET); eval 'use Csc::HTML; $HTMLWIDGET = "CscHTML";' or eval 'use Gtk::HTML; $HTMLWIDGET = "GtkHTML";'; use Gtk; init Gtk; use URI::URL; use IO::Socket; use MIME::Types; use File::Copy; require 'prontolib.pl'; Gtk::Widget->set_default_colormap(Gtk::Gdk::Rgb->get_cmap()); Gtk::Widget->set_default_visual(Gtk::Gdk::Rgb->get_visual()); if ($HTMLWIDGET eq "GtkHTML") { init Gtk::HTML; } else { init Csc::HTML; } &read_prefs; $conn=&open_db_conn; $url = $ARGV[0]; if ($url ne "") { &init_webbrowser($url); } else { &init_webbrowser } sub init_webbrowser { my ($url) = @_; my ($window, $bg, $query, $sql, @row); if (not defined $url) { $url = $prefs{'HomePage'};} $wb_win = new Gtk::Window("toplevel"); $wb_win->signal_connect('destroy' => sub { $wb_win->destroy; undef $wb_win; Gtk->exit(0);}); $wb_win->signal_connect('delete_event' => \&Gtk::false); $wb_win->set_default_size('640','480'); $wb_win->set_policy(1,1,0); $wb_win->set_title("Pronto Mini Browser"); $wb_win->{'vbox'} = new Gtk::VBox(0,0); $wb_win->{'vbox'}->show; $wb_win->show; $wb_win->add($wb_win->{'vbox'}); $window = $wb_win->window; $bg = $wb_win->style->bg('normal'); $wb_win->{'menu'} = new Gtk::MenuBar; $wb_win->{'menu'}->{'file'} = new Gtk::MenuItem("File"); $wb_win->{'menu'}->{'file'}->show; $wb_win->{'menu'}->show; $wb_win->{'menu'}->append($wb_win->{'menu'}->{'file'}); $wb_win->{'menu'}->{'view'} = new Gtk::MenuItem("View"); $wb_win->{'menu'}->{'view'}->show; $wb_win->{'menu'}->append($wb_win->{'menu'}->{'view'}); $wb_win->{'view_menu'} = new Gtk::Menu; $wb_win->{'menu'}->{'view'}->set_submenu($wb_win->{'view_menu'}); $wb_win->{'view_menu'}->{'debug'} = new Gtk::CheckMenuItem("Debug"); $wb_win->{'view_menu'}->{'debug'}->set_active(0); $wb_win->{'view_menu'}->{'debug'}->show; $wb_win->{'view_menu'}->{'debug'}->signal_connect("toggled" => \&debug); $wb_win->{'view_menu'}->append($wb_win->{'view_menu'}->{'debug'}); $wb_win->{'file_menu'} = new Gtk::Menu; $wb_win->{'menu'}->{'file'}->set_submenu($wb_win->{'file_menu'}); $wb_win->{'file_menu'}->{'new'} = new Gtk::MenuItem("New Window .."); $wb_win->{'file_menu'}->{'new'}->signal_connect("activate" => \&new_window); $wb_win->{'file_menu'}->{'new'}->show; $wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'new'}); $wb_win->{'file_menu'}->{'home'} = new Gtk::MenuItem("Home"); $wb_win->{'file_menu'}->{'home'}->signal_connect("activate" => \&wb_view_url, $prefs{'HomePage'}); $wb_win->{'file_menu'}->{'home'}->show; $wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'home'}); $wb_win->{'file_menu'}->{'back'} = new Gtk::MenuItem("Back"); $wb_win->{'file_menu'}->{'back'}->signal_connect("activate" => \&wb_view_url, "back"); $wb_win->{'file_menu'}->{'back'}->show; $wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'back'}); $wb_win->{'file_menu'}->{'search'} = new Gtk::MenuItem("Search"); $wb_win->{'file_menu'}->{'search'}->show; $wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'search'}); $wb_win->{'file_menu'}->{'close'} = new Gtk::MenuItem("Close"); $wb_win->{'file_menu'}->{'close'}->signal_connect("activate" => sub { $wb_win->destroy; undef $wb_win; Gtk->exit(0); }); $wb_win->{'file_menu'}->{'close'}->show; $wb_win->{'file_menu'}->append($wb_win->{'file_menu'}->{'close'}); $wb_win->{'file_menu'}->show; $wb_win->{'vbox'}->pack_start($wb_win->{'menu'},0,0,0); $wb_win->{'handlebox'} = new Gtk::HandleBox(); $wb_win->{'handlebox'}->show; $wb_win->{'toolbar'} = new Gtk::Toolbar('horizontal', 'both'); $wb_win->{'toolbar'}->set_button_relief('none'); $wb_win->{'toolbar'}->set_tooltips($prefs{'ToolTips'}); $wb_win->{'toolbar'}->border_width('2'); $wb_win->{'toolbar'}->show; $wb_win->{'handlebox'}->add($wb_win->{'toolbar'}); $wb_win->{'vbox'}->pack_start($wb_win->{'handlebox'},0,0,0); $wb_win->{'back_button'} = $wb_win->{'toolbar'}->append_item("Back","Click here to go back a page", "",new_pixmap("$prefs{'PixmapDir'}/back.xpm", $window, $bg)); $wb_win->{'home_button'} = $wb_win->{'toolbar'}->append_item("Home","Click here to go to your homepage", "",new_pixmap("$prefs{'PixmapDir'}/top.xpm", $window, $bg)); $wb_win->{'entry'} = new Gtk::Entry; $wb_win->{'entry'}->set_text($url); $wb_win->{'entry'}->show; $wb_win->{'toolbar'}->append_widget($wb_win->{'entry'}, "Type a URL here and press enter to go to that page", ""); $wb_win->{'entry'}->set_usize(300,25); $wb_win->{'go_button'} = new Gtk::Button; $wb_win->{'go_button'}->show; my ($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm($window,$bg,"$prefs{'PixmapDir'}/go.xpm"); $wb_win->{'go_button'}->{'pixmap'} = new Gtk::Pixmap($pixmap, $mask); $wb_win->{'go_button'}->{'pixmap'}->show; $wb_win->{'go_button'}->add($wb_win->{'go_button'}->{'pixmap'}); $wb_win->{'bookmarks'}->{'button'}= new Gtk::Button("Bookmarks"); $wb_win->{'bookmarks'}->{'button'}->set_usize(75,25); $wb_win->{'bookmarks'}->{'button'}->show; $wb_win->{'toolbar'}->append_widget($wb_win->{'go_button'}, "Click here to load page", ""); $wb_win->{'toolbar'}->append_widget($wb_win->{'bookmarks'}->{'button'}, "Bookmarks", ""); $wb_win->{'toolbar'}->insert_space(2); $wb_win->{'toolbar'}->insert_space(4); $wb_win->{'toolbar'}->insert_space(6); $wb_win->{'toolbar'}->set_space_size(10); $wb_win->{'statusbar'} = new Gtk::Statusbar; $wb_win->{'statusbar'}->show; $wb_win->{'progress'}=new Gtk::ProgressBar; $wb_win->{'progress'}->set_usize(200,20); $wb_win->{'progress'}->show; $wb_win->{'popup'} = new Gtk::Menu; $wb_win->{'popup'}->{'sep'} = new Gtk::MenuItem; $wb_win->{'popup'}->show; $wb_win->{'popup'}->{'sep'}->show; $wb_win->{'popup'}->append($wb_win->{'popup'}->{'sep'}); $wb_win->{'popup'}->{'new'} = new Gtk::MenuItem("Open in a new Window..."); $wb_win->{'popup'}->{'new'}->signal_connect("activate" => \&load_new); $wb_win->{'popup'}->append($wb_win->{'popup'}->{'new'}); $wb_win->{'popup'}->{'new'}->show; $wb_win->{'popup'}->{'save'} = new Gtk::MenuItem("Save Link As..."); $wb_win->{'popup'}->{'save'}->signal_connect("activate" => \&download_url); $wb_win->{'popup'}->{'save'}->show; $wb_win->{'popup'}->append($wb_win->{'popup'}->{'save'}); $wb_win->{'bookmarks'}->{'popup'} = new Gtk::Menu; $wb_win->{'bookmarks'}->{'popup'}->{'bm_page'} = new Gtk::MenuItem("Bookmark Current Page"); $wb_win->{'bookmarks'}->{'popup'}->{'bm_page'}->signal_connect("activate" => \&add_bookmark, $wb_win); $wb_win->{'bookmarks'}->{'popup'}->{'bm_page'}->show; $wb_win->{'bookmarks'}->{'popup'}->append($wb_win->{'bookmarks'}->{'popup'}->{'bm_page'}); $wb_win->{'bookmarks'}->{'popup'}->{'sep'} = new Gtk::MenuItem; $wb_win->{'bookmarks'}->{'popup'}->{'sep'}->show; $wb_win->{'bookmarks'}->{'popup'}->append($wb_win->{'bookmarks'}->{'popup'}->{'sep'}); $sql = "select id, title, url from bookmarks order by id"; $query=$conn->prepare($sql); $query->execute(); while (@row=$query->fetchrow_array()) { $wb_win->{'bookmarks'}->{'popup'}->{$row[0]} = new Gtk::MenuItem($row[1]); $wb_win->{'bookmarks'}->{'popup'}->{$row[0]}->signal_connect("activate" => \&wb_view_url, $row[2]); $wb_win->{'bookmarks'}->{'popup'}->{$row[0]}->show; $wb_win->{'bookmarks'}->{'popup'}->append($wb_win->{'bookmarks'}->{'popup'}->{$row[0]}); } if ($HTMLWIDGET eq "GtkHTML") { $wb_win->{'html'} = new Gtk::HTML; } else { $wb_win->{'html'} = new Csc::HTML; } if ($THREADS == 1) { $wb_win->{'html'}->signal_connect('url_requested' => \&thread_lwu); } else { $wb_win->{'html'}->signal_connect('url_requested' => \&load_wb_url); } $wb_win->{'html'}->signal_connect('link_clicked' => \&wb_view_url); $wb_win->{'html'}->signal_connect('title_changed' => \&set_title); $wb_win->{'html'}->signal_connect('on_url' => \&wb_status); $wb_win->{'html'}->signal_connect('submit' => \&on_submit); $wb_win->{'html'}->signal_connect('redirect' => \&on_redirect); $wb_win->{'html'}->set_editable(0); $wb_win->{'html'}->enable_debug(0); $wb_win->{'sw'} = new Gtk::ScrolledWindow(undef, undef); $wb_win->{'sw'}->set_policy('automatic', 'automatic'); $wb_win->{'sw'}->show; $wb_win->{'sw'}->add($wb_win->{'html'}); $wb_win->{'vbox'}->pack_start($wb_win->{'sw'},1,1,0); $wb_win->{'hbox'}= new Gtk::HBox(0,0); $wb_win->{'hbox'}->show; $wb_win->{'vbox'}->pack_end($wb_win->{'hbox'},0,0,0); $wb_win->{'hbox'}->pack_start($wb_win->{'statusbar'},1,1,0); $wb_win->{'hbox'}->pack_end($wb_win->{'progress'},0,0,0); $wb_win->{'html'}->realize; $wb_win->{'html'}->show; $wb_win->{'html'}->signal_connect('button_press_event' => \&wb_mouse_click); $wb_win->{'entry'}->signal_connect("activate" => \&wb_entry_url); $wb_win->{'back_button'}->signal_connect("clicked" => \&wb_view_url, "back"); $wb_win->{'home_button'}->signal_connect("clicked" => \&wb_view_url, $prefs{'HomePage'}); $wb_win->{'go_button'}->signal_connect("clicked" => \&wb_entry_url); $wb_win->{'bookmarks'}->{'button'}->signal_connect("clicked" => sub {$wb_win->{'bookmarks'}->{'popup'}->popup(undef, undef, 0, 0);}); $wb_win->{'file_menu'}->{'search'}->signal_connect("activate" => sub { $wb_win->{'html'}->search; }); &wb_view_url(undef, $url); return 1; } sub set_title { my ($widget, $title) = @_; $wb_win->set_title($title) } sub add_bookmark { my ($widget, $wb_win) = @_; my ($sql, $query, $title, $address, $id); $title = $wb_win->{'html'}->get_title(); $address = $wb_win->{'current'}->as_string; print ("title = $title\naddress = $address\n"); $sql = "insert into bookmarks (id, title, url) values (?, ?, ?)"; $query = $conn->prepare($sql); $id = &newid('bookmarks', $conn); $query->execute($id, $title, $address); $wb_win->{'bookmarks'}->{'popup'}->{$id} = new Gtk::MenuItem($title); $wb_win->{'bookmarks'}->{'popup'}->{$id}->signal_connect("activate" => \&wb_view_url, $address); $wb_win->{'bookmarks'}->{'popup'}->{$id}->show; $wb_win->{'bookmarks'}->{'popup'}->append($wb_win->{'bookmarks'}->{'popup'}->{$id}); return 1; } sub debug { my ($widget) = @_; if ($widget->active) { $wb_win->{'html'}->enable_debug(0); } else { $wb_win->{'html'}->enable_debug(1); } } sub on_submit { my ($widget, $method, $action, $encoding) = @_; if ($method eq "GET") { $action.="?$encoding"; &wb_view_url(undef, $action); } elsif ($method eq "POST") { $wb_win->{'length'} = length($encoding); $wb_win->{'message'} = $encoding; print ("$wb_win->{'message'}\n"); if (!$action) {$action = $wb_win->{'current'}; } &wb_view_url(undef, $action); } else { print ("Unsupported Form Method: $method\nAction: $action\nEncoding: $encoding\n"); } return 1; } sub redirect_timer_event { my ($redirect_url) = @_; Gtk->timeout_remove($redirect_timerID); undef $redirect_timerID; &wb_view_url(undef, $redirect_url); } sub on_redirect { my ($widget, $url, $delay) = @_; if (not defined $redirect_timerID) { $redirect_timerID = Gtk->timeout_add($delay * 1000, \&redirect_timer_event, $url); } } sub wb_mouse_click { my ($widget, $event) = @_; if ($event->{'button'} != 3) { return 1; } if (!$wb_win->{'mouse_url'}) { return 1; } $wb_win->{'popup'}->popup(undef, undef, $event->{'button'}, $event->{'time'}); return 1; } sub gtkhtml_mouse_click { my ($widget, $popup, $url, $event) = @_; if ($event->{'button'} != 3) { return 1; } if(!defined $$url) { return 1; } if($$url =~ /^file:$prefs{'MailDir'}\/tmp\//) { $popup->popup(undef, undef, $event, $event->{'time'}); } return 1; } sub wb_status { shift; my $url = shift; if (defined $url) { my $stat = (new URI::URL $url, $wb_win->{'base'})->abs($wb_win->{'base'},1); $wb_win->{'statusbar'}->push(1,$stat); $wb_win->{'mouse_url'} = $stat; } else { $wb_win->{'statusbar'}->pop(1); $wb_win->{'mouse_url'} = ""; } return 1; } sub wb_entry_url { my ($url); $url = $wb_win->{'entry'}->get_text; if ($url !~ /^\w+:/) { $url = "http://" . $url; } &wb_view_url(undef, $url); return 1; } sub wb_view_url { my ($widget, $url) = @_; if (!$url) { return 1; } my ($request, $host, $port, $path, $type, $header, $status, $st_num, $full_url, $socket, $redirect_url, $back); $back = 0; if ($url =~ /^mailto:(.+)/) { my ($address, @fields); $address = $1; $fields[0] = $address; $fields[1] = ""; $fields[2] = ""; my $child; unless ($child = fork) { die "cannot fork: $~" unless defined $child; exec("pronto $address"); } #&init_msg_window(0, undef, \@fields); return 1; } if (not defined $wb_win) { &init_webbrowser($url); return 1; } if ($url eq "back") { if (defined @{$wb_win->{'history'}}) { my $tmp = pop @{$wb_win->{'history'}}; if ($tmp) { $url = $tmp; $back = 1;} else { return 1; } } else { return 1; } } if (defined $wb_win) { $wb_win->{'statusbar'}->pop(1); } $wb_win->{'progress'}->set_activity_mode(1); if ($url =~ /^file:(.+)/) { $full_url = $url; my $path = $1; if (-d $path) { # its a directory if ($path !~ /\/$/) { $path.="/"; } $wb_win->{'entry'}->set_text($full_url); $wb_win->{'current'} = $full_url; $wb_win->{'base'} = $full_url; $type = "text/html"; my $i = 1000; opendir DIR, $path; my @entries = grep !/^\.\.?$/, readdir DIR; closedir(DIR); open (TMP,">$prefs{'MailDir'}/temp.html"); print TMP ("Items in $path\n"); print TMP ("

Items in $path

\n"); print TMP (".
\n"); my $tmp = $path; $tmp =~ s/(.*\/)\w+\/$/$1/; print TMP ("..
\n"); foreach (sort(@entries)) { if (-d "$path$_") { print TMP ("$_
\n"); } else { print TMP ("$_
\n"); } } print TMP (""); close(TMP); $full_url = "file:$prefs{'MailDir'}/temp.html"; } else { # its a file of some sort ($type) = MIME::Types::by_suffix($1); if (!$type) { $type = "application/unknown"; } } } else { $full_url = (new URI::URL $url, $wb_win->{'base'})->abs($wb_win->{'base'},1); # $full_url =~ s/%(\w\w)/chr(hex($1))/eg; $full_url =~ /http:\/\/([\w\.-]+)([:\d]*)(.*)/; if (!$3) { $path = "/"; } else { $path = $3; } if (!$2) { $port = 80; } else { $port = $2; } if (!$1) { return 1; } else { $host = $1; } if ($prefs{'Proxy'}) { $socket = IO::Socket::INET->new(PeerAddr => $prefs{'Proxy'}, PeerPort => $prefs{'ProxyPort'}, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM) or return 1; print $socket "HEAD $full_url HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n"; } else { $socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM) or return 1; print $socket "HEAD $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n"; } CONTINUE: $status = <$socket>; $/ = ""; $header = <$socket>; $/ = "\n"; $status =~ /HTTP\/\d.\d (\d+)/ and $st_num = $1; if ($st_num == 301 || $st_num == 302) { $header =~ /Location: ?(.+)/i and $redirect_url = $1; &wb_view_url(undef, $redirect_url); return 1; } elsif ($st_num == 100) { goto CONTINUE; } elsif ($st_num != 200) { &err_dialog("$status"); return 1; } $header =~ /Content-Type: ?(.+)/i and $type = $1; } if ($type !~ /text\//i) { if ($type =~ /image\//) { $full_url =~ s/ /%20/g; open (TMP,">$prefs{'MailDir'}/temp.html"); print TMP ("$full_url"); close(TMP); $full_url = "file:$prefs{'MailDir'}/temp.html"; } else { &download_url(undef, $full_url); return 1; } } if (defined $wb_win->{'current'} && $back != 1) { push @{$wb_win->{'history'}}, $wb_win->{'current'}; } $wb_win->{'current'} = $full_url; $wb_win->{'base'} = $full_url; $wb_win->{'entry'}->set_text($full_url); if ($THREADS == 1) { &thread_lwu($wb_win->{'html'}, $full_url, $wb_win->{'html'}->begin) } else { &load_wb_url($wb_win->{'html'}, $full_url, $wb_win->{'html'}->begin) } $wb_win->{'progress'}->set_activity_mode(0); return 1; } sub download_url { my ($widget, $url) = @_; if (!$url && !($url = $wb_win->{'mouse_url'})) { return 1; } my ($filename, $fs_window); $url =~ /\/([-\w\.]+)$/ and $filename = $1; if (!$filename) { $filename=""; } print ("File before: $filename\n"); $fs_window = new Gtk::FileSelection "Download File"; $fs_window->position(-mouse); $fs_window->signal_connect("destroy", sub {$fs_window->destroy;}); $fs_window->signal_connect("delete_event" => \&Gtk::false); $fs_window->ok_button->signal_connect("clicked", \&begin_dl, $fs_window, $url); $fs_window->cancel_button->signal_connect("clicked", sub {$fs_window->destroy;}); $fs_window->set_filename($filename); $fs_window->show; return 1; } sub begin_dl { my ($widget, $fs_window, $url) = @_; my ($fh, $status_dialog, $sd_vbox, $sd_label, $sd_pbar, $sd_button, $path, $port, $host, $socket, $status, $st_num, $length, $count, $d); my ($answer, $header) = ("",""); my $filename = $fs_window->get_filename(); print ("Filename: $filename\n"); $fs_window->destroy; if ($url =~ /^file:(.+)/) { my $from = $1; copy($from, $filename); return 1; } $status_dialog = new Gtk::Dialog; $status_dialog->signal_connect("destroy" => sub { $status_dialog->destroy; }); $status_dialog->signal_connect("delete_event" => sub { $status_dialog->destroy; }); $status_dialog->set_title("Downloading File..."); $status_dialog->border_width(0); $sd_vbox=new Gtk::VBox(0,5); $sd_vbox->border_width(10); $status_dialog->vbox->pack_start($sd_vbox,1,1,0); $sd_vbox->show; $sd_label=new Gtk::Label "Downloading $filename..."; $sd_label->set_alignment(0.0,0.5); $sd_vbox->pack_start($sd_label,0,1,0); $sd_label->show; $sd_pbar=new Gtk::ProgressBar; $sd_pbar->set_usize(200,20); $sd_vbox->pack_start($sd_pbar,1,1,0); $sd_pbar->show; $sd_pbar->set_show_text(1); $sd_pbar->set_text_alignment(0.5,0.5); $sd_pbar->set_format_string("%v of %u - %p %%"); $sd_button=new Gtk::Button "Cancel Transfer"; $sd_button->can_default(1); $status_dialog->action_area->pack_start($sd_button,1,1,0); $sd_button->grab_default; $sd_button->show; $status_dialog->show; $sd_button->signal_connect("clicked", sub { $status_dialog->destroy; $fh->close; $socket->close; return 1; }); # $url =~ s/%(\w\w)/chr(hex($1))/eg; # $url =~ s/ //g; $url =~ /http:\/\/([\w\.-]+)([:\d]*)(.*)/; if (!$3) { $path = "/"; } else { $path = $3; } if (!$2) { $port = 80; } else { $port = $2; } if (!$1) { return 1; } else { $host = $1; } print ("Host: $host\nPath: $path\nPort: $port\n"); if ($prefs{'Proxy'}) { $socket = IO::Socket::INET->new(PeerAddr => $prefs{'Proxy'}, PeerPort => $prefs{'ProxyPort'}, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM); print $socket "GET $url HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n"; } else { $socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM); print $socket "GET $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n"; } CONTINUE: $status = <$socket>; $status =~ /HTTP\/\d.\d (\d+)/ and $st_num = $1; while (defined $answer and $answer ne "\n") { $answer = <$socket>; if ($answer) { $answer =~ s/\r//g; $header.= $answer; } } if ($st_num == 301 || $st_num ==302) { $header =~ /\nLocation: ?(.+)/i and $url = $1; &begin_dl($widget, $fs_window, $url); return 1; } elsif ($st_num == 100) { goto CONTINUE; } elsif ($st_num != 200) { &err_dialog("$status"); return 1; } print ("$header\n"); $header =~ /Content-Length: ?(\d+)/i and $length = $1; $sd_pbar->configure(0,0,$length); if ($fh = new IO::File ">$filename") { if (defined $length && $length > 8192) { my $numfullpackets = int($length/8192); my $lastpacket = $length - ($numfullpackets * 8192); for (my $i = 1; $i <= $numfullpackets; $i++) { $count+=8192; $sd_pbar->set_value($count); while (Gtk->events_pending) { Gtk->main_iteration; } $socket->read($d, 8192); print $fh $d; } $socket->read($d, $lastpacket); } else { $socket->read($d, 8192); } print $fh $d; } $status_dialog->destroy; return 1; } sub thread_lwu { my ($html, $url, $handle) = @_; my $t = new Thread \&thread_start_lwu, $html, $url, $handle; $t->detach; return 1; } sub thread_start_lwu { my ($html, $url, $handle) = @_; Gtk::Gdk->threads_enter(); &load_wb_url($html, $url, $handle); Gtk::Gdk->threads_leave(); POSIX::_exit(); } sub load_wb_url { my ($html, $url, $handle) = @_; my ($full_url, $socket, $answer, $length, $header, $host, $path, $port, $d, $xferencode, $status, $st_num); $header=""; $answer = ""; $full_url = (new URI::URL $url, $wb_win->{'base'})->abs($wb_win->{'base'},1); if ($full_url->as_string =~ /^file:(.+)/) { my $path = $1; $path =~ s/%(\w\w)/chr(hex($1))/eg; my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size)=stat $path; $socket = IO::File->new($path) or return 1; $socket->read($d, $size); $html->write($handle, $d); $html->end($handle, 'ok'); return 1; } $full_url =~ /http:\/\/([\w\.-]+)([:\d]*)(.*)/; if (!$3) { $path = "/"; } else { $path = $3; } if (!$2) { $port = 80; } else { $port = $2; } if ($1) { $host = $1; } else { return 1; } if ($prefs{'Proxy'}) { $socket = IO::Socket::INET->new(PeerAddr => $prefs{'Proxy'}, PeerPort => $prefs{'ProxyPort'}, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM) or return 1; } else { $socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => "TCP", Timeout => "30", Type => SOCK_STREAM) or return 1; } if (!$wb_win->{'message'}) { if ($prefs{'Proxy'}) { print $socket "GET $full_url HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n"; } else { print $socket "GET $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\n\r\n"; } } else { if ($prefs{'Proxy'}) { print $socket "POST $full_url HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\nContent-type: application/x-www-form-urlencode\r\nContent-length: $wb_win->{'length'}\r\n\r\n$wb_win->{'message'}\r\n"; } else { print $socket "POST $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: Pronto/$version\r\nConnection: close\r\nContent-type: application/x-www-form-urlencode\r\nContent-length: $wb_win->{'length'}\r\n\r\n$wb_win->{'message'}\r\n"; } undef $wb_win->{'message'}; undef $wb_win->{'length'}; } CONTINUE: $status = <$socket>; $status =~ /HTTP\/\d.\d (\d+)/ and $st_num = $1; while (defined $answer and $answer ne "\n") { $answer = <$socket>; if ($answer) { $answer =~ s/\r//g; $header.= $answer; } } if ($st_num == 301 || $st_num ==302) { $url = ""; $header =~ /Location: ?(.+)/i and $url = $1; unless ($url eq "") { &load_wb_url($html, $url, $handle); return 1; } } elsif ($st_num == 100) { $answer = ""; goto CONTINUE; } elsif ($st_num != 200) { &err_dialog("$status"); return 1; } $header =~ /Content-Length: ?(\d+)/i and $length = $1; $header =~ /\nTransfer-Encoding: ?(.+)/i and $xferencode = $1; if (defined $xferencode && $xferencode =~ /chunked/) { $wb_win->{'progress'}->set_activity_mode(1); my ($body, $line); $/ = "\r\n"; $line = <$socket>; $/ = "\n"; $line =~ /^(\w+)/ and $length = $1; while (hex($length) > 0) { $socket->read($d, hex($length)); $body.=$d; $/ = "\r\n"; $line = <$socket>; $line = <$socket>; $length = 0; $line =~ /^(\w+)/ and $length = $1; $/ = "\n"; } $html->write($handle, $body); $wb_win->{'progress'}->set_activity_mode(0); } else { if (defined $length && $length > 8192) { $wb_win->{'progress'}->configure(0,0,$length); my $numfullpackets = int($length/8192); my $lastpacket = $length - ($numfullpackets * 8192); for (my $i = 1; $i <= $numfullpackets; $i++) { $socket->read($d, 8192); $wb_win->{'progress'}->set_value($i * 8192); $html->write($handle, $d); } $wb_win->{'progress'}->set_value($length); $socket->read($d, $lastpacket); } else { $socket->read($d, 65535); } $html->write($handle, $d); } $html->end($handle, 'ok'); $wb_win->{'progress'}->set_value(0); return 1; } sub new_pixmap { my ($filename, $window, $background) = @_; my ($pixmap, $mask) = create_from_xpm Gtk::Gdk::Pixmap($window, $background, $filename); return new Gtk::Pixmap($pixmap, $mask); } sub load_new { my ($widget, $url) = @_; if (!$url && !($url = $wb_win->{'mouse_url'})) { return 1; } my $child; unless ($child = fork) { die "cannot fork: $~" unless defined $child; exec("prontobrowser $url"); } } sub new_window { my $child; unless ($child = fork) { die "cannot fork: $~" unless defined $child; exec("prontobrowser"); } } main Gtk;