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