blob: 42c9be8ff3e8ce0e810dab59d6ce0862ef52d315 [file] [log] [blame]
Dmitry V. Levin769ffe92014-12-06 03:53:16 +00001#include "defs.h"
2
3#ifdef HAVE_LINUX_XATTR_H
4# include <linux/xattr.h>
5#else
6# define XATTR_CREATE 1
7# define XATTR_REPLACE 2
8#endif
9
10#include "xlat/xattrflags.h"
11
12static void
13print_xattr_val(struct tcb *tcp, int failed,
14 unsigned long arg,
15 unsigned long insize,
16 unsigned long size)
17{
18 if (insize == 0)
19 failed = 1;
20 if (!failed) {
21 unsigned long capacity = 4 * size + 1;
22 unsigned char *buf = (capacity < size) ? NULL : malloc(capacity);
23 if (buf == NULL || /* probably a bogus size argument */
24 umoven(tcp, arg, size, (char *) &buf[3 * size]) < 0) {
25 failed = 1;
26 }
27 else {
28 unsigned char *out = buf;
29 unsigned char *in = &buf[3 * size];
30 size_t i;
31 for (i = 0; i < size; ++i) {
32 if (in[i] >= ' ' && in[i] <= 0x7e)
33 *out++ = in[i];
34 else {
35#define tohex(n) "0123456789abcdef"[n]
36 *out++ = '\\';
37 *out++ = 'x';
38 *out++ = tohex(in[i] / 16);
39 *out++ = tohex(in[i] % 16);
40 }
41 }
42 /* Don't print terminating NUL if there is one. */
43 if (i > 0 && in[i - 1] == '\0')
44 out -= 4;
45 *out = '\0';
46 tprintf(", \"%s\", %ld", buf, insize);
47 }
48 free(buf);
49 }
50 if (failed)
51 tprintf(", 0x%lx, %ld", arg, insize);
52}
53
54int
55sys_setxattr(struct tcb *tcp)
56{
57 if (entering(tcp)) {
58 printpath(tcp, tcp->u_arg[0]);
59 tprints(", ");
60 printstr(tcp, tcp->u_arg[1], -1);
61 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
62 tprints(", ");
63 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
64 }
65 return 0;
66}
67
68int
69sys_fsetxattr(struct tcb *tcp)
70{
71 if (entering(tcp)) {
72 printfd(tcp, tcp->u_arg[0]);
73 tprints(", ");
74 printstr(tcp, tcp->u_arg[1], -1);
75 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
76 tprints(", ");
77 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
78 }
79 return 0;
80}
81
82int
83sys_getxattr(struct tcb *tcp)
84{
85 if (entering(tcp)) {
86 printpath(tcp, tcp->u_arg[0]);
87 tprints(", ");
88 printstr(tcp, tcp->u_arg[1], -1);
89 } else {
90 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
91 tcp->u_rval);
92 }
93 return 0;
94}
95
96int
97sys_fgetxattr(struct tcb *tcp)
98{
99 if (entering(tcp)) {
100 printfd(tcp, tcp->u_arg[0]);
101 tprints(", ");
102 printstr(tcp, tcp->u_arg[1], -1);
103 } else {
104 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
105 tcp->u_rval);
106 }
107 return 0;
108}
109
110static void
111print_xattr_list(struct tcb *tcp, unsigned long addr, unsigned long size)
112{
113 if (syserror(tcp)) {
114 tprintf("%#lx", addr);
115 } else {
116 if (!addr) {
117 tprints("NULL");
118 } else {
119 unsigned long len =
120 (size < (unsigned long) tcp->u_rval) ?
121 size : (unsigned long) tcp->u_rval;
122 printstr(tcp, addr, len);
123 }
124 }
125 tprintf(", %lu", size);
126}
127
128int
129sys_listxattr(struct tcb *tcp)
130{
131 if (entering(tcp)) {
132 printpath(tcp, tcp->u_arg[0]);
133 tprints(", ");
134 } else {
135 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
136 }
137 return 0;
138}
139
140int
141sys_flistxattr(struct tcb *tcp)
142{
143 if (entering(tcp)) {
144 printfd(tcp, tcp->u_arg[0]);
145 tprints(", ");
146 } else {
147 print_xattr_list(tcp, tcp->u_arg[1], tcp->u_arg[2]);
148 }
149 return 0;
150}
151
152int
153sys_removexattr(struct tcb *tcp)
154{
155 if (entering(tcp)) {
156 printpath(tcp, tcp->u_arg[0]);
157 tprints(", ");
158 printstr(tcp, tcp->u_arg[1], -1);
159 }
160 return 0;
161}
162
163int
164sys_fremovexattr(struct tcb *tcp)
165{
166 if (entering(tcp)) {
167 printfd(tcp, tcp->u_arg[0]);
168 tprints(", ");
169 printstr(tcp, tcp->u_arg[1], -1);
170 }
171 return 0;
172}