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