1 /* 2 * Copyright 2004, Axel Dörfler, axeld@pinc-software.de. 3 * Copyright 2002, Sebastian Nozzi. 4 * 5 * Distributed under the terms of the MIT license. 6 */ 7 8 9 #include "addAttr.h" 10 11 #include <TypeConstants.h> 12 #include <Mime.h> 13 14 #include <stdio.h> 15 #include <string.h> 16 17 18 // supported types (if you add any, make sure that writeAttr() handles them properly) 19 20 const struct { 21 type_code type; 22 const char *name; 23 } kSupportedTypes[] = { 24 {B_STRING_TYPE, "string"}, 25 {B_MIME_STRING_TYPE, "mime"}, 26 27 {B_INT32_TYPE, "int32"}, 28 {B_INT32_TYPE, "int"}, 29 {B_UINT32_TYPE, "uint32"}, 30 {B_UINT32_TYPE, "uint"}, 31 32 {B_INT64_TYPE, "int64"}, 33 {B_INT64_TYPE, "llong"}, 34 {B_UINT64_TYPE, "uint64"}, 35 {B_UINT64_TYPE, "ullong"}, 36 37 {B_FLOAT_TYPE, "float"}, 38 {B_DOUBLE_TYPE, "double"}, 39 40 {B_BOOL_TYPE, "bool"}, 41 }; 42 const uint32 kNumSupportedTypes = sizeof(kSupportedTypes) / sizeof(kSupportedTypes[0]); 43 44 char *gProgramName; 45 46 47 /** For the given string that the user specifies as attribute type 48 * in the command line, this function tries to figure out the 49 * corresponding Be API value. 50 * 51 * On success, "result" will contain that value 52 * On failure, B_BAD_VALUE is returned and "result" is not modified 53 */ 54 55 static status_t 56 typeForString(const char *string, type_code *_result) 57 { 58 for (uint32 i = 0; i < kNumSupportedTypes; i++) { 59 if (!strcmp(string, kSupportedTypes[i].name)) { 60 *_result = kSupportedTypes[i].type; 61 return B_OK; 62 } 63 } 64 65 // type didn't show up - in this case, we parse the string 66 // as number and use it directly as type code 67 68 if (sscanf(string, "%lu", _result) == 1) 69 return B_OK; 70 71 return B_BAD_VALUE; 72 } 73 74 75 void 76 usage(void) 77 { 78 fprintf(stderr, "usage: %s [-t type] attr value file1 [file2...]\n", gProgramName); 79 fprintf(stderr, "\tType is one of:\n"); 80 fprintf(stderr, "\t\tstring, mime, int, llong, float, double, bool,\n"); 81 fprintf(stderr, "\t\tor a numeric value (ie. 0x1234, 42, ...)\n"); 82 fprintf(stderr, "\tThe default is `string\'\n"); 83 84 exit(1); 85 } 86 87 88 void 89 invalidAttrType(const char *attrTypeName) 90 { 91 fprintf(stderr, "%s: attribute type \"%s\" is not valid\n", gProgramName, attrTypeName); 92 fprintf(stderr, "\tTry one of: string, mime, int, llong, float, double,\n"); 93 fprintf(stderr, "\t\tbool, or a numeric value (ie. 0x1234, 42, ...)\n"); 94 95 exit(1); 96 } 97 98 99 void 100 invalidBoolValue(const char *value) 101 { 102 fprintf(stderr, "%s: attribute value \"%s\" is not valid\n", gProgramName, value); 103 fprintf(stderr, "\tBool accepts: 0, f, false, disabled, off,\n"); 104 fprintf(stderr, "\t\t1, t, true, enabled, on\n"); 105 106 exit(1); 107 } 108 109 110 int 111 main(int argc, char *argv[]) 112 { 113 gProgramName = strrchr(argv[0], '/'); 114 if (gProgramName == NULL) 115 gProgramName = argv[0]; 116 else 117 gProgramName++; 118 119 if (argc < 3 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) 120 usage(); 121 122 type_code attrType = B_STRING_TYPE; 123 124 int32 i = 1; 125 126 if (!strcmp(argv[1], "-t")) { 127 // Get the attribute type 128 if (typeForString(argv[2], &attrType) != B_OK) 129 invalidAttrType(argv[2]); 130 131 i += 2; 132 } 133 134 const char *attrName = argv[i++]; 135 const char *attrValue = argv[i++]; 136 137 // no files specified 138 if (argv[i] == NULL) 139 usage(); 140 141 // Now that we gathered all the information proceed 142 // to add the attribute to the file(s) 143 144 int result = 0; 145 146 for (; i < argc; i++) { 147 status_t status = addAttr(argv[i], attrType, attrName, attrValue); 148 149 // special case for bool types 150 if (status == B_BAD_VALUE && attrType == B_BOOL_TYPE) 151 invalidBoolValue(attrValue); 152 153 if (status != B_OK) { 154 fprintf(stderr, "%s: can\'t add attribute to file %s: %s\n", 155 gProgramName, argv[i], strerror(status)); 156 157 // proceed files, but return an error at the end 158 result = 1; 159 } 160 } 161 162 return result; 163 } 164 165