Make UEFI boot-platform build again
[haiku.git] / src / bin / addattr / addAttr.cpp
blob5305e0849261caf1d027048faf288debe997777a
1 /*
2 * Copyright 2004-2015, Axel Dörfler, axeld@pinc-software.de.
3 * Copyright 2002, Sebastian Nozzi.
5 * Distributed under the terms of the MIT license.
6 */
9 #include "addAttr.h"
11 #include <TypeConstants.h>
12 #include <Mime.h>
14 #include <fs_attr.h>
15 #ifdef __HAIKU__
16 # include <parsedate.h>
17 #endif
19 #include <ctype.h>
20 #include <errno.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <strings.h>
24 #include <unistd.h>
27 template<class Type>
28 ssize_t
29 writeAttrValue(int fd, const char* name, type_code type, Type value)
31 ssize_t bytes = fs_write_attr(fd, name, type, 0, &value, sizeof(Type));
32 if (bytes < 0)
33 return errno;
35 return bytes;
39 /*! Writes an attribute to a node, taking the type into account and
40 converting the value accordingly
42 On success it will return the amount of bytes written
43 On failure it returns an error code (negative number)
45 static ssize_t
46 writeAttr(int fd, type_code type, const char* name, const char* value, size_t length)
48 uint64 uint64value = 0;
49 int64 int64value = 0;
50 double floatValue = 0.0;
52 // parse number input at once
54 switch (type) {
55 case B_BOOL_TYPE:
56 case B_INT8_TYPE:
57 case B_INT16_TYPE:
58 case B_INT32_TYPE:
59 case B_INT64_TYPE:
60 int64value = strtoll(value, NULL, 0);
61 break;
63 case B_UINT8_TYPE:
64 case B_UINT16_TYPE:
65 case B_UINT32_TYPE:
66 case B_UINT64_TYPE:
67 uint64value = strtoull(value, NULL, 0);
68 break;
70 case B_FLOAT_TYPE:
71 case B_DOUBLE_TYPE:
72 floatValue = strtod(value, NULL);
73 break;
76 switch (type) {
77 case B_INT8_TYPE:
78 return writeAttrValue<int8>(fd, name, type, (int8)int64value);
79 case B_INT16_TYPE:
80 return writeAttrValue<int16>(fd, name, type, (int16)int64value);
81 case B_INT32_TYPE:
82 return writeAttrValue<int32>(fd, name, type, (int32)int64value);
83 case B_INT64_TYPE:
84 return writeAttrValue<int64>(fd, name, type, int64value);
86 case B_UINT8_TYPE:
87 return writeAttrValue<uint8>(fd, name, type, (uint8)uint64value);
88 case B_UINT16_TYPE:
89 return writeAttrValue<uint16>(fd, name, type, (uint16)uint64value);
90 case B_UINT32_TYPE:
91 return writeAttrValue<uint32>(fd, name, type, (uint32)uint64value);
92 case B_UINT64_TYPE:
93 return writeAttrValue<uint64>(fd, name, type, uint64value);
95 case B_FLOAT_TYPE:
96 return writeAttrValue<float>(fd, name, type, (float)floatValue);
97 case B_DOUBLE_TYPE:
98 return writeAttrValue<double>(fd, name, type, (double)floatValue);
100 case B_BOOL_TYPE:
102 uint8 boolValue = 0;
104 if (!strcasecmp(value, "true") || !strcasecmp(value, "t")
105 || !strcasecmp(value, "on") || !strcasecmp(value, "enabled")
106 || (isdigit(value[0]) && int64value == 1))
107 boolValue = 1;
108 else if (!strcasecmp(value, "false") || !strcasecmp(value, "f")
109 || !strcasecmp(value, "off") || !strcasecmp(value, "disabled")
110 || (isdigit(value[0]) && int64value == 0))
111 boolValue = 0;
112 else
113 return B_BAD_VALUE;
115 return writeAttrValue<uint8>(fd, name, B_BOOL_TYPE, boolValue);
118 #ifdef __HAIKU__
119 case B_TIME_TYPE:
121 time_t timeValue = parsedate(value, time(NULL));
122 if (timeValue < 0)
123 return B_BAD_VALUE;
125 return writeAttrValue<time_t>(fd, name, B_TIME_TYPE, timeValue);
127 #endif
129 case B_STRING_TYPE:
130 case B_MIME_STRING_TYPE:
131 default:
132 // For string, mime-strings and any other type we just write the value
133 // Note that the trailing NULL is added. If a length was given, we write
134 // the value directly, though.
135 ssize_t bytes = fs_write_attr(fd, name, type, 0, value,
136 length ? length : strlen(value) + 1);
137 if (bytes < 0)
138 return errno;
140 return bytes;
145 /*! Adds an attribute to a file for the given type, name and value
146 Converts the value accordingly in case of numeric or boolean types
148 On success, it returns B_OK, or else an appropriate error code.
150 status_t
151 addAttr(const char* file, type_code type, const char* name,
152 const char* value, size_t length, bool resolveLinks)
154 int fd = open(file, O_RDONLY | (resolveLinks ? 0 : O_NOTRAVERSE));
155 if (fd < 0)
156 return errno;
158 fs_remove_attr(fd, name);
159 ssize_t bytes = writeAttr(fd, type, name, value, length);
161 close(fd);
163 return bytes >= 0 ? B_OK : bytes;