• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <string.h>
3 #include "fuse_kernel.h"
4 
5 static struct {
6 	const char *name;
7 } fuse_ll_ops[] = {
8 	[FUSE_LOOKUP]	   = { "LOOKUP"	     },
9 	[FUSE_FORGET]	   = { "FORGET"	     },
10 	[FUSE_GETATTR]	   = { "GETATTR"     },
11 	[FUSE_SETATTR]	   = { "SETATTR"     },
12 	[FUSE_READLINK]	   = { "READLINK"    },
13 	[FUSE_SYMLINK]	   = { "SYMLINK"     },
14 	[FUSE_MKNOD]	   = { "MKNOD"	     },
15 	[FUSE_MKDIR]	   = { "MKDIR"	     },
16 	[FUSE_UNLINK]	   = { "UNLINK"	     },
17 	[FUSE_RMDIR]	   = { "RMDIR"	     },
18 	[FUSE_RENAME]	   = { "RENAME"	     },
19 	[FUSE_LINK]	   = { "LINK"	     },
20 	[FUSE_OPEN]	   = { "OPEN"	     },
21 	[FUSE_READ]	   = { "READ"	     },
22 	[FUSE_WRITE]	   = { "WRITE"	     },
23 	[FUSE_STATFS]	   = { "STATFS"	     },
24 	[FUSE_RELEASE]	   = { "RELEASE"     },
25 	[FUSE_FSYNC]	   = { "FSYNC"	     },
26 	[FUSE_SETXATTR]	   = { "SETXATTR"    },
27 	[FUSE_GETXATTR]	   = { "GETXATTR"    },
28 	[FUSE_LISTXATTR]   = { "LISTXATTR"   },
29 	[FUSE_REMOVEXATTR] = { "REMOVEXATTR" },
30 	[FUSE_FLUSH]	   = { "FLUSH"	     },
31 	[FUSE_INIT]	   = { "INIT"	     },
32 	[FUSE_OPENDIR]	   = { "OPENDIR"     },
33 	[FUSE_READDIR]	   = { "READDIR"     },
34 	[FUSE_RELEASEDIR]  = { "RELEASEDIR"  },
35 	[FUSE_FSYNCDIR]	   = { "FSYNCDIR"    },
36 	[FUSE_GETLK]	   = { "GETLK"	     },
37 	[FUSE_SETLK]	   = { "SETLK"	     },
38 	[FUSE_SETLKW]	   = { "SETLKW"	     },
39 	[FUSE_ACCESS]	   = { "ACCESS"	     },
40 	[FUSE_CREATE]	   = { "CREATE"	     },
41 	[FUSE_INTERRUPT]   = { "INTERRUPT"   },
42 	[FUSE_BMAP]	   = { "BMAP"	     },
43 	[FUSE_DESTROY]	   = { "DESTROY"     },
44 	[FUSE_READDIRPLUS] = { "READDIRPLUS" },
45 };
46 
47 #define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
48 
opname(enum fuse_opcode opcode)49 static const char *opname(enum fuse_opcode opcode)
50 {
51 	if (opcode >= FUSE_MAXOP || !fuse_ll_ops[opcode].name)
52 		return "???";
53 	else
54 		return fuse_ll_ops[opcode].name;
55 }
56 
57 
process_buf(int dir,char * buf,int len)58 static void process_buf(int dir, char *buf, int len)
59 {
60 	static unsigned long long prevuniq = -1;
61 	static int prevopcode;
62 
63 	if (!dir) {
64 		struct fuse_in_header *in = (struct fuse_in_header *) buf;
65 		buf += sizeof(struct fuse_in_header);
66 
67 		printf("unique: %llu, opcode: %s (%i), nodeid: %lu, len: %i, insize: %i\n",
68 		       (unsigned long long) in->unique,
69 		       opname((enum fuse_opcode) in->opcode), in->opcode,
70 		       (unsigned long) in->nodeid, in->len, len);
71 
72 		switch (in->opcode) {
73 		case FUSE_READ: {
74 			struct fuse_read_in *arg = (struct fuse_read_in *) buf;
75 			printf("-READ fh:%llu off:%llu siz:%u rfl:%u own:%llu fl:%u\n",
76 			       arg->fh, arg->offset, arg->size, arg->read_flags,
77 			       arg->lock_owner, arg->flags);
78 			break;
79 		}
80 		case FUSE_WRITE: {
81 			struct fuse_write_in *arg = (struct fuse_write_in *) buf;
82 			printf("-WRITE fh:%llu off:%llu siz:%u wfl:%u own:%llu fl:%u\n",
83 			       arg->fh, arg->offset, arg->size, arg->write_flags,
84 			       arg->lock_owner, arg->flags);
85 			break;
86 		}
87 		}
88 		prevuniq = in->unique;
89 		prevopcode = in->opcode;
90 	} else {
91 		struct fuse_out_header *out = (struct fuse_out_header *) buf;
92 		buf += sizeof(struct fuse_out_header);
93 
94 		printf("   unique: %llu, error: %i (%s), len: %i, outsize: %i\n",
95 		       (unsigned long long) out->unique, out->error,
96 		       strerror(-out->error), out->len, len);
97 
98 		if (out->unique == prevuniq) {
99 			switch (prevopcode) {
100 			case FUSE_GETATTR: {
101 				struct fuse_attr_out *arg = (struct fuse_attr_out *) buf;
102 				printf("+ATTR v:%llu.%09u i:%llu s:%llu b:%llu\n",
103 				       arg->attr_valid, arg->attr_valid_nsec,
104 				       arg->attr.ino, arg->attr.size, arg->attr.blocks);
105 				break;
106 			}
107 			case FUSE_LOOKUP: {
108 				struct fuse_entry_out *arg = (struct fuse_entry_out *) buf;
109 				printf("+ENTRY nodeid:%llu v:%llu.%09u i:%llu s:%llu b:%llu\n",
110 				       arg->nodeid, arg->attr_valid, arg->attr_valid_nsec,
111 				       arg->attr.ino, arg->attr.size, arg->attr.blocks);
112 				break;
113 			}
114 			}
115 		}
116 	}
117 
118 }
119 
main(void)120 int main(void)
121 {
122 	FILE *in = stdin;
123 	while (1) {
124 		int dir;
125 		int res;
126 		char buf[1048576];
127 		unsigned len = 0;
128 
129 		memset(buf, 0, sizeof(buf));
130 		while (1) {
131 			char str[32];
132 
133 			res = fscanf(in, "%30s", str);
134 			if (res != 1 && feof(in))
135 				return 0;
136 
137 			if (res == 0)
138 				continue;
139 
140 			if (strncmp(str, "read(", 5) == 0) {
141 				dir = 0;
142 				break;
143 			} else if (strncmp(str, "writev(", 7) == 0) {
144 				dir = 1;
145 				break;
146 			}
147 		}
148 
149 		while (1) {
150 			int c = getc(in);
151 			if (c == '"') {
152 				while (1) {
153 					int val;
154 
155 					c = getc(in);
156 					if (c == EOF) {
157 						fprintf(stderr, "eof in string\n");
158 						break;
159 					}
160 					if (c == '\n') {
161 						fprintf(stderr, "eol in string\n");
162 						break;
163 					}
164 					if (c == '"')
165 						break;
166 					if (c != '\\') {
167 						val = c;
168 					} else {
169 						c = getc(in);
170 						switch (c) {
171 						case 'n': val = '\n'; break;
172 						case 'r': val = '\r'; break;
173 						case 't': val = '\t'; break;
174 						case '"': val = '"'; break;
175 						case '\\': val = '\\'; break;
176 						case 'x':
177 							res = scanf("%x", &val);
178 							if (res != 1) {
179 								fprintf(stderr, "parse error\n");
180 								continue;
181 							}
182 							break;
183 						default:
184 							fprintf(stderr, "unknown sequence: '\\%c'\n", c);
185 							continue;
186 						}
187 					}
188 					buf[len++] = val;
189 				}
190 			}
191 			if (c == '\n')
192 				break;
193 		}
194 		process_buf(dir, buf, len);
195 		memset(buf, 0, len);
196 		len = 0;
197 	}
198 }
199