xref: /haiku/src/bin/listattr.cpp (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
1 /*
2  * Copyright 2004, Axel Dörfler, axeld@pinc-software.de.
3  * Copyright 2002, Ryan Fleet.
4  *
5  * Distributed under the terms of the MIT license.
6  */
7 
8 
9 #include <TypeConstants.h>
10 #include <Mime.h>
11 
12 #include <fs_attr.h>
13 
14 #include <string.h>
15 #include <stdio.h>
16 
17 
18 static const char *
19 get_type(type_code type)
20 {
21 	static char buffer[32];
22 
23 	switch (type) {
24 		case B_MIME_STRING_TYPE:
25 			return "MIME String";
26 		case B_RAW_TYPE:
27 			return "Raw Data";
28 
29 		case B_STRING_TYPE:
30 			return "Text";
31 		case B_INT64_TYPE:
32 			return "Int-64";
33 		case B_UINT64_TYPE:
34 			return "Uint-64";
35 		case B_INT32_TYPE:
36 			return "Int-32";
37 		case B_UINT32_TYPE:
38 			return "Uint-32";
39 		case B_INT16_TYPE:
40 			return "Int-16";
41 		case B_UINT16_TYPE:
42 			return "Uint-16";
43 		case B_INT8_TYPE:
44 			return "Int-8";
45 		case B_UINT8_TYPE:
46 			return "Uint-8";
47 		case B_BOOL_TYPE:
48 			return "Boolean";
49 		case B_FLOAT_TYPE:
50 			return "Float";
51 		case B_DOUBLE_TYPE:
52 			return "Double";
53 
54 		case 'MICN':
55 			return "Mini Icon";
56 		case 'ICON':
57 			return "Icon";
58 
59 		default:
60 		{
61 			int32 missed = 0, shift = 24;
62 			uint8 value[4];
63 			for (int32 i = 0; i < 4; i++, shift -= 8) {
64 				value[i] = uint8(type >> shift);
65 				if (value[i] < ' ' || value[i] > 127) {
66 					value[i] = '.';
67 					missed++;
68 				}
69 			}
70 
71 			if (missed < 2)
72 				sprintf(buffer, "'%c%c%c%c'", value[0], value[1], value[2], value[3]);
73 			else
74 				sprintf(buffer, "0x%08lx", type);
75 			return buffer;
76 		}
77 	}
78 }
79 
80 
81 int
82 main(int argc, char *argv[])
83 {
84 	const char *program = strrchr(argv[0], '/');
85 	if (program == NULL)
86 		program = argv[0];
87 	else
88 		program++;
89 
90 	if (argc < 2 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
91 		printf("usage: %s 'filename' ['filename' ...]\n", program);
92 		return 1;
93 	}
94 
95 	off_t total = 0;
96 
97 	for (int i = 1; i < argc; ++i) {
98 		BNode node(argv[i]);
99 
100 		status_t status = node.InitCheck();
101 		if (status < B_OK) {
102 			fprintf(stderr, "%s: initialization failed for \"%s\": %s\n",
103 				program, argv[i], strerror(status));
104 			return 0;
105 		}
106 
107 		printf("File: %s\n", argv[i]);
108 		printf("  Type         Size                 Name\n");
109 		printf("-----------  ---------  -------------------------------\n");
110 
111 		char name[B_ATTR_NAME_LENGTH];
112 		while (node.GetNextAttrName(name) == B_OK) {
113 			attr_info attrInfo;
114 
115 			status = node.GetAttrInfo(name, &attrInfo);
116 			if (status >= B_OK) {
117 				printf("%11s ", get_type(attrInfo.type));
118 				printf("% 10Li  ", attrInfo.size);
119 				printf("\"%s\"\n", name);
120 				total += attrInfo.size;
121 			} else {
122 				fprintf(stderr, "%s: stat failed for \"%s\": %s\n",
123 					program, name, strerror(status));
124 			}
125 		}
126 	}
127 
128 	printf("\n%Ld bytes total in attributes.\n", total);
129 	return 0;
130 }
131