1 /* 2 * Copyright 2004-2006, 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 <fs_attr.h> 15 16 #include <ctype.h> 17 #include <errno.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <unistd.h> 21 22 23 template<class Type> 24 ssize_t 25 writeAttrValue(int fd, const char *name, type_code type, Type value) 26 { 27 ssize_t bytes = fs_write_attr(fd, name, type, 0, &value, sizeof(Type)); 28 if (bytes < 0) 29 return errno; 30 31 return bytes; 32 } 33 34 35 /** Writes an attribute to a node, taking the type into account and 36 * converting the value accordingly 37 * 38 * On success it will return the amount of bytes written 39 * On failure it returns an error code (negative number) 40 */ 41 42 static ssize_t 43 writeAttr(int fd, type_code type, const char *name, const char *value, size_t length) 44 { 45 uint64 uint64value = 0; 46 int64 int64value = 0; 47 double floatValue = 0.0; 48 49 // parse number input at once 50 51 switch (type) { 52 case B_BOOL_TYPE: 53 case B_INT8_TYPE: 54 case B_INT16_TYPE: 55 case B_INT32_TYPE: 56 case B_INT64_TYPE: 57 int64value = strtoll(value, NULL, 0); 58 break; 59 60 case B_UINT8_TYPE: 61 case B_UINT16_TYPE: 62 case B_UINT32_TYPE: 63 case B_UINT64_TYPE: 64 uint64value = strtoull(value, NULL, 0); 65 break; 66 67 case B_FLOAT_TYPE: 68 case B_DOUBLE_TYPE: 69 floatValue = strtod(value, NULL); 70 break; 71 } 72 73 switch (type) { 74 case B_INT8_TYPE: 75 return writeAttrValue<int8>(fd, name, type, (int8)int64value); 76 case B_INT16_TYPE: 77 return writeAttrValue<int16>(fd, name, type, (int16)int64value); 78 case B_INT32_TYPE: 79 return writeAttrValue<int32>(fd, name, type, (int32)int64value); 80 case B_INT64_TYPE: 81 return writeAttrValue<int64>(fd, name, type, int64value); 82 83 case B_UINT8_TYPE: 84 return writeAttrValue<uint8>(fd, name, type, (uint8)uint64value); 85 case B_UINT16_TYPE: 86 return writeAttrValue<uint16>(fd, name, type, (uint16)uint64value); 87 case B_UINT32_TYPE: 88 return writeAttrValue<uint32>(fd, name, type, (uint32)uint64value); 89 case B_UINT64_TYPE: 90 return writeAttrValue<uint64>(fd, name, type, uint64value); 91 92 case B_FLOAT_TYPE: 93 return writeAttrValue<float>(fd, name, type, (float)floatValue); 94 case B_DOUBLE_TYPE: 95 return writeAttrValue<double>(fd, name, type, (double)floatValue); 96 97 case B_BOOL_TYPE: 98 { 99 uint8 boolValue = 0; 100 101 if (!strcasecmp(value, "true") || !strcasecmp(value, "t") 102 || !strcasecmp(value, "on") || !strcasecmp(value, "enabled") 103 || (isdigit(value[0]) && int64value == 1)) 104 boolValue = 1; 105 else if (!strcasecmp(value, "false") || !strcasecmp(value, "f") 106 || !strcasecmp(value, "off") || !strcasecmp(value, "disabled") 107 || (isdigit(value[0]) && int64value == 0)) 108 boolValue = 0; 109 else 110 return B_BAD_VALUE; 111 112 return writeAttrValue<uint8>(fd, name, B_BOOL_TYPE, boolValue); 113 } 114 115 case B_STRING_TYPE: 116 case B_MIME_STRING_TYPE: 117 default: 118 // For string, mime-strings and any other type we just write the value 119 // Note that the trailing NULL is added. If a length was given, we write 120 // the value directly, though. 121 ssize_t bytes = fs_write_attr(fd, name, type, 0, value, 122 length ? length : strlen(value) + 1); 123 if (bytes < 0) 124 return errno; 125 126 return bytes; 127 } 128 } 129 130 131 /** Adds an attribute to a file for the given type, name and value 132 * Converts the value accordingly in case of numeric or boolean types 133 * 134 * On success, it returns B_OK, or else an appropriate error code. 135 */ 136 137 status_t 138 addAttr(const char *file, type_code type, const char *name, 139 const char *value, size_t length, bool resolveLinks) 140 { 141 int fd = open(file, O_RDONLY | (resolveLinks ? 0 : O_NOTRAVERSE)); 142 if (fd < 0) 143 return errno; 144 145 fs_remove_attr(fd, name); 146 ssize_t bytes = writeAttr(fd, type, name, value, length); 147 148 close(fd); 149 150 return bytes >= 0 ? B_OK : bytes; 151 } 152 153