1 /* 2 * Copyright (c) 2003-2005, Haiku 3 * 4 * This software is part of the Haiku distribution and is covered 5 * by the MIT license. 6 * 7 * Authors: 8 * Scott Dellinger (dellinsd@myrealbox.com) 9 * Axel Dörfler, axeld@pinc-software.de. 10 */ 11 12 /** Description: Adds an index to a volume. */ 13 14 15 #include <fs_info.h> 16 #include <fs_index.h> 17 #include <TypeConstants.h> 18 #include <Directory.h> 19 #include <Path.h> 20 #include <Volume.h> 21 22 #include <getopt.h> 23 #include <stdio.h> 24 #include <string.h> 25 #include <errno.h> 26 27 28 static struct option const kLongOptions[] = { 29 {"volume", required_argument, 0, 'd'}, 30 {"type", required_argument, 0, 't'}, 31 {"copy-from", required_argument, 0, 'f'}, 32 {"verbose", no_argument, 0, 'v'}, 33 {"help", no_argument, 0, 'h'}, 34 {NULL} 35 }; 36 37 extern const char *__progname; 38 static const char *kProgramName = __progname; 39 40 41 static void 42 copy_indexes(dev_t from, dev_t to, bool verbose) 43 { 44 DIR *indexes = fs_open_index_dir(from); 45 46 if (verbose) 47 puts("Copying indexes:"); 48 49 while (dirent *dirent = fs_read_index_dir(indexes)) { 50 if (!strcmp(dirent->d_name, "name") 51 || !strcmp(dirent->d_name, "size") 52 || !strcmp(dirent->d_name, "last_modified")) 53 continue; 54 55 index_info info; 56 if (fs_stat_index(from, dirent->d_name, &info) != 0) { 57 fprintf(stderr, "%s: Skipped index \"%s\": %s\n", 58 kProgramName, dirent->d_name, strerror(errno)); 59 continue; 60 } 61 62 if (fs_create_index(to, dirent->d_name, info.type, 0) != 0) { 63 if (errno == B_BAD_VALUE || errno == B_FILE_EXISTS) { 64 // B_BAD_VALUE is what BeOS returns here... 65 continue; 66 } 67 fprintf(stderr, "%s: Could not create index \"%s\": %s\n", 68 kProgramName, dirent->d_name, strerror(errno)); 69 } else if (verbose) 70 printf("\t%s\n", dirent->d_name); 71 } 72 } 73 74 75 static void 76 usage(int status) 77 { 78 fprintf(stderr, 79 "Usage: %s [options] <attribute>\n" 80 "Creates a new index for the specified attribute.\n" 81 "\n" 82 " -d, --volume=PATH\ta path on the volume to which the index will be added,\n" 83 "\t\t\tdefaults to current volume.\n" 84 " -t, --type=TYPE the type of the attribute being indexed. One of \"int\",\n" 85 "\t\t\t\"llong\", \"string\", \"float\", or \"double\".\n" 86 "\t\t\tDefaults to \"string\".\n" 87 " --copy-from\tpath to volume to copy the indexes from.\n" 88 " -v, --verbose\t\tprint information about the index being created\n", 89 kProgramName); 90 91 exit(status); 92 } 93 94 95 int 96 main(int32 argc, char **argv) 97 { 98 char *indexTypeName = "string"; 99 int indexType = B_STRING_TYPE; 100 char *indexName = NULL; 101 bool verbose = false; 102 dev_t device = -1, copyFromDevice = -1; 103 104 int c; 105 while ((c = getopt_long(argc, argv, "d:ht:v", kLongOptions, NULL)) != -1) { 106 switch (c) { 107 case 0: 108 break; 109 case 'd': 110 device = dev_for_path(optarg); 111 if (device < 0) { 112 fprintf(stderr, "%s: can't get information about volume: %s\n", 113 kProgramName, optarg); 114 return -1; 115 } 116 break; 117 case 'f': 118 copyFromDevice = dev_for_path(optarg); 119 if (copyFromDevice < 0) { 120 fprintf(stderr, "%s: can't get information about volume: %s\n", 121 kProgramName, optarg); 122 return -1; 123 } 124 break; 125 case 'h': 126 usage(0); 127 break; 128 case 't': 129 indexTypeName = optarg; 130 if (strncmp("int", optarg, 3) == 0) 131 indexType = B_INT32_TYPE; 132 else if (strncmp("llong", optarg, 5) == 0) 133 indexType = B_INT64_TYPE; 134 else if (strncmp("string", optarg, 6) == 0) 135 indexType = B_STRING_TYPE; 136 else if (strncmp("float", optarg, 5) == 0) 137 indexType = B_FLOAT_TYPE; 138 else if (strncmp("double", optarg, 6) == 0) 139 indexType = B_DOUBLE_TYPE; 140 else 141 usage(1); 142 break; 143 case 'v': 144 verbose = 1; 145 break; 146 default: 147 usage(1); 148 break; 149 } 150 } 151 152 if (device == -1) { 153 // Create the index on the volume of the current 154 // directory if no volume was specified. 155 156 device = dev_for_path("."); 157 if (device < 0) { 158 fprintf(stderr, "%s: can't get information about current volume\n", kProgramName); 159 return -1; 160 } 161 } 162 163 if (copyFromDevice != -1) { 164 copy_indexes(copyFromDevice, device, verbose); 165 return 0; 166 } 167 168 if (argc - optind == 1) { 169 // last argument 170 indexName = argv[optind]; 171 } else 172 usage(1); 173 174 if (verbose) { 175 /* Get the mount point of the specified volume. */ 176 BVolume volume(device); 177 BDirectory dir; 178 volume.GetRootDirectory(&dir); 179 BPath path(&dir, NULL); 180 181 printf("Creating index \"%s\" of type %s on volume mounted at %s.\n", 182 indexName, indexTypeName, path.Path()); 183 } 184 185 if (fs_create_index(device, indexName, indexType, 0) != 0) 186 fprintf(stderr, "%s: Could not create index: %s\n", kProgramName, strerror(errno)); 187 188 return 0; 189 } 190