xref: /freebsd/cddl/usr.sbin/dwatch/libexec/vop_symlink (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
15bf5ca77SDevin Teske# -*- tab-width: 4 -*- ;; Emacs
25bf5ca77SDevin Teske# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
35bf5ca77SDevin Teske############################################################ IDENT(1)
45bf5ca77SDevin Teske#
55bf5ca77SDevin Teske# $Title: dwatch(8) module for VOP_SYMLINK(9) [or similar] entry $
65bf5ca77SDevin Teske# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
75bf5ca77SDevin Teske#
85bf5ca77SDevin Teske############################################################ DESCRIPTION
95bf5ca77SDevin Teske#
105bf5ca77SDevin Teske# Print symlink paths being created by VOP_SYMLINK(9) [or similar]
115bf5ca77SDevin Teske# NB: All paths are shown even if error prevents their creation.
125bf5ca77SDevin Teske#
135bf5ca77SDevin Teske############################################################ PROBE
145bf5ca77SDevin Teske
155bf5ca77SDevin Teske: ${PROBE:=vfs:vop:$PROFILE:entry}
165bf5ca77SDevin Teske
175bf5ca77SDevin Teske############################################################ ACTIONS
185bf5ca77SDevin Teske
195bf5ca77SDevin Teskeexec 9<<EOF
205bf5ca77SDevin Teske$PROBE /* probe ID $ID */
215bf5ca77SDevin Teske{${TRACE:+
225bf5ca77SDevin Teske	printf("<$ID>");}
235bf5ca77SDevin Teske	this->vp = (struct vnode *)arg0;
245bf5ca77SDevin Teske	this->ncp = this->vp != NULL ?
255bf5ca77SDevin Teske		this->vp->v_cache_dst.tqh_first : 0;
265bf5ca77SDevin Teske	this->target = args[1] ? args[1]->a_target : "";
275bf5ca77SDevin Teske	this->fi_name = args[1] ? (
285bf5ca77SDevin Teske		args[1]->a_cnp != NULL ?
295bf5ca77SDevin Teske			stringof(args[1]->a_cnp->cn_nameptr) : ""
305bf5ca77SDevin Teske	) : "";
315bf5ca77SDevin Teske	this->mount = this->vp != NULL ?
325bf5ca77SDevin Teske		this->vp->v_mount : NULL; /* ptr to vfs we are in */
335bf5ca77SDevin Teske	this->fi_fs = this->mount != NULL ?
345bf5ca77SDevin Teske		stringof(this->mount->mnt_stat.f_fstypename) : "";
355bf5ca77SDevin Teske	this->fi_mount = this->mount != NULL ?
365bf5ca77SDevin Teske		stringof(this->mount->mnt_stat.f_mntonname) : "";
375bf5ca77SDevin Teske	this->d_name = args[0]->v_cache_dd != NULL ?
385bf5ca77SDevin Teske		stringof(args[0]->v_cache_dd->nc_name) : "";
395bf5ca77SDevin Teske
405bf5ca77SDevin Teske	$( awk -v MAX_DEPTH=$MAX_DEPTH '
415bf5ca77SDevin Teske		{ sub(/^\\\t/, "\t") }
425bf5ca77SDevin Teske		{ buf = buf "\t" $0 "\n" }
435bf5ca77SDevin Teske		END {
445bf5ca77SDevin Teske			sub(/\n$/, "", buf)
455bf5ca77SDevin Teske			$0 = buf
465bf5ca77SDevin Teske			sub(/^[[:space:]]*/, "")
475bf5ca77SDevin Teske			for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) {
485bf5ca77SDevin Teske				gsub(/DEPTH/, DEPTH)
495bf5ca77SDevin Teske				print
505bf5ca77SDevin Teske				$0 = buf
515bf5ca77SDevin Teske			}
525bf5ca77SDevin Teske		}
535bf5ca77SDevin Teske	' <<-EOFDEPTH
545bf5ca77SDevin Teske	this->nameDEPTH = "";
555bf5ca77SDevin Teske	EOFDEPTH
565bf5ca77SDevin Teske	)
575bf5ca77SDevin Teske}
585bf5ca77SDevin Teske
595bf5ca77SDevin Teske$PROBE /this->vp == 0 || this->fi_fs == 0 ||
605bf5ca77SDevin Teske	this->fi_fs == "devfs" || this->fi_fs == "" ||
615bf5ca77SDevin Teske	this->fi_name == ""/ /* probe ID $(( $ID + 1 )) */
625bf5ca77SDevin Teske{${TRACE:+
635bf5ca77SDevin Teske	printf("<$(( $ID + 1 ))>");}
645bf5ca77SDevin Teske	this->ncp = 0;
655bf5ca77SDevin Teske}
665bf5ca77SDevin Teske
675bf5ca77SDevin Teske/*********************************************************/
685bf5ca77SDevin Teske
695bf5ca77SDevin Teske$PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */
705bf5ca77SDevin Teske{${TRACE:+
715bf5ca77SDevin Teske	printf("<$(( $ID + 2 ))>");}
725bf5ca77SDevin Teske	this->dvp = this->ncp->nc_dvp != NULL ?
735bf5ca77SDevin Teske		this->ncp->nc_dvp->v_cache_dst.tqh_first : 0;
745bf5ca77SDevin Teske	this->name1 = this->dvp != 0 ? (
755bf5ca77SDevin Teske		this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
765bf5ca77SDevin Teske	) : "";
775bf5ca77SDevin Teske}
785bf5ca77SDevin Teske
795bf5ca77SDevin Teske$PROBE /this->name1 == 0 || this->fi_fs == 0 ||
805bf5ca77SDevin Teske	this->fi_fs == "devfs" || this->fi_fs == "" ||
815bf5ca77SDevin Teske	this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */
825bf5ca77SDevin Teske{${TRACE:+
835bf5ca77SDevin Teske	printf("<$(( $ID + 3 ))>");}
845bf5ca77SDevin Teske	this->dvp = 0;
855bf5ca77SDevin Teske}
865bf5ca77SDevin Teske
875bf5ca77SDevin Teske/*********************************************************/
885bf5ca77SDevin Teske
895bf5ca77SDevin Teske/*
905bf5ca77SDevin Teske * BEGIN Pathname-depth iterators
915bf5ca77SDevin Teske */
925bf5ca77SDevin Teske
935bf5ca77SDevin Teske$( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH '
945bf5ca77SDevin Teske	{ buf = buf $0 "\n" }
955bf5ca77SDevin Teske	END {
965bf5ca77SDevin Teske		sub(/\n$/, "", buf)
975bf5ca77SDevin Teske		for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
985bf5ca77SDevin Teske			$0 = buf
995bf5ca77SDevin Teske			gsub(/DEPTH/, DEPTH)
1005bf5ca77SDevin Teske			gsub(/IDNUM/, ID++)
1015bf5ca77SDevin Teske			print
1025bf5ca77SDevin Teske		}
1035bf5ca77SDevin Teske	}
1045bf5ca77SDevin Teske' <<EOFDEPTH
1055bf5ca77SDevin Teske$PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
1065bf5ca77SDevin Teske{${TRACE:+
1075bf5ca77SDevin Teske	printf("<IDNUM>");}
1085bf5ca77SDevin Teske	this->dvp = this->dvp->nc_dvp != NULL ?
1095bf5ca77SDevin Teske		this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
1105bf5ca77SDevin Teske	this->nameDEPTH = this->dvp != 0 ? (
1115bf5ca77SDevin Teske		this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
1125bf5ca77SDevin Teske	) : "";
1135bf5ca77SDevin Teske}
1145bf5ca77SDevin Teske
1155bf5ca77SDevin TeskeEOFDEPTH
1165bf5ca77SDevin Teske)
1175bf5ca77SDevin Teske
1185bf5ca77SDevin Teske$PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */
1195bf5ca77SDevin Teske{${TRACE:+
1205bf5ca77SDevin Teske	printf("<$(( $ID + $MAX_DEPTH + 3 ))>");}
1215bf5ca77SDevin Teske	this->dvp = this->dvp->nc_dvp != NULL ?
1225bf5ca77SDevin Teske		this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
1235bf5ca77SDevin Teske	this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? (
1245bf5ca77SDevin Teske		this->dvp->nc_dvp != NULL ? "..." : ""
1255bf5ca77SDevin Teske	) : "";
1265bf5ca77SDevin Teske}
1275bf5ca77SDevin Teske
1285bf5ca77SDevin Teske/*
1295bf5ca77SDevin Teske * END Pathname-depth iterators
1305bf5ca77SDevin Teske */
1315bf5ca77SDevin Teske
1325bf5ca77SDevin Teske/*********************************************************/
1335bf5ca77SDevin Teske
1345bf5ca77SDevin Teske$PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */
1355bf5ca77SDevin Teske{${TRACE:+
1365bf5ca77SDevin Teske	printf("<$(( $ID + $MAX_DEPTH + 4 ))>");
1375bf5ca77SDevin Teske}
1385bf5ca77SDevin Teske	/*
1395bf5ca77SDevin Teske	 * Join full path
1405bf5ca77SDevin Teske	 * NB: Up-to but not including the parent directory (joined below)
1415bf5ca77SDevin Teske	 */
1425bf5ca77SDevin Teske	this->path = this->fi_mount;
1435bf5ca77SDevin Teske	this->path = strjoin(this->path, this->fi_mount != 0 ? (
1445bf5ca77SDevin Teske		this->fi_mount == "/" ? "" : "/"
1455bf5ca77SDevin Teske	) : "/");
1465bf5ca77SDevin Teske	$( awk -v MAX_DEPTH=$MAX_DEPTH '
1475bf5ca77SDevin Teske		{ sub(/^\\\t/, "\t") }
1485bf5ca77SDevin Teske		{ buf = buf "\t" $0 "\n" }
1495bf5ca77SDevin Teske		END {
1505bf5ca77SDevin Teske			sub(/\n$/, "", buf)
1515bf5ca77SDevin Teske			$0 = buf
1525bf5ca77SDevin Teske			sub(/^[[:space:]]*/, "")
1535bf5ca77SDevin Teske			for (N = MAX_DEPTH + 1; N > 0; N--) {
1545bf5ca77SDevin Teske				gsub(/N/, N)
1555bf5ca77SDevin Teske				print
1565bf5ca77SDevin Teske				$0 = buf
1575bf5ca77SDevin Teske			}
1585bf5ca77SDevin Teske		}
1595bf5ca77SDevin Teske	' <<-EOFDEPTH
1605bf5ca77SDevin Teske	this->path = strjoin(this->path,
1615bf5ca77SDevin Teske	\	strjoin(this->nameN, this->nameN != "" ? "/" : ""));
1625bf5ca77SDevin Teske	EOFDEPTH
1635bf5ca77SDevin Teske	)
1645bf5ca77SDevin Teske
1655bf5ca77SDevin Teske	/* Join the parent directory name */
1665bf5ca77SDevin Teske	this->path = strjoin(this->path, strjoin(this->name =
1675bf5ca77SDevin Teske		(this->d_name != 0 ? this->d_name : ""),
1685bf5ca77SDevin Teske		this->name != "" ? "/" : ""));
1695bf5ca77SDevin Teske
1705bf5ca77SDevin Teske	/* Join the entry name */
1715bf5ca77SDevin Teske	this->path = strjoin(this->path,
1725bf5ca77SDevin Teske		this->name = (this->fi_name != 0 ? this->fi_name : ""));
1735bf5ca77SDevin Teske}
1745bf5ca77SDevin TeskeEOF
1755bf5ca77SDevin TeskeACTIONS=$( cat <&9 )
1765bf5ca77SDevin TeskeID=$(( $ID + $MAX_DEPTH + 5 ))
1775bf5ca77SDevin Teske
1785bf5ca77SDevin Teske############################################################ EVENT ACTION
1795bf5ca77SDevin Teske
1805bf5ca77SDevin TeskeEVENT_TEST="this->fi_mount != 0"
1815bf5ca77SDevin Teske
1825bf5ca77SDevin Teske############################################################ EVENT DETAILS
1835bf5ca77SDevin Teske
184*a061d970SDevin Teskeif [ ! "$CUSTOM_DETAILS" ]; then
1855bf5ca77SDevin Teskeexec 9<<EOF
1865bf5ca77SDevin Teske	/*
1875bf5ca77SDevin Teske	 * Print full path and target
1885bf5ca77SDevin Teske	 */
1895bf5ca77SDevin Teske	printf("%s -> %s", this->path, this->target);
1905bf5ca77SDevin TeskeEOF
1915bf5ca77SDevin TeskeEVENT_DETAILS=$( cat <&9 )
192*a061d970SDevin Teskefi
1935bf5ca77SDevin Teske
1945bf5ca77SDevin Teske################################################################################
1955bf5ca77SDevin Teske# END
1965bf5ca77SDevin Teske################################################################################
197