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_READDIR(9) [or similar] entry $ 6# $Copyright: 2014-2018 Devin Teske. All rights reserved. $ 7# 8############################################################ DESCRIPTION 9# 10# Print directory paths being read by VOP_READDIR(9) [or similar] 11# NB: All paths are shown even if error prevents their reading. 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->vp = (struct vnode *)arg0; 24 this->ncp = this->vp != NULL ? 25 this->vp->v_cache_dst.tqh_first : 0; 26 this->mount = this->vp != NULL ? 27 this->vp->v_mount : NULL; /* ptr to vfs we are in */ 28 this->fi_fs = this->mount != NULL ? 29 stringof(this->mount->mnt_stat.f_fstypename) : ""; 30 this->fi_mount = this->mount != NULL ? 31 stringof(this->mount->mnt_stat.f_mntonname) : ""; 32 this->d_name = args[0]->v_cache_dd != NULL ? 33 stringof(args[0]->v_cache_dd->nc_name) : ""; 34 35 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 36 { sub(/^\\\t/, "\t") } 37 { buf = buf "\t" $0 "\n" } 38 END { 39 sub(/\n$/, "", buf) 40 $0 = buf 41 sub(/^[[:space:]]*/, "") 42 for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) { 43 gsub(/DEPTH/, DEPTH) 44 print 45 $0 = buf 46 } 47 } 48 ' <<-EOFDEPTH 49 this->nameDEPTH = ""; 50 EOFDEPTH 51 ) 52} 53 54$PROBE /this->vp == 0 || this->fi_fs == 0 || 55 this->fi_fs == "devfs" || this->fi_fs == ""/ /* probe ID $(( 56 $ID + 1 57 )) */ 58{${TRACE:+ 59 printf("<$(( $ID + 1 ))>");} 60 this->ncp = 0; 61} 62 63/*********************************************************/ 64 65$PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */ 66{${TRACE:+ 67 printf("<$(( $ID + 2 ))>");} 68 this->dvp = this->ncp->nc_dvp != NULL ? 69 this->ncp->nc_dvp->v_cache_dst.tqh_first : 0; 70 this->name1 = this->dvp != 0 ? ( 71 this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : "" 72 ) : ""; 73} 74 75$PROBE /this->name1 == 0 || this->fi_fs == 0 || 76 this->fi_fs == "devfs" || this->fi_fs == "" || 77 this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */ 78{${TRACE:+ 79 printf("<$(( $ID + 3 ))>");} 80 this->dvp = 0; 81} 82 83/*********************************************************/ 84 85/* 86 * BEGIN Pathname-depth iterators 87 */ 88 89$( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH ' 90 { buf = buf $0 "\n" } 91 END { 92 sub(/\n$/, "", buf) 93 for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) { 94 $0 = buf 95 gsub(/DEPTH/, DEPTH) 96 gsub(/IDNUM/, ID++) 97 print 98 } 99 } 100' <<EOFDEPTH 101$PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */ 102{${TRACE:+ 103 printf("<IDNUM>");} 104 this->dvp = this->dvp->nc_dvp != NULL ? 105 this->dvp->nc_dvp->v_cache_dst.tqh_first : 0; 106 this->nameDEPTH = this->dvp != 0 ? ( 107 this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : "" 108 ) : ""; 109} 110 111EOFDEPTH 112) 113 114$PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */ 115{${TRACE:+ 116 printf("<$(( $ID + $MAX_DEPTH + 3 ))>");} 117 this->dvp = this->dvp->nc_dvp != NULL ? 118 this->dvp->nc_dvp->v_cache_dst.tqh_first : 0; 119 this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? ( 120 this->dvp->nc_dvp != NULL ? "..." : "" 121 ) : ""; 122} 123 124/* 125 * END Pathname-depth iterators 126 */ 127 128/*********************************************************/ 129 130$PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */ 131{${TRACE:+ 132 printf("<$(( $ID + $MAX_DEPTH + 4 ))>"); 133} 134 /* 135 * Join full path 136 * NB: Up-to but not including the parent directory (joined below) 137 */ 138 this->path = this->fi_mount; 139 this->path = strjoin(this->path, this->fi_mount != 0 ? ( 140 this->fi_mount == "/" ? "" : "/" 141 ) : "/"); 142 $( awk -v MAX_DEPTH=$MAX_DEPTH ' 143 { sub(/^\\\t/, "\t") } 144 { buf = buf "\t" $0 "\n" } 145 END { 146 sub(/\n$/, "", buf) 147 $0 = buf 148 sub(/^[[:space:]]*/, "") 149 for (N = MAX_DEPTH + 1; N > 0; N--) { 150 gsub(/N/, N) 151 print 152 $0 = buf 153 } 154 } 155 ' <<-EOFDEPTH 156 this->path = strjoin(this->path, 157 \ strjoin(this->nameN, this->nameN != "" ? "/" : "")); 158 EOFDEPTH 159 ) 160 161 /* Join the parent directory name */ 162 this->path = strjoin(this->path, strjoin(this->name = 163 (this->d_name != 0 ? this->d_name : ""), 164 this->name != "" ? "/" : "")); 165} 166EOF 167ACTIONS=$( cat <&9 ) 168ID=$(( $ID + $MAX_DEPTH + 5 )) 169 170############################################################ EVENT ACTION 171 172EVENT_TEST="this->fi_mount != 0" 173 174############################################################ EVENT DETAILS 175 176if [ ! "$CUSTOM_DETAILS" ]; then 177exec 9<<EOF 178 /* 179 * Print full path 180 */ 181 printf("%s", this->path); 182EOF 183EVENT_DETAILS=$( cat <&9 ) 184fi 185 186################################################################################ 187# END 188################################################################################ 189