2 * Copyright 2004-2015, Axel Dörfler, axeld@pinc-software.de.
3 * Copyright 2002, Ryan Fleet.
5 * Distributed under the terms of the MIT license.
10 #include <TypeConstants.h>
20 /*! Dumps the contents of the attribute in the form of raw data. This view
21 is used for the type B_RAW_TYPE, for custom types and for any type that
22 is not directly supported by the utility "addattr".
25 dump_raw_data(const char *buffer
, size_t size
)
27 const uint32 kChunkSize
= 16;
28 uint32 dumpPosition
= 0;
30 while (dumpPosition
< size
) {
31 // Position for this line
32 printf("\t%04" B_PRIx32
": ", dumpPosition
);
34 // Print the bytes in form of hexadecimal numbers
35 for (uint32 i
= 0; i
< kChunkSize
; i
++) {
36 if (dumpPosition
+ i
< size
) {
37 printf("%02x ", (uint8
)buffer
[dumpPosition
+ i
]);
42 // Print the bytes in form of printable characters
43 // (whenever possible)
45 for (uint32 i
= 0; i
< kChunkSize
; i
++) {
46 if (dumpPosition
< size
) {
47 char c
= buffer
[dumpPosition
];
48 putchar(isgraph(c
) ? c
: '.');
60 show_attr_contents(BNode
& node
, const char* attribute
, const attr_info
& info
)
62 // limit size of the attribute, only the first kLimit byte will make it on
66 off_t size
= info
.size
;
73 ssize_t bytesRead
= node
.ReadAttr(attribute
, info
.type
, 0, buffer
, size
);
74 if (bytesRead
!= size
) {
75 fprintf(stderr
, "Could only read %" B_PRIdOFF
" bytes from attribute!\n",
82 printf("%" B_PRId8
"\n", *((int8
*)buffer
));
85 printf("%" B_PRIu8
"\n", *((uint8
*)buffer
));
88 printf("%" B_PRId16
"\n", *((int16
*)buffer
));
91 printf("%" B_PRIu16
"\n", *((uint16
*)buffer
));
94 printf("%" B_PRId32
"\n", *((int32
*)buffer
));
97 printf("%" B_PRIu32
"\n", *((uint32
*)buffer
));
100 printf("%" B_PRId64
"\n", *((int64
*)buffer
));
103 printf("%" B_PRIu64
"\n", *((uint64
*)buffer
));
106 printf("%f\n", *((float *)buffer
));
109 printf("%f\n", *((double *)buffer
));
112 printf("%d\n", *((unsigned char *)buffer
));
116 char stringBuffer
[256];
118 localtime_r((time_t *)buffer
, &timeInfo
);
119 strftime(stringBuffer
, sizeof(stringBuffer
), "%c", &timeInfo
);
120 printf("%s\n", stringBuffer
);
124 case B_MIME_STRING_TYPE
:
128 printf("%s\n", buffer
);
134 if (!cut
&& message
.Unflatten(buffer
) == B_OK
) {
136 message
.PrintToStream();
140 // supposed to fall through
144 // The rest of the attributes types are displayed as raw data
146 dump_raw_data(buffer
, size
);
154 get_type(type_code type
)
156 static char buffer
[32];
159 case B_MIME_STRING_TYPE
:
160 return "MIME String";
189 case B_MINI_ICON_TYPE
:
191 case B_LARGE_ICON_TYPE
:
196 int32 missed
= 0, shift
= 24;
198 for (int32 i
= 0; i
< 4; i
++, shift
-= 8) {
199 value
[i
] = uint8(type
>> shift
);
200 if (value
[i
] < ' ' || value
[i
] > 127) {
207 sprintf(buffer
, "'%c%c%c%c'", value
[0], value
[1], value
[2],
210 sprintf(buffer
, "0x%08" B_PRIx32
, type
);
219 main(int argc
, char *argv
[])
221 const char *program
= strrchr(argv
[0], '/');
227 bool printContents
= false;
229 if (argc
> 2 && (!strcmp(argv
[1], "--long") || !strcmp(argv
[1], "-l"))) {
230 printContents
= true;
235 if (argc
< 2 || !strcmp(argv
[1], "--help") || !strcmp(argv
[1], "-h")) {
236 printf("usage: %s [-l|--long] 'filename' ['filename' ...]\n"
237 " -l, --long Shows the attribute contents as well.\n", program
);
238 return argc
== 2 ? 0 : 1;
243 for (int i
= 1; i
< argc
; ++i
) {
246 status_t status
= node
.InitCheck();
248 fprintf(stderr
, "%s: initialization failed for \"%s\": %s\n",
249 program
, argv
[i
], strerror(status
));
253 printf("File: %s\n", argv
[i
]);
255 const int kTypeWidth
= 12;
256 const int kSizeWidth
= 10;
257 const int kNameWidth
= 36;
258 const int kContentsWidth
= 21;
259 printf("%*s %*s %-*s%s\n", kTypeWidth
, "Type", kSizeWidth
, "Size",
260 kNameWidth
, "Name", printContents
? "Contents" : "");
263 separator
.SetTo('-', kTypeWidth
+ kSizeWidth
+ kNameWidth
264 + (printContents
? kContentsWidth
: 0));
265 puts(separator
.String());
267 char name
[B_ATTR_NAME_LENGTH
];
268 while (node
.GetNextAttrName(name
) == B_OK
) {
271 status
= node
.GetAttrInfo(name
, &attrInfo
);
272 if (status
>= B_OK
) {
273 printf("%*s", kTypeWidth
, get_type(attrInfo
.type
));
274 printf("% *" B_PRId64
" ", kSizeWidth
, attrInfo
.size
);
275 printf("\"%s\"", name
);
279 int length
= kNameWidth
- 2 - strlen(name
);
281 printf("%*s", length
, "");
283 show_attr_contents(node
, name
, attrInfo
);
287 total
+= attrInfo
.size
;
289 fprintf(stderr
, "%s: stat failed for \"%s\": %s\n",
290 program
, name
, strerror(status
));
295 printf("\n%" B_PRId64
" bytes total in attributes.\n", total
);