Viewing file: ppp-client-lib.pl (8.47 KB) -rwxr-xr-x Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# ppp-client-lib.pl # Common functions for configuring WV-Dial # XXX what about redhat connect process? # XXX what about SuSE connect process?
BEGIN { push(@INC, ".."); }; use WebminCore; &init_config(); $details_file = "$module_config_directory/connect"; $resolv_conf = "/etc/resolv.conf"; $ppp_resolv_conf = "/etc/ppp/resolv.conf"; $save_resolv_conf = $resolv_conf.".save";
# get_config() # Returns a list of all configuration settings sub get_config { local (@rv, $sect); local $lnum = 0; open(FILE, $config{'file'}); while(<FILE>) { s/^\s*;.*//; s/\r|\n//g; if (/^\s*\[(.*)\]/) { # Start of a section $sect = { 'name' => $1, 'index' => scalar(@rv), 'line' => $lnum, 'eline' => $lnum, 'values' => { }, 'onames' => { } }; push(@rv, $sect); } elsif (/^\s*([^=]+\S)\s*=\s*(.*)/ && $sect) { # A directive within a section $sect->{'values'}->{lc($1)} = $2; $sect->{'onames'}->{lc($1)} = $1; $sect->{'eline'} = $lnum; } $lnum++; } close(FILE); return \@rv; }
# create_dialer(&dialer) # Add a dialer to the configuration sub create_dialer { local $lref = &read_file_lines($config{'file'}); push(@$lref, "", &dialer_lines($_[0])); &flush_file_lines(); }
# update_dialer(&dialer) sub update_dialer { local $lref = &read_file_lines($config{'file'}); splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1, &dialer_lines($_[0])); &flush_file_lines(); }
# delete_dialer(&dialer) sub delete_dialer { local $lref = &read_file_lines($config{'file'}); splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1); if ($_[0]->{'line'} && $lref->[$_[0]->{'line'}-1] eq "") { splice(@$lref, $_[0]->{'line'}-1, 1); } &flush_file_lines(); }
# dialer_lines(&dialer) sub dialer_lines { local @rv = "[$_[0]->{'name'}]"; local $k; foreach $k (keys %{$_[0]->{'values'}}) { local $pk = $_[0]->{'onames'}->{$k} || $k; push(@rv, $pk." = ".$_[0]->{'values'}->{$k}); } return @rv; }
# device_name(device) # Returns a human-readable modem device name sub device_name { if ($_[0] =~ /^\/dev\/ttyS(\d+)$/) { return &text('device_serial', $1+1); } else { return "<tt>$_[0]</tt>"; } }
# save_connect_details(ip, pid, section) sub save_connect_details { &open_tempfile(DETAILS, ">$details_file"); &print_tempfile(DETAILS, $_[0],"\n",$_[1],"\n",$_[2],"\n"); &close_tempfile(DETAILS); }
# get_connect_details() sub get_connect_details { local ($ip, $pid, $sect); open(DETAILS, $details_file) || return (); chop($ip = <DETAILS>); chop($pid = <DETAILS>); chop($sect = <DETAILS>); close(DETAILS); return ($ip, $pid, $sect); }
# get_wvdial_pid() # Returns the PID of a running wvdial process sub get_wvdial_pid { local $p; &foreign_require("proc", "proc-lib.pl"); foreach $p (&proc::list_processes()) { if ($p->{'args'} =~ /^\S*wvdial($|\s)/ && $p->{'args'} !~ /\[/) { return $p->{'pid'}; } } return undef; }
sub dialer_name { return $_[0] =~ /^Dialer Defaults$/i ? $text{'index_defaults'} : $_[0] =~ /^Dialer\s+(.*)$/i ? &text('index_dialer', "$1") : $_[0]; }
# ppp_connect(section-name, textmode) sub ppp_connect { # Get this dialer's configuration local $conf = &get_config(); local ($dialer) = grep { lc($_->{'name'}) eq lc($_[0]) } @$conf; local ($ddialer) = grep { lc($_->{'name'}) eq 'dialer defaults' } @$conf; local ($inherits, $parent, $autodns); if ($inherits = $dialer->{'values'}->{'inherits'}) { ($parent) = grep { lc($_->{'name'}) eq lc($inherits) } @$conf; } $autodns = $dialer->{'values'}->{'auto dns'} ? ($dialer->{'values'}->{'auto dns'} =~ /on|yes|1/ ? 1 : 0) : $parent->{'values'}->{'auto dns'} ? ($parent->{'values'}->{'auto dns'} =~ /on|yes|1/ ? 1 : 0) : $ddialer->{'values'}->{'auto dns'} ? ($ddialer->{'values'}->{'auto dns'} =~ /on|yes|1/ ? 1 : 0) : 1;
# Run wvdial, writing to a temp file in the background local $stime = time(); local $sect = $_[0]; $sect =~ s/^Dialer\s+//; local $temp = &tempname(); if (!($pid = fork())) { untie(*STDIN); untie(*STDOUT); untie(*STDERR); open(STDOUT, ">$temp"); open(STDERR, ">&STDOUT"); open(STDIN, "/dev/null"); exec($config{'wvdial'}, $sect); exit(1); } while (!open(TEMP, $temp)) { } &additional_log("exec", undef, "$config{'wvdial'} $sect"); unlink($temp);
# Read output until success or failure if ($_[1] == 1) { print &text('connect_cmd', "$config{'wvdial'} $sect"),"\n\n"; } elsif ($_[1] == 0) { print "<b>",&text('connect_cmd', "<tt>$config{'wvdial'} $sect</tt>"),"</b><br>\n"; print "<pre>"; } local ($connected, $failed); while(1) { local $line = &wait_for_line(); if ($_[1] == 1) { print $line; } elsif ($_[1] == 0) { print &html_escape($line); } if ($line =~ /IP\s+address\s+is\s+(\d+\.\d+\.\d+\.\d+)/i) { # Connected OK! $connected = $1 eq "0.0.0.0" ? "*" : $1; last; } elsif ($line =~ /starting\s+ppp/i) { # Connected in stupid mode $connected = "*"; last; } elsif (!$line) { # Program terminated .. must have failed! $failed++; last; } } print "</pre>\n" if ($_[1] == 0);
# If OK, save the PID for later if ($connected) { if ($_[1] == 0) { print "<b>",$connected eq '*' ? $text{'connect_noip'} : &text('connect_ip', "<tt>$connected</tt>"),"</b><p>\n"; } elsif ($_[1] == 1) { print $connected eq '*' ? $text{'connect_noip'} : &text('connect_ip', $connected),"\n"; } &save_connect_details($connected, $pid, $_[0]); } else { if ($_[1] == 0) { print "<b>$text{'connect_failed'}</b><p>\n"; } elsif ($_[1] == 1) { print "$text{'connect_failed'}\n\n"; } } $config{'dialer'} = $_[0]; &lock_file("$module_config_directory/config"); &write_file("$module_config_directory/config", \%config); &unlock_file("$module_config_directory/config");
if ($connected && $autodns) { # If the resolv.conf file has not been modified, and the PPP # resolv.conf has, copy it into place while(1) { sleep(3); local ($ip, $pid, $sect) = &get_connect_details(); if (!$pid || !kill(0, $pid)) { # Connection is down .. DNS will never be updated if ($_[1] == 0) { print "<b>$text{'connect_dnsdown'}</b><p>\n"; } elsif ($_[1] == 1) { print "$text{'connect_dnsdown'}\n\n"; } last; } $now = time(); if ($now > $stime+60) { # Took too long to update DNS if ($_[1] == 0) { print "<b>$text{'connect_dnsto'}</b><p>\n"; } elsif ($_[1] == 1) { print "$text{'connect_dnsto'}\n\n"; } last; } local @pst = stat($ppp_resolv_conf); local @ost = stat($resolv_conf); if ($ost[9] >= $stime) { # Something else has update the DNS config .. if ($_[1] == 0) { print "<b>$text{'connect_dns2'}</b><p>\n"; } elsif ($_[1] == 1) { print "$text{'connect_dns2'}\n\n"; } last; } if ($pst[9] >= $stime) { # A PPP DNS config has been created .. use it &system_logged("cp $resolv_conf $save_resolv_conf") if (!-l $resolv_conf); unlink($resolv_conf); &system_logged("cp $ppp_resolv_conf $resolv_conf"); if ($_[1] == 0) { print "<b>$text{'connect_dns'}</b><p>\n"; } elsif ($_[1] == 1) { print "$text{'connect_dns'}\n\n"; } last; } } } return $connected; }
# wait_for_line() # Reads a line from the temp file, or waits if there is no more to read. Only # returns undef if the process has died sub wait_for_line { local $line = <TEMP>; return $line if ($line); waitpid($pid, 1); return undef if (!kill(0, $pid)); sleep(1); return &wait_for_line(); }
# ppp_disconnect(mode, text-mode) # Shuts down the active PPP connection sub ppp_disconnect { local ($ip, $pid, $sect); if ($_[0] == 0) { ($ip, $pid, $sect) = &get_connect_details(); } else { $pid = &get_wvdial_pid(); } if ($pid && &kill_logged('TERM', $pid)) { # Tell the user that the connection is now down if ($ip) { if ($_[1] == 0) { print &text('disc_ok1', "<tt>$ip</tt>", &dialer_name($sect)),"<p>\n"; } elsif ($_[1] == 1) { print &text('disc_ok1', $ip, &dialer_name($sect)),"\n\n"; } } else { if ($_[1] == 0) { print $text{'disc_ok2'},"<p>\n"; } elsif ($_[1] == 1) { print $text{'disc_ok2'},"\n\n"; } }
# Restore the saved DNS config file, if it hasn't been done sleep(3); local @ost = stat($resolv_conf); if (!-l $resolv_conf && $ost[9] < time()-5 && -r $save_resolv_conf) { &system_logged("mv $save_resolv_conf $resolv_conf"); if ($_[1] == 0) { print "$text{'disc_dns'}<p>\n"; } elsif ($_[1] == 1) { print "$text{'disc_dns'}\n\n"; } } &system_logged("rm -f $ppp_resolv_conf"); return 1; } else { # Wasn't even active .. tell the user if ($_[1] == 0) { print "$text{'disc_edown'}<p>\n"; } elsif ($_[1] == 1) { print "$text{'disc_edown'}\n\n"; } return 0; } }
1;
|