xref: /haiku/src/bin/addattr/addAttr.cpp (revision 3aeed6607cd07762c0e709633c012b3a632dbad9)
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