xref: /haiku/src/bin/lsindex.cpp (revision 15fb7d88e971c4d6c787c6a3a5c159afb1ebf77b)
1 //	lsindex - for Haiku
2 //
3 //	authors, in order of contribution:
4 //	jonas.sundstrom@kirilla.com
5 //	revol@free.fr
6 //	axeld@pinc-software.de
7 //
8 
9 #include <TypeConstants.h>
10 #include <fs_info.h>
11 #include <fs_index.h>
12 
13 #include <stdio.h>
14 #include <string.h>
15 #include <errno.h>
16 
17 
18 static void
19 print_help(void)
20 {
21 	fprintf (stderr,
22 		"Usage: lsindex [--help | -v | --verbose | --mkindex | -l | --long] [volume path]\n"
23 		"   -l --long\t outputs long listing\n"
24 		"   -v --verbose\t gives index type, dates and owner\n"
25 		"      --mkindex\t outputs mkindex commands to recreate all the indices\n"
26 		"      --help\t prints out this text\n\n"
27 		"   If no volume is specified, the volume of the current directory is assumed.\n");
28 }
29 
30 
31 static const char *
32 print_index_type(const index_info &info, bool mkindexOutput)
33 {
34 	static char buffer[30];
35 
36 	switch (info.type) {
37 		case B_INT32_TYPE:
38 			return mkindexOutput ? "int" : "Int-32";
39 		case B_INT64_TYPE:
40 			return mkindexOutput ? "llong" : "Int-64";
41 		case B_STRING_TYPE:
42 			return mkindexOutput ? "string" : "Text";
43 		case B_FLOAT_TYPE:
44 			return mkindexOutput ? "float" : "Float";
45 		case B_DOUBLE_TYPE:
46 			return mkindexOutput ? "double" : "Double";
47 
48 		default:
49 			sprintf(buffer, mkindexOutput
50 				 ? "0x%08" B_PRIx32
51 				 : "Unknown type (0x%" B_PRIx32 ")",
52 					info.type);
53 			return buffer;
54 	}
55 }
56 
57 
58 static const char *
59 type_string(type_code type)
60 {
61 	// all types from <TypeConstants.h> listed for completeness,
62 	// even though they don't all apply to attribute indices
63 
64 #define RETURN_TYPE(x) case x: return #x
65 
66 	switch (type) {
67 		RETURN_TYPE(B_ANY_TYPE);
68 		RETURN_TYPE(B_BOOL_TYPE);
69 		RETURN_TYPE(B_CHAR_TYPE);
70 		RETURN_TYPE(B_COLOR_8_BIT_TYPE);
71 		RETURN_TYPE(B_DOUBLE_TYPE);
72 		RETURN_TYPE(B_FLOAT_TYPE);
73 		RETURN_TYPE(B_GRAYSCALE_8_BIT_TYPE);
74 		RETURN_TYPE(B_INT64_TYPE);
75 		RETURN_TYPE(B_INT32_TYPE);
76 		RETURN_TYPE(B_INT16_TYPE);
77 		RETURN_TYPE(B_INT8_TYPE);
78 		RETURN_TYPE(B_MESSAGE_TYPE);
79 		RETURN_TYPE(B_MESSENGER_TYPE);
80 		RETURN_TYPE(B_MIME_TYPE);
81 		RETURN_TYPE(B_MONOCHROME_1_BIT_TYPE);
82 		RETURN_TYPE(B_OBJECT_TYPE);
83 		RETURN_TYPE(B_OFF_T_TYPE);
84 		RETURN_TYPE(B_PATTERN_TYPE);
85 		RETURN_TYPE(B_POINTER_TYPE);
86 		RETURN_TYPE(B_POINT_TYPE);
87 		RETURN_TYPE(B_RAW_TYPE);
88 		RETURN_TYPE(B_RECT_TYPE);
89 		RETURN_TYPE(B_REF_TYPE);
90 		RETURN_TYPE(B_RGB_32_BIT_TYPE);
91 		RETURN_TYPE(B_RGB_COLOR_TYPE);
92 		RETURN_TYPE(B_SIZE_T_TYPE);
93 		RETURN_TYPE(B_SSIZE_T_TYPE);
94 		RETURN_TYPE(B_STRING_TYPE);
95 		RETURN_TYPE(B_TIME_TYPE);
96 		RETURN_TYPE(B_UINT64_TYPE);
97 		RETURN_TYPE(B_UINT32_TYPE);
98 		RETURN_TYPE(B_UINT16_TYPE);
99 		RETURN_TYPE(B_UINT8_TYPE);
100 		RETURN_TYPE(B_MEDIA_PARAMETER_TYPE);
101 		RETURN_TYPE(B_MEDIA_PARAMETER_WEB_TYPE);
102 		RETURN_TYPE(B_MEDIA_PARAMETER_GROUP_TYPE);
103 		RETURN_TYPE(B_ASCII_TYPE);
104 
105 		default:
106 			return NULL;
107 	}
108 #undef RETURN_TYPE
109 }
110 
111 
112 static void
113 print_index_long_stat(const index_info &info, char *name)
114 {
115 	char modified[30];
116 	strftime(modified, 30, "%m/%d/%Y %I:%M %p",
117 		localtime(&info.modification_time));
118 	printf("%16s  %s  %8" B_PRIdOFF " %s\n",
119 		print_index_type(info, false), modified, info.size, name);
120 }
121 
122 
123 static void
124 print_index_verbose_stat(const index_info &info, char *name)
125 {
126 	printf("%-18s\t", name);
127 
128 	// Type
129 	const char *typeString = type_string(info.type);
130 	if (typeString != NULL)
131 		printf("%-10s\t", typeString);
132 	else
133 		printf("%" B_PRIu32 "\t", info.type);
134 
135 	// Size
136 	printf("%10" B_PRIdOFF "  ", info.size);
137 
138 	// Created
139 	char string[30];
140 	strftime(string, sizeof(string), "%Y-%m-%d %H:%M", localtime(&info.creation_time));
141 	printf("%s  ", string);
142 
143 	// Modified
144 	strftime(string, sizeof(string), "%Y-%m-%d %H:%M", localtime(&info.modification_time));
145 	printf("%s", string);
146 
147 	// User
148 	printf("%5d", info.uid);
149 
150 	// Group
151 	printf("%5d\n", info.gid);
152 }
153 
154 
155 int
156 main(int argc, char **argv)
157 {
158 	dev_t device = dev_for_path(".");
159 	DIR *indices = NULL;
160 	bool verbose = false;
161 	bool longListing = false;
162 	bool mkindexOutput = false; /* mkindex-ready output */
163 
164 	for (int i = 1; i < argc; i++) {
165 		if (argv[i][0] == '-') {
166 			if (!strcmp(argv[i], "--help")) {
167 				print_help();
168 				return 0;
169 			} else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v"))
170 				verbose = true;
171 			else if (!strcmp(argv[i], "--long") || !strcmp(argv[i], "-l"))
172 				longListing = true;
173 			else if (!strcmp(argv[i], "--mkindex"))
174 				mkindexOutput = true;
175 			else {
176 				fprintf(stderr, "%s: option %s is not understood (use --help for help)\n", argv[0], argv[i]);
177 				return -1;
178 			}
179 		} else {
180 			device = dev_for_path(argv[i]);
181 			if (device < 0) {
182 				fprintf(stderr, "%s: can't get information about volume: %s\n", argv[0], argv[i]);
183 				return -1;
184 			}
185 		}
186 	}
187 
188 	indices = fs_open_index_dir(device);
189 	if (indices == NULL) {
190 		fprintf(stderr, "%s: can't open index dir of device %" B_PRIdDEV "\n",
191 			argv[0], device);
192 		return -1;
193 	}
194 
195 	if (verbose) {
196 		printf(" Name   Type   Size   Created   Modified   User   Group\n");
197 		printf("********************************************************\n");
198 	}
199 
200 	while (1) {
201 		dirent *index = fs_read_index_dir(indices);
202 		if (index == NULL) {
203 			if (errno != B_ENTRY_NOT_FOUND && errno != B_OK) {
204 				printf("%s: fs_read_index_dir: (%d) %s\n", argv[0], errno, strerror(errno));
205 				return errno;
206 			}
207 			break;
208 		}
209 
210 		if (verbose || longListing || mkindexOutput) {
211 			index_info info;
212 
213 			if (fs_stat_index(device, index->d_name, &info) != B_OK) {
214 				printf("%s: fs_stat_index(): (%d) %s\n", argv[0], errno, strerror(errno));
215 				return errno;
216 			}
217 
218 			if (verbose)
219 				print_index_verbose_stat(info, index->d_name);
220 			else if (longListing)
221 				print_index_long_stat(info, index->d_name);
222 			else /* mkindexOutput */
223 				printf("mkindex -t %s '%s'\n", print_index_type(info, true), index->d_name);
224 		} else
225 			printf("%s\n", index->d_name);
226 	}
227 
228 	fs_close_index_dir(indices);
229 	return 0;
230 }
231 
232