1 #
   2 # CDDL HEADER START
   3 #
   4 # The contents of this file are subject to the terms of the
   5 # Common Development and Distribution License (the "License").
   6 # You may not use this file except in compliance with the License.
   7 #
   8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9 # or http://www.opensolaris.org/os/licensing.
  10 # See the License for the specific language governing permissions
  11 # and limitations under the License.
  12 #
  13 # When distributing Covered Code, include this CDDL HEADER in each
  14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15 # If applicable, add the following below this CDDL HEADER, with the
  16 # fields enclosed by brackets "[]" replaced with your own identifying
  17 # information: Portions Copyright [yyyy] [name of copyright owner]
  18 #
  19 # CDDL HEADER END
  20 #
  21 
  22 #
  23 # Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24 # Use is subject to license terms.
  25 #
  26 
  27 #
  28 # Collection of tcl procedures
  29 #
  30 
  31 #---------------------------------------------------------
  32 # Extract the attributes
  33 #  Usage: extract_attr attrs name
  34 #       It takes two arguments, the attributes list
  35 #       and the attribute name to be extracted.
  36 #       It then returns its attributes.
  37 #
  38 proc extract_attr {attrs name} {
  39 
  40     foreach entry $attrs {
  41         if {$name == [lindex $entry 0]} {
  42             return [lindex $entry 1]
  43         }
  44     }
  45 }
  46 
  47 #---------------------------------------------------------
  48 # Get the filehandle from the list components of a path
  49 #  Usage: get_fh path
  50 #       path: the "path" in "components" format.
  51 #             the path must start from rootfh.
  52 #  Return: 
  53 #       the filehandle of the last components of "path";
  54 #       or empty string if operation failed during the process.
  55 #
  56 proc get_fh { path } {
  57     set result [compound {Putrootfh; foreach c $path {Lookup $c}; Getfh}]
  58     return [lindex [lindex $result end] 2]
  59 }
  60 
  61 
  62 #---------------------------------------------------------
  63 # Nicely print the time
  64 #  Usage: nicetime seconds
  65 #       It takes the seconds as the argument and 
  66 #       nicely print the associated readable date/time
  67 #
  68 proc nicetime { second } {
  69     return [clock format $second]
  70 }
  71 
  72 
  73 #---------------------------------------------------------
  74 # print attributes
  75 #  Usage: prn_attrs attribute_list
  76 #       Given the attribute list {{name val} ...}, 
  77 #       print out each name and its value
  78 #
  79 proc prn_attrs { alist } {
  80   foreach attr $alist {
  81     set name [ lindex $attr 0]
  82     set val  [ lindex $attr 1]
  83 
  84     switch $name {
  85         supported_attrs { puts "\tSupported attrs  = $val" }
  86         type            { switch $val {
  87                           reg { puts "\tFile type        = file"}
  88                           lnk { puts "\tFile type        = symlink"}
  89                           default { puts "\tFile type        = $val" }
  90                           }
  91                         }
  92         fh_expire_type  { puts "\tFH expire type   = $val" }
  93         change          { puts "\tChange           = $val" }
  94         size            { puts "\tFile size        = $val" }
  95         link_support    { puts "\tLink support     = $val" }
  96         symlink_support { puts "\tSymlink support  = $val" }
  97         named_attr      { puts "\tNamed attr       = $val" }
  98         fsid            { puts "\tFile system ID   = $val" }
  99         unique_handles  { puts "\tUnique handles   = $val" }
 100         lease_time      { puts "\tLease time       = $val" }
 101         rdattr_error    { puts "\tRdattr error     = $val" }
 102         acl             { puts "\tACL              = $val" }
 103         aclsupport      { puts "\tACL support      = $val" }
 104         archive         { puts "\tArchive          = $val" }
 105         cansettime      { puts "\tCan set time     = $val" }
 106         case_insensitive {puts "\tCase insensitive = $val" }
 107         case_preserving { puts "\tCase preserving  = $val" }
 108         chown_restricted {puts "\tChown restricted = $val" }
 109         filehandle      { puts "\tFile handle      = $val" }
 110         fileid          { puts "\tFile ID          = $val" }
 111         files_avail     { puts "\tFiles available  = $val" }
 112         files_free      { puts "\tFiles free       = $val" }
 113         files_total     { puts "\tFiles total      = $val" }
 114         fs_locations    { puts "\tFS locations     = $val" }
 115         hidden          { puts "\tHidden           = $val" }
 116         homogeneous     { puts "\tHomogeneous      = $val" }
 117         maxfilesize     { puts "\tMax file size    = $val" }
 118         maxlink         { puts "\tMax link         = $val" }
 119         maxname         { puts "\tMax name         = $val" }
 120         maxread         { puts "\tMax read         = $val" }
 121         maxwrite        { puts "\tMax write        = $val" }
 122         mimetype        { puts "\tMime type        = $val" }
 123         mode            { puts "\tMode bits        = $val" }
 124         no_trunc        { puts "\tNo trunc         = $val" }
 125         numlinks        { puts "\tNumber of links  = $val" }
 126         owner           { puts "\tOwner            = $val" }
 127         owner_group     { puts "\tGroup            = $val" }
 128         quota_avail_hard { puts "\tHard quota       = $val" }
 129         quota_avail_soft { puts "\tSoft quota       = $val" }
 130         quota_used      { puts "\tQuota used       = $val" }
 131         rawdev          { puts "\tRaw device       = $val" }
 132         space_avail     { puts "\tSpace available  = $val" }
 133         space_free      { puts "\tSpace free       = $val" }
 134         space_total     { puts "\tSpace total      = $val" }
 135         space_used      { puts "\tSpace used       = $val" }
 136         system          { puts "\tSystem           = $val" }
 137         time_access     { 
 138                           set nt [nicetime [lindex $val 0] ]
 139                           puts "\tAccess time      = $val - $nt" 
 140                         }
 141         time_access_set { puts "\tTime access set  = $val" }
 142         time_backup     { 
 143                           set nt [nicetime [lindex $val 0] ]
 144                           puts "\tBackup time      = $val - $nt" 
 145                         }
 146         time_create     {
 147                           set nt [nicetime [lindex $val 0] ]
 148                           puts "\tCreated time      = $val - $nt" 
 149                         }
 150         time_delta      { puts "\tTime delta       = $val" }
 151         time_metadata   {
 152                           set nt [nicetime [lindex $val 0] ]
 153                           puts "\tTime metadata    = $val - $nt" 
 154                         }
 155         time_modify     {
 156                           set nt [nicetime [lindex $val 0] ]
 157                           puts "\tModified time    = $val - $nt"
 158                         }
 159         time_modify_set { puts "\tTime modify set  = $val" }
 160         default         { puts "\tUnknown attributes" }
 161     }
 162   }
 163 }
 164 
 165 
 166 #---------------------------------------------------------
 167 # print directory list
 168 #  Usage: prn_dirlist directory_list_w/attributes
 169 #       Given the directory list { verf entry_name attrs ...}, 
 170 #       e.g. results returned from Readdir op,
 171 #       print out each name and its returned values
 172 #
 173 proc prn_dirlist { dirlist } {
 174 
 175     foreach entry $dirlist {
 176         set name  [lindex $entry 1]
 177         puts "  $name"
 178         prn_attrs [lindex $entry 2]
 179     }
 180 }
 181 
 182 
 183 #---------------------------------------------------------
 184 # Convert pathname to components
 185 #  Usage: path2comp path delm
 186 #       It takes the path argument, and convert it to
 187 #       the format of comonents based on the 'delm' delimiter.
 188 #
 189 proc path2comp { path delm } {
 190     set comps [split $path $delm]
 191     if { [lindex $comps 0] == "" } {
 192             set comps [lrange $comps 1 [expr [llength $comps] - 1] ]
 193     }
 194     return $comps
 195 }
 196 
 197 
 198 #---------------------------------------------------------
 199 # write ascii to a file
 200 #  Usage: write_ascii filehandle stateid data
 201 #       It takes the filehandle of the file, the stateid,
 202 #       and the ascii data to be written, writes the data
 203 #       to the file starting from offset 0.  All data will
 204 #       be FILE_SYNC.
 205 #
 206 proc write_ascii { fh sid data } {
 207 
 208     set wres [compound {Putfh $fh; Write $sid 0 f a $data}]
 209     if { $status != "OK" } {
 210         puts "write_ascii Failed."
 211         puts $wres
 212     }
 213     set winfo [ split [lindex [lindex $wres 1] 2] = ]
 214     set cnt [ lindex [lindex $winfo 1] 0]
 215     set cmt [ lindex [lindex $winfo 2] 0]
 216     puts "Wrote $cmt of $cnt bytes of data."
 217 }
 218 
 219 
 220 #---------------------------------------------------------
 221 # Read a remote file using NFSv4 when given the path components
 222 #  Usage: readv4_path path stateid offset count
 223 #       Given the path argument and its stateid, it reads
 224 #       the file with the byte "count", starting from the 
 225 #       given offset; then print out the data being read.
 226 #
 227 proc readv4_path { fpath stateid offset count } {
 228 
 229     set pfh [ get_fh $fpath ]
 230     set rres [compound {Putfh $pfh; Read $stateid $offset $count}]
 231     if { $status != "OK" } {
 232         puts "readv4_path Failed."
 233         puts $rres
 234     }
 235     return [lindex [lindex [lindex $rres 1] 2] 2]
 236 }
 237 
 238 
 239 #---------------------------------------------------------
 240 # Read a remote file using NFSv4 when given the path filehandle
 241 #  Usage: readv4_fh pfh stateid offset count
 242 #       Given the path filehandle and its stateid, it reads
 243 #       the file with the byte "count", starting from the 
 244 #       given offset; then print out the data being read.
 245 #
 246 proc readv4_fh { pfh stateid offset count } {
 247 
 248     set rres [compound {Putfh $pfh; Read $stateid $offset $count}]
 249     if { $status != "OK" } {
 250         puts "readv4_fh Failed."
 251         puts $rres
 252     }
 253     return [lindex [lindex [lindex $rres 1] 2] 2]
 254 }
 255 
 256 
 257 # End of tclprocs