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