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 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 * 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 * 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 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 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 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