1# -*- tab-width: 4 -*- ;; Emacs 2# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM 3############################################################ IDENT(1) 4# 5# $Title: dwatch(8) module for VOP_RENAME(9) [or similar] entry $ 6# $Copyright: 2014-2018 Devin Teske. All rights reserved. $ 7# 8############################################################ DESCRIPTION 9# 10# Print filesystem paths being renamed by VOP_RENAME(9) [or similar] 11# NB: All paths are shown even if error prevents their rename. 12# 13############################################################ PROBE 14 15: ${PROBE:=vfs:vop:$PROFILE:entry} 16 17############################################################ ACTIONS 18 19exec 9<<EOF 20$PROBE /* probe ID $ID */ 21{${TRACE:+ 22 printf("<$ID>");} 23 this->fvp = args[1] ? args[1]->a_fdvp : NULL; 24 this->fncp = this->fvp != NULL ? 25 this->fvp->v_cache_dst.tqh_first : 0; 26 this->ffi_name = args[1] ? ( 27 args[1]->a_fcnp != NULL ? 28 stringof(args[1]->a_fcnp->cn_nameptr) : "" 29 ) : ""; 30 this->fmount = this->fvp != NULL ? 31 this->fvp->v_mount : NULL; /* ptr to vfs we are in */ 32 this->ffi_fs = this->fmount != NULL ? 33 stringof(this->fmount->mnt_stat.f_fstypename) : ""; 34 this->ffi_mount = this->fmount != NULL ? 35 stringof(this->fmount->mnt_stat.f_mntonname) : ""; 36 this->fd_name = args[0]->v_cache_dd != NULL ? 37 stringof(args[0]->v_cache_dd->nc_name) : ""; 38 39 this->tvp = args[1] ? args[1]->a_tdvp : NULL; 40 this->tncp = this->tvp != NULL ? 41 this->tvp->v_cache_dst.tqh_first : 0; 42 this->tfi_name = args[1] ? ( 43 args[1]->a_tcnp != NULL ? 44 stringof(args[1]->a_tcnp->cn_nameptr) : "" 45 ) : ""; 46 this->tmount = this->tvp != NULL ? 47 this->tvp->v_mount : NULL; /* ptr to vfs we are in */ 48 this->tfi_fs = this->tmount != NULL ? 49 stringof(this->tmount->mnt_stat.f_fstypename) : ""; 50 this->tfi_mount = this->tmount != NULL ? 51 stringof(this->tmount->mnt_stat.f_mntonname) : ""; 52 this->td_name = this->tvp != NULL ? ( 53 this->tvp->v_cache_dd != NULL ? 54 stringof(this->tvp->v_cache_dd->nc_name) : "" 55 ) : ""; 56 57 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 58 { sub(/^\\\t/, "\t") } 59 { buf = buf "\t" $0 "\n" } 60 END { 61 sub(/\n$/, "", buf) 62 $0 = buf 63 sub(/^[[:space:]]*/, "") 64 for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) { 65 gsub(/DEPTH/, DEPTH) 66 print 67 $0 = buf 68 } 69 } 70 ' <<-EOFDEPTH 71 this->fnameDEPTH = this->tnameDEPTH = ""; 72 EOFDEPTH 73 ) 74} 75 76$PROBE /this->fvp == 0 || this->ffi_fs == 0 || 77 this->ffi_fs == "devfs" || this->ffi_fs == "" || 78 this->ffi_name == ""/ /* probe ID $(( $ID + 1 )) */ 79{${TRACE:+ 80 printf("<$(( $ID + 1 ))>");} 81 this->fncp = 0; 82} 83 84$PROBE /this->tvp == 0 || this->tfi_fs == 0 || 85 this->tfi_fs == "devfs" || this->tfi_fs == "" || 86 this->tfi_name == ""/ /* probe ID $(( $ID + 2 )) */ 87{${TRACE:+ 88 printf("<$(( $ID + 2 ))>");} 89 this->tncp = 0; 90} 91 92/*********************************************************/ 93 94$PROBE /this->fncp/ /* probe ID $(( $ID + 3 )) (depth 1) */ 95{${TRACE:+ 96 printf("<$(( $ID + 3 ))>");} 97 this->fdvp = this->fncp->nc_dvp != NULL ? 98 this->fncp->nc_dvp->v_cache_dst.tqh_first : 0; 99 this->fname1 = this->fdvp != 0 ? ( 100 this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : "" 101 ) : ""; 102} 103 104$PROBE /this->tncp/ /* probe ID $(( $ID + 4 )) (depth 1) */ 105{${TRACE:+ 106 printf("<$(( $ID + 4 ))>");} 107 this->tdvp = this->tncp->nc_dvp != NULL ? 108 this->tncp->nc_dvp->v_cache_dst.tqh_first : 0; 109 this->tname1 = this->tdvp != 0 ? ( 110 this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : "" 111 ) : ""; 112} 113 114$PROBE /this->fname1 == 0 || this->ffi_fs == 0 || 115 this->ffi_fs == "devfs" || this->ffi_fs == "" || 116 this->fname1 == "/" || this->fname1 == ""/ /* probe ID $(( 117 $ID + 5 118 )) */ 119{${TRACE:+ 120 printf("<$(( $ID + 5 ))>");} 121 this->fdvp = 0; 122} 123 124$PROBE /this->tname1 == 0 || this->tfi_fs == 0 || 125 this->tfi_fs == "devfs" || this->tfi_fs == "" || 126 this->tname1 == "/" || this->tname1 == ""/ /* probe ID $(( 127 $ID + 6 128 )) */ 129{${TRACE:+ 130 printf("<$(( $ID + 6 ))>");} 131 this->tdvp = 0; 132} 133 134/*********************************************************/ 135 136/* 137 * BEGIN Pathname-depth iterators 138 */ 139 140$( awk -v ID=$(( $ID + 7 )) -v MAX_DEPTH=$MAX_DEPTH ' 141 { buf = buf $0 "\n" } 142 END { 143 sub(/\n$/, "", buf) 144 for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) { 145 $0 = buf 146 gsub(/DEPTH/, DEPTH) 147 gsub(/IDNUM1/, ID) 148 gsub(/IDNUM2/, ID + 1) 149 print 150 ID = ID + 2 151 } 152 } 153' <<EOFDEPTH 154$PROBE /this->fdvp/ /* probe ID IDNUM1 (depth DEPTH) */ 155{${TRACE:+ 156 printf("<IDNUM1>");} 157 this->fdvp = this->fdvp->nc_dvp != NULL ? 158 this->fdvp->nc_dvp->v_cache_dst.tqh_first : 0; 159 this->fnameDEPTH = this->fdvp != 0 ? ( 160 this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : "" 161 ) : ""; 162} 163$PROBE /this->tdvp/ /* probe ID IDNUM2 (depth DEPTH) */ 164{${TRACE:+ 165 printf("<IDNUM2>");} 166 this->tdvp = this->tdvp->nc_dvp != NULL ? 167 this->tdvp->nc_dvp->v_cache_dst.tqh_first : 0; 168 this->tnameDEPTH = this->tdvp != 0 ? ( 169 this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : "" 170 ) : ""; 171} 172 173EOFDEPTH 174) 175 176$PROBE /this->fdvp/ /* probe ID $(( $ID + $MAX_DEPTH * 2 + 5 )) */ 177{${TRACE:+ 178 printf("<$(( $ID + $MAX_DEPTH * 2 + 5 ))>");} 179 this->fdvp = this->fdvp->nc_dvp != NULL ? 180 this->fdvp->nc_dvp->v_cache_dst.tqh_first : 0; 181 this->fname$(( $MAX_DEPTH + 1 )) = this->fdvp != 0 ? ( 182 this->fdvp->nc_dvp != NULL ? "..." : "" 183 ) : ""; 184} 185$PROBE /this->tdvp/ /* probe ID $(( $ID + $MAX_DEPTH * 2 + 6 )) */ 186{${TRACE:+ 187 printf("<$(( $ID + $MAX_DEPTH * 2 + 6 ))>");} 188 this->tdvp = this->tdvp->nc_dvp != NULL ? 189 this->tdvp->nc_dvp->v_cache_dst.tqh_first : 0; 190 this->tname$(( $MAX_DEPTH + 1 )) = this->tdvp != 0 ? ( 191 this->tdvp->nc_dvp != NULL ? "..." : "" 192 ) : ""; 193} 194 195/* 196 * END Pathname-depth iterators 197 */ 198 199/*********************************************************/ 200 201$PROBE /this->ffi_mount != 0 && this->tfi_mount != 0/ /* probe ID $(( 202 $ID + $MAX_DEPTH * 2 + 7 203)) */ 204{${TRACE:+ 205 printf("<$(( $ID + $MAX_DEPTH * 2 + 7 ))>"); 206} 207 /* 208 * Join 'from' full path 209 * NB: Up-to but not including the parent directory (joined below) 210 */ 211 this->fpath = this->ffi_mount; 212 this->fpath = strjoin(this->fpath, this->ffi_mount != 0 ? ( 213 this->ffi_mount == "/" ? "" : "/" 214 ) : "/"); 215 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 216 { sub(/^\\\t/, "\t") } 217 { buf = buf "\t" $0 "\n" } 218 END { 219 sub(/\n$/, "", buf) 220 $0 = buf 221 sub(/^[[:space:]]*/, "") 222 for (N = MAX_DEPTH + 1; N > 0; N--) { 223 gsub(/N/, N) 224 print 225 $0 = buf 226 } 227 } 228 ' <<-EOFDEPTH 229 this->fpath = strjoin(this->fpath, 230 \ strjoin(this->fnameN, this->fnameN != "" ? "/" : "")); 231 EOFDEPTH 232 ) 233 234 /* Join the 'from' parent directory name */ 235 this->fpath = strjoin(this->fpath, strjoin(this->fname = 236 (this->fd_name != 0 ? this->fd_name : ""), 237 this->fname != "" ? "/" : "")); 238 239 /* Join the 'from' entry name */ 240 this->fpath = strjoin(this->fpath, 241 this->fname = (this->ffi_name != 0 ? this->ffi_name : "")); 242 243 /* 244 * Join 'to' full path 245 * NB: Up-to but not including the parent directory (joined below) 246 */ 247 this->tpath = this->tfi_mount; 248 this->tpath = strjoin(this->tpath, this->tfi_mount != 0 ? ( 249 this->tfi_mount == "/" ? "" : "/" 250 ) : "/"); 251 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 252 { sub(/^\\\t/, "\t") } 253 { buf = buf "\t" $0 "\n" } 254 END { 255 sub(/\n$/, "", buf) 256 $0 = buf 257 sub(/^[[:space:]]*/, "") 258 for (N = MAX_DEPTH + 1; N > 0; N--) { 259 gsub(/N/, N) 260 print 261 $0 = buf 262 } 263 } 264 ' <<-EOFDEPTH 265 this->tpath = strjoin(this->tpath, 266 \ strjoin(this->tnameN, this->tnameN != "" ? "/" : "")); 267 EOFDEPTH 268 ) 269 270 /* Join the 'to' parent directory name */ 271 this->tpath = strjoin(this->tpath, strjoin(this->tname = 272 (this->td_name != 0 ? this->td_name : ""), 273 this->tname != "" ? "/" : "")); 274 275 /* Join the 'to' entry name */ 276 this->tpath = strjoin(this->tpath, 277 this->tname = (this->tfi_name != 0 ? this->tfi_name : "")); 278} 279EOF 280ACTIONS=$( cat <&9 ) 281ID=$(( $ID + $MAX_DEPTH * 2 + 8 )) 282 283############################################################ EVENT ACTION 284 285EVENT_TEST="this->ffi_mount != 0 && this->tfi_mount != 0" 286 287############################################################ EVENT DETAILS 288 289if [ ! "$CUSTOM_DETAILS" ]; then 290exec 9<<EOF 291 /* 292 * Print 'from' and 'to' full paths 293 */ 294 printf("%s -> %s", this->fpath, this->tpath); 295EOF 296EVENT_DETAILS=$( cat <&9 ) 297fi 298 299################################################################################ 300# END 301################################################################################ 302