117049c45SAxel Dörfler /* 2fcdd9a92SAxel Dörfler * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. 317049c45SAxel Dörfler * Copyright 2002, Sebastian Nozzi. 417049c45SAxel Dörfler * 517049c45SAxel Dörfler * Distributed under the terms of the MIT license. 617049c45SAxel Dörfler */ 717049c45SAxel Dörfler 817049c45SAxel Dörfler 917049c45SAxel Dörfler #include "addAttr.h" 1017049c45SAxel Dörfler 1117049c45SAxel Dörfler #include <TypeConstants.h> 1217049c45SAxel Dörfler #include <Mime.h> 1317049c45SAxel Dörfler 1417049c45SAxel Dörfler #include <fs_attr.h> 1517049c45SAxel Dörfler 16c8fa948bSStephan Aßmus #include <ctype.h> 17c8fa948bSStephan Aßmus #include <errno.h> 1817049c45SAxel Dörfler #include <stdlib.h> 1917049c45SAxel Dörfler #include <string.h> 20*3aeed660SJérôme Duval #include <strings.h> 21c8fa948bSStephan Aßmus #include <unistd.h> 2217049c45SAxel Dörfler 2317049c45SAxel Dörfler 2417049c45SAxel Dörfler template<class Type> 2517049c45SAxel Dörfler ssize_t 2617049c45SAxel Dörfler writeAttrValue(int fd, const char *name, type_code type, Type value) 2717049c45SAxel Dörfler { 2817049c45SAxel Dörfler ssize_t bytes = fs_write_attr(fd, name, type, 0, &value, sizeof(Type)); 2917049c45SAxel Dörfler if (bytes < 0) 3017049c45SAxel Dörfler return errno; 3117049c45SAxel Dörfler 3217049c45SAxel Dörfler return bytes; 3317049c45SAxel Dörfler } 3417049c45SAxel Dörfler 3517049c45SAxel Dörfler 3617049c45SAxel Dörfler /** Writes an attribute to a node, taking the type into account and 377cd683baSJérôme Duval * converting the value accordingly 3817049c45SAxel Dörfler * 397cd683baSJérôme Duval * On success it will return the amount of bytes written 4017049c45SAxel Dörfler * On failure it returns an error code (negative number) 4117049c45SAxel Dörfler */ 4217049c45SAxel Dörfler 4317049c45SAxel Dörfler static ssize_t 44fcdd9a92SAxel Dörfler writeAttr(int fd, type_code type, const char *name, const char *value, size_t length) 4517049c45SAxel Dörfler { 4617049c45SAxel Dörfler uint64 uint64value = 0; 4717049c45SAxel Dörfler int64 int64value = 0; 4817049c45SAxel Dörfler double floatValue = 0.0; 4917049c45SAxel Dörfler 5017049c45SAxel Dörfler // parse number input at once 5117049c45SAxel Dörfler 5217049c45SAxel Dörfler switch (type) { 5317049c45SAxel Dörfler case B_BOOL_TYPE: 5417049c45SAxel Dörfler case B_INT8_TYPE: 5517049c45SAxel Dörfler case B_INT16_TYPE: 5617049c45SAxel Dörfler case B_INT32_TYPE: 5717049c45SAxel Dörfler case B_INT64_TYPE: 5817049c45SAxel Dörfler int64value = strtoll(value, NULL, 0); 5917049c45SAxel Dörfler break; 6017049c45SAxel Dörfler 6117049c45SAxel Dörfler case B_UINT8_TYPE: 6217049c45SAxel Dörfler case B_UINT16_TYPE: 6317049c45SAxel Dörfler case B_UINT32_TYPE: 6417049c45SAxel Dörfler case B_UINT64_TYPE: 6517049c45SAxel Dörfler uint64value = strtoull(value, NULL, 0); 6617049c45SAxel Dörfler break; 6717049c45SAxel Dörfler 6817049c45SAxel Dörfler case B_FLOAT_TYPE: 6917049c45SAxel Dörfler case B_DOUBLE_TYPE: 7017049c45SAxel Dörfler floatValue = strtod(value, NULL); 7117049c45SAxel Dörfler break; 7217049c45SAxel Dörfler } 7317049c45SAxel Dörfler 7417049c45SAxel Dörfler switch (type) { 7517049c45SAxel Dörfler case B_INT8_TYPE: 7617049c45SAxel Dörfler return writeAttrValue<int8>(fd, name, type, (int8)int64value); 7717049c45SAxel Dörfler case B_INT16_TYPE: 7817049c45SAxel Dörfler return writeAttrValue<int16>(fd, name, type, (int16)int64value); 7917049c45SAxel Dörfler case B_INT32_TYPE: 8017049c45SAxel Dörfler return writeAttrValue<int32>(fd, name, type, (int32)int64value); 8117049c45SAxel Dörfler case B_INT64_TYPE: 8217049c45SAxel Dörfler return writeAttrValue<int64>(fd, name, type, int64value); 8317049c45SAxel Dörfler 8417049c45SAxel Dörfler case B_UINT8_TYPE: 8517049c45SAxel Dörfler return writeAttrValue<uint8>(fd, name, type, (uint8)uint64value); 8617049c45SAxel Dörfler case B_UINT16_TYPE: 8717049c45SAxel Dörfler return writeAttrValue<uint16>(fd, name, type, (uint16)uint64value); 8817049c45SAxel Dörfler case B_UINT32_TYPE: 8917049c45SAxel Dörfler return writeAttrValue<uint32>(fd, name, type, (uint32)uint64value); 9017049c45SAxel Dörfler case B_UINT64_TYPE: 9117049c45SAxel Dörfler return writeAttrValue<uint64>(fd, name, type, uint64value); 9217049c45SAxel Dörfler 9317049c45SAxel Dörfler case B_FLOAT_TYPE: 9417049c45SAxel Dörfler return writeAttrValue<float>(fd, name, type, (float)floatValue); 9517049c45SAxel Dörfler case B_DOUBLE_TYPE: 9617049c45SAxel Dörfler return writeAttrValue<double>(fd, name, type, (double)floatValue); 9717049c45SAxel Dörfler 9817049c45SAxel Dörfler case B_BOOL_TYPE: 9917049c45SAxel Dörfler { 10017049c45SAxel Dörfler uint8 boolValue = 0; 10117049c45SAxel Dörfler 10217049c45SAxel Dörfler if (!strcasecmp(value, "true") || !strcasecmp(value, "t") 10317049c45SAxel Dörfler || !strcasecmp(value, "on") || !strcasecmp(value, "enabled") 10417049c45SAxel Dörfler || (isdigit(value[0]) && int64value == 1)) 10517049c45SAxel Dörfler boolValue = 1; 10617049c45SAxel Dörfler else if (!strcasecmp(value, "false") || !strcasecmp(value, "f") 10717049c45SAxel Dörfler || !strcasecmp(value, "off") || !strcasecmp(value, "disabled") 10817049c45SAxel Dörfler || (isdigit(value[0]) && int64value == 0)) 10917049c45SAxel Dörfler boolValue = 0; 11017049c45SAxel Dörfler else 11117049c45SAxel Dörfler return B_BAD_VALUE; 11217049c45SAxel Dörfler 11317049c45SAxel Dörfler return writeAttrValue<uint8>(fd, name, B_BOOL_TYPE, boolValue); 11417049c45SAxel Dörfler } 11517049c45SAxel Dörfler 11617049c45SAxel Dörfler case B_STRING_TYPE: 11717049c45SAxel Dörfler case B_MIME_STRING_TYPE: 11817049c45SAxel Dörfler default: 11917049c45SAxel Dörfler // For string, mime-strings and any other type we just write the value 120fcdd9a92SAxel Dörfler // Note that the trailing NULL is added. If a length was given, we write 121fcdd9a92SAxel Dörfler // the value directly, though. 122fcdd9a92SAxel Dörfler ssize_t bytes = fs_write_attr(fd, name, type, 0, value, 123fcdd9a92SAxel Dörfler length ? length : strlen(value) + 1); 12417049c45SAxel Dörfler if (bytes < 0) 12517049c45SAxel Dörfler return errno; 126fcdd9a92SAxel Dörfler 12717049c45SAxel Dörfler return bytes; 12817049c45SAxel Dörfler } 12917049c45SAxel Dörfler } 13017049c45SAxel Dörfler 13117049c45SAxel Dörfler 13217049c45SAxel Dörfler /** Adds an attribute to a file for the given type, name and value 13317049c45SAxel Dörfler * Converts the value accordingly in case of numeric or boolean types 13417049c45SAxel Dörfler * 13517049c45SAxel Dörfler * On success, it returns B_OK, or else an appropriate error code. 13617049c45SAxel Dörfler */ 13717049c45SAxel Dörfler 13817049c45SAxel Dörfler status_t 139fcdd9a92SAxel Dörfler addAttr(const char *file, type_code type, const char *name, 1408b20dbc8SJérôme Duval const char *value, size_t length, bool resolveLinks) 14117049c45SAxel Dörfler { 1428b20dbc8SJérôme Duval int fd = open(file, O_RDONLY | (resolveLinks ? 0 : O_NOTRAVERSE)); 14317049c45SAxel Dörfler if (fd < 0) 14417049c45SAxel Dörfler return errno; 14517049c45SAxel Dörfler 14617049c45SAxel Dörfler fs_remove_attr(fd, name); 147fcdd9a92SAxel Dörfler ssize_t bytes = writeAttr(fd, type, name, value, length); 14817049c45SAxel Dörfler 1498e619472SStephan Aßmus close(fd); 1508e619472SStephan Aßmus 15117049c45SAxel Dörfler return bytes >= 0 ? B_OK : bytes; 15217049c45SAxel Dörfler } 15317049c45SAxel Dörfler 154