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