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