#!/usr/bin/perl # Workgroup list: file:/$LIB/smb.cgi # Server list: file:/$LIB/smb.cgi?workgroup # Sahre list: file:/$LIB/smb.cgi?//server # Directory: file:/$LIB/smb.cgi?//server/share # file:/$LIB/smb.cgi?//server/share/dir... # Get file: file:/$LIB/smb.cgi?//server/share/dir.../file # # ----- ~/.w3m/smb ----- # workgroup = # [ username = ] # [ password = ] # [ password_file = ] # ---------------------- # --- --- # # ----------------------- # default: # = $USER # = $PASSWD (Don't use!) # = $PASSWD_FILE $DEBUG = 1; $MIME_TYPE = "~/.mime.types"; $AUTH_FILE = "~/.w3m/smb"; $MIME_TYPE =~ s@^~/@$ENV{"HOME"}/@; $AUTH_FILE =~ s@^~/@$ENV{"HOME"}/@; $WORKGROUP = "-"; $USER = $ENV{"USER"}; $PASSWD = $ENV{"PASSWD"}; $PASSWD_FILE = $ENV{"PASSWD_FILE"}; &load_auth_file($AUTH_FILE); $NMBLOOKUP = "nmblookup"; $SMBCLIENT = "smbclient"; @NMBLOOKUP_OPT = ("-T"); @SMBCLIENT_OPT = ("-N"); $USE_OPT_A = defined($PASSWD) && (-f $AUTH_FILE) && &check_opt_a(); if ($USE_OPT_A) { push(@SMBCLIENT_OPT, "-A", $AUTH_FILE); } elsif (-f $PASSWD_FILE) { $USE_PASSWD_FILE = 1; } elsif (defined($PASSWD)) { $USE_PASSWD_FD = 1; $PASSWD_FD = 0; } if (defined($PASSWD)) { $passwd = "*" x 8; } $DEBUG && print <) { $DEBUG && print "DEBUG: $_"; /^\s/ && last; } close($F); if (s/\s+([A-Z]*) {1,8}\d+ (\w{3} ){2}[ \d]\d \d\d:\d\d:\d\d \d{4}\s*$// && $1 !~ /D/) { &get_file($service, $file); exit; } get_list: $_ = "$file/*"; s@/+@\\@g; @cmd = ($SMBCLIENT, $service, @SMBCLIENT_OPT, "-c", "ls \"$_\""); $F = &open_pipe(1, @cmd); while (<$F>) { /^\s*$/ && last; $DEBUG && print "DEBUG: $_"; /^cd\s+/ && last; /^\S/ && next; s/\r?\n//; push(@files, $_); } close($F); $qservice = &html_quote($service); $service = &file_encode($service); $qfile = &html_quote($file); $file = &file_encode($file); print "Content-Type: text/html\n\n"; print "$qservice$qfile\n"; print "$qservice$qfile\n"; print "
\n";
	for (sort @files) {
		s/\s+([A-Z]*) {1,8}\d+  (\w{3} ){2}[ \d]\d \d\d:\d\d:\d\d \d{4}\s*$// || next;
		$c = $&;
		s/^  //;
		$_ eq "." && next;
		print ""
			. &html_quote($_) . ""
			. &html_quote($c) . "\n";
	}
	print "
\n"; } sub get_file { local($service, $file) = @_; local($encoding, $type); local($_, @cmd); $_ = $file; s@/@\\@g; @cmd = ($SMBCLIENT, $service, @SMBCLIENT_OPT, "-E", "-c", "more \"$_\""); $DEBUG && print "DEBUG: @cmd\n"; ($encoding, $type) = &guess_type($file); $file =~ s@^.*/@@; $| = 1; print "Content-Encoding: $encoding\n" if $encoding; print "Content-Type: $type; name=\"$file\"\n\n"; $ENV{"PAGER"} = $PAGER if $PAGER; &exec_cmd(1, @cmd); } sub share_list { local($server) = @_; local(@share); local($qserver, $_, $d, @c); @share = &get_list(1, $server, "Share"); $qserver = &html_quote($server); $server = &file_encode($server); print "Content-Type: text/html\n\n"; print "Share list: $qserver\n"; print "\n"; print "
$qserver"; for (sort @share) { ($_, $d, @c) = split(" "); if ($d eq 'Disk') { print "
+ " . &html_quote($_) . ""; } else { print "
+ " . &html_quote($_); } print "" . &html_quote($d) . "" . &html_quote("@c") . "\n"; } print "
\n"; } sub server_list { local($group) = @_; local($master, @server); local($_, @c); $master = &get_master($group); @server = &get_list(0, $master, "Server"); $group = &html_quote($group); print "Content-Type: text/html\n\n"; print "Server list: $group\n"; print "\n"; print "
$group\n"; for (sort @server) { ($_, @c) = split(" "); print "
+ " . &html_quote($_) . "" . &html_quote("@c") . "\n"; } print "
\n"; } sub group_list { local($master, @group); local($_, @c); $master = &get_master($WORKGROUP || "-"); @group = &get_list(0, $master, "Workgroup"); print "Content-Type: text/html\n\n"; print "Workgroup list\n"; print "\n"; for (sort @group) { ($_, @c) = split(" "); print "
" . &html_quote($_) . "" . &html_quote("@c") . "\n"; } print "
\n"; } sub check_opt_a { local($_, $F, @cmd); @cmd = ($SMBCLIENT, "-h"); $F = &open_pipe(0, @cmd); while (<$F>) { if (/^\s*-A\s/) { $DEBUG && print "DEBUG: $_"; close($F); return 1; } } close($F); return 0; } sub get_master { local($group) = @_; local($_, $F, @cmd); @cmd = ($NMBLOOKUP, "-M", @NMBLOOKUP_OPT, $group); $F = &open_pipe(0, @cmd); $_ = <$F>; $_ = <$F>; close($F); ($_) = split(/[,\s]/); s/\.*$//; return $_; } sub get_list { local($passwd, $server, $header) = @_; local(@list) = (); local($_, @cmd, $F); @cmd = ($SMBCLIENT, @SMBCLIENT_OPT, "-L", $server); $F = &open_pipe($passwd, @cmd); while (<$F>) { if (/^\s*$header/) { $DEBUG && print "DEBUG: $_"; last; } } while (<$F>) { /^\s*$/ && last; $DEBUG && print "DEBUG: $_"; /^\S/ && last; /^\s*-/ && next; push(@list, $_); } close($F); return @list; } sub open_pipe { local($passwd, @cmd) = @_; local($F) = $FILE++; $DEBUG && print "DEBUG: @cmd\n"; open($F, "-|") || &exec_cmd($passwd, @cmd); return $F; } sub exec_cmd { local($passwd, @cmd) = @_; $ENV{"LC_ALL"} = "C"; $ENV{"USER"} = $USER; if ($passwd && !$USE_OPT_A) { if ($USE_PASSWD_FILE) { $ENV{"PASSWD_FILE"} = $PASSWD_FILE; } elsif ($USE_PASSWD_FD) { $ENV{"PASSWD_FD"} = $PASSWD_FD; if (open(W, "|-")) { print W $PASSWD; close(W); exit; } } } open(STDERR, ">/dev/null"); exec @cmd; exit 1; } sub print_form { local($_) = @_; local($q) = &html_quote($_); $_ = &file_encode($_); print <$q
Workgroup User Password
EOF } sub load_auth_file { local($_) = @_; if ($USER =~ s/%(.*)$//) { $PASSWD = $1 unless $PASSWD; } open(F, $_) || return; while () { s/\s+$//; if (s/^workgroup\s*=\s*//i) { $WORKGROUP = $_; } elsif (s/^user(name)?\s*=\s*//i) { $USER = $_; } elsif (s/^passw(or)?d\s*=\s*//i) { $PASSWD = $_; } elsif (s/^passw(or)?d_file\s*=\s*//i) { $PASSWD_FILE = $_; } } close(F); } sub load_mime_type { local($_) = @_; local(%mime) = (); local($type, @suffix); open(F, $_) || return (); while() { /^#/ && next; chop; (($type, @suffix) = split(" ")) >= 2 || next; for (@suffix) { $mime{$_} = $type; } } close(F); return %mime; } sub guess_type { local($_) = @_; local(%mime) = &load_mime_type($MIME_TYPE); local($encoding) = undef; if (s/\.gz$//i) { $encoding = "gzip"; } elsif (s/\.Z$//i) { $encoding = "compress"; } elsif (s/\.bz2?$//i) { $encoding = "bzip2"; } /\.(\w+)$/; $_ = $1; tr/A-Z/a-z/; return ($encoding, $mime{$_} || "text/plain"); } sub cleanup { local($_) = @_; $_ .= "/"; s@//+@/@g; s@/\./@/@g; while(m@/\.\./@) { s@^/(\.\./)+@/@; s@/[^/]+/\.\./@/@; } s@(.)/$@$1@; return $_; } sub file_encode { local($_) = @_; s/[\000-\040\+:#?&%<>"\177-\377]/sprintf('%%%02X', unpack('C', $&))/eg; return $_; } sub file_decode { local($_) = @_; s/\+/ /g; s/%([\da-f][\da-f])/pack('C', hex($1))/egi; s@[\r\n\0\\"]@@g; return $_; } sub html_quote { local($_) = @_; local(%QUOTE) = ( '<', '<', '>', '>', '&', '&', '"', '"', ); s/[<>&"]/$QUOTE{$&}/g; return $_; }