# -*- tab-width: 4 -*- ;; Emacs # vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM ############################################################ IDENT(1) # # $Title: dwatch(8) module for VOP_READDIR(9) [or similar] entry $ # $Copyright: 2014-2018 Devin Teske. All rights reserved. $ # ############################################################ DESCRIPTION # # Print directory paths being read by VOP_READDIR(9) [or similar] # NB: All paths are shown even if error prevents their reading. # ############################################################ PROBE : ${PROBE:=vfs:vop:$PROFILE:entry} ############################################################ ACTIONS exec 9<<EOF $PROBE /* probe ID $ID */ {${TRACE:+ printf("<$ID>");} this->vp = (struct vnode *)arg0; this->ncp = this->vp != NULL ? this->vp->v_cache_dst.tqh_first : 0; this->mount = this->vp != NULL ? this->vp->v_mount : NULL; /* ptr to vfs we are in */ this->fi_fs = this->mount != NULL ? stringof(this->mount->mnt_stat.f_fstypename) : ""; this->fi_mount = this->mount != NULL ? stringof(this->mount->mnt_stat.f_mntonname) : ""; this->d_name = args[0]->v_cache_dd != NULL ? stringof(args[0]->v_cache_dd->nc_name) : ""; $( awk -v MAX_DEPTH=$MAX_DEPTH ' { sub(/^\\\t/, "\t") } { buf = buf "\t" $0 "\n" } END { sub(/\n$/, "", buf) $0 = buf sub(/^[[:space:]]*/, "") for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) { gsub(/DEPTH/, DEPTH) print $0 = buf } } ' <<-EOFDEPTH this->nameDEPTH = ""; EOFDEPTH ) } $PROBE /this->vp == 0 || this->fi_fs == 0 || this->fi_fs == "devfs" || this->fi_fs == ""/ /* probe ID $(( $ID + 1 )) */ {${TRACE:+ printf("<$(( $ID + 1 ))>");} this->ncp = 0; } /*********************************************************/ $PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */ {${TRACE:+ printf("<$(( $ID + 2 ))>");} this->dvp = this->ncp->nc_dvp != NULL ? this->ncp->nc_dvp->v_cache_dst.tqh_first : 0; this->name1 = this->dvp != 0 ? ( this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : "" ) : ""; } $PROBE /this->name1 == 0 || this->fi_fs == 0 || this->fi_fs == "devfs" || this->fi_fs == "" || this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */ {${TRACE:+ printf("<$(( $ID + 3 ))>");} this->dvp = 0; } /*********************************************************/ /* * BEGIN Pathname-depth iterators */ $( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH ' { buf = buf $0 "\n" } END { sub(/\n$/, "", buf) for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) { $0 = buf gsub(/DEPTH/, DEPTH) gsub(/IDNUM/, ID++) print } } ' <<EOFDEPTH $PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */ {${TRACE:+ printf("<IDNUM>");} this->dvp = this->dvp->nc_dvp != NULL ? this->dvp->nc_dvp->v_cache_dst.tqh_first : 0; this->nameDEPTH = this->dvp != 0 ? ( this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : "" ) : ""; } EOFDEPTH ) $PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */ {${TRACE:+ printf("<$(( $ID + $MAX_DEPTH + 3 ))>");} this->dvp = this->dvp->nc_dvp != NULL ? this->dvp->nc_dvp->v_cache_dst.tqh_first : 0; this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? ( this->dvp->nc_dvp != NULL ? "..." : "" ) : ""; } /* * END Pathname-depth iterators */ /*********************************************************/ $PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */ {${TRACE:+ printf("<$(( $ID + $MAX_DEPTH + 4 ))>"); } /* * Join full path * NB: Up-to but not including the parent directory (joined below) */ this->path = this->fi_mount; this->path = strjoin(this->path, this->fi_mount != 0 ? ( this->fi_mount == "/" ? "" : "/" ) : "/"); $( awk -v MAX_DEPTH=$MAX_DEPTH ' { sub(/^\\\t/, "\t") } { buf = buf "\t" $0 "\n" } END { sub(/\n$/, "", buf) $0 = buf sub(/^[[:space:]]*/, "") for (N = MAX_DEPTH + 1; N > 0; N--) { gsub(/N/, N) print $0 = buf } } ' <<-EOFDEPTH this->path = strjoin(this->path, \ strjoin(this->nameN, this->nameN != "" ? "/" : "")); EOFDEPTH ) /* Join the parent directory name */ this->path = strjoin(this->path, strjoin(this->name = (this->d_name != 0 ? this->d_name : ""), this->name != "" ? "/" : "")); } EOF ACTIONS=$( cat <&9 ) ID=$(( $ID + $MAX_DEPTH + 5 )) ############################################################ EVENT ACTION EVENT_TEST="this->fi_mount != 0" ############################################################ EVENT DETAILS if [ ! "$CUSTOM_DETAILS" ]; then exec 9<<EOF /* * Print full path */ printf("%s", this->path); EOF EVENT_DETAILS=$( cat <&9 ) fi ################################################################################ # END ################################################################################