1#include <stdio.h> 2#include <string.h> 3#include "fuse_kernel.h" 4 5static 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 49static 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 58static 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 120int 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