1 #!nfsh
   2 #
   3 # CDDL HEADER START
   4 #
   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 
  23 #
  24 # Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25 # Use is subject to license terms.
  26 #
  27 
  28 #
  29 # Do a file tree walk.
  30 #
  31 # This script accepts a hostname and a pathname to
  32 # a directory.  It then recursively descends the
  33 # directory hierarchy listing all the files and
  34 # directory. Each directory level is indented.
  35 
  36 
  37 #  Given an attribute name, extract its 
  38 #  value from an attribute list that looks
  39 #  like this:
  40 #  { {type dir} {size 1664} {filehandle 7C842044} }
  41 
  42 # NOTE (03/01/2000):
  43 #  this script does not work if path exported by
  44 #  server is more than one component.
  45 #
  46 
  47 proc extract_attr {attrs name} {
  48 
  49     foreach entry $attrs {
  50         if {$name == [lindex $entry 0]} {
  51             return [lindex $entry 1]
  52         }
  53     }
  54 }
  55 
  56 
  57 # Do a path lookup and return a filehandle
  58 
  59 proc get_handle { path } {
  60     set result [compound {Putrootfh; foreach c $path {Lookup $c}; Getfh}]
  61     return [lindex [lindex $result end] 2]
  62 }
  63 
  64 # This procedure is invoked recursively to list
  65 # The entries in a directory hierarchy. The first
  66 # argument is a filehandle.  The second is the
  67 # recursion depth which is used to control indenting.
  68 
  69 proc dolist { fh depth} {
  70 
  71     set cookie 0
  72     set eof false
  73     
  74     while { $eof != "true" } {
  75     
  76         set result [compound {
  77             Putfh $fh
  78             Readdir $cookie 0 1024 1024 {type filehandle}
  79         }]
  80     
  81         if {$status != "OK"} {
  82             puts $status
  83             exit
  84         }
  85     
  86     
  87         # Get the readdir result from the compound result
  88     
  89         set readdirres [ lindex $result 1 ]
  90     
  91     
  92         # Get the eof flag from the directory result
  93     
  94         set eof [ lindex $readdirres 4 ]
  95     
  96     
  97         # Now extract the directory listing itself
  98     
  99         set dirlist [ lindex $readdirres 3 ]
 100 
 101 
 102         # Examine each entry in the directory
 103 
 104         foreach entry $dirlist {
 105 
 106             set cookie [ lindex $entry 0 ]
 107             set name   [ lindex $entry 1 ]
 108             set attrs  [ lindex $entry 2 ]
 109             set type   [ extract_attr $attrs "type" ]
 110             set fh2    [ extract_attr $attrs "filehandle" ]
 111 
 112 
 113             # Indent the line
 114 
 115             for { set i 0 } { $i < $depth } { incr i } {
 116                 puts -nonewline "   "
 117             }
 118 
 119 
 120             # If the entry is a directory, invoke the
 121             # procedure recursively. Otherwise, just
 122             # list the entry name.
 123 
 124             if {$type == "dir"} {
 125                 puts "$name/"
 126                 dolist $fh2 [expr $depth+1]
 127 
 128             } else {
 129                 puts "$name"
 130             }
 131         }
 132     }
 133 
 134     return
 135 }
 136 
 137 #####################
 138 
 139 if { $argc != 2 } {
 140     puts "Usage: $argv0 <hostname> <pathname>"
 141     exit
 142 }
 143 
 144 set host [ lindex $argv 0 ]
 145 set path [ split [ lindex $argv 1 ] / ]
 146 if { [lindex $path 0] == "" } {
 147         set path [lrange $path 1 [expr [llength $path] - 1]]
 148 }
 149 
 150 # The Java server temporarily runs
 151 # on port 999 so as not to interfere
 152 # with the native NFS server.
 153 
 154 #connect -p 9999 -t udp $host
 155 connect $host
 156 
 157 dolist [get_handle $path] 0