xref: /haiku/src/bin/addattr/addAttr.cpp (revision 24bb6e132db1ff97c26abf00f2b8df9155f48039)
117049c45SAxel Dörfler /*
206732c7cSAxel Dörfler  * Copyright 2004-2015, 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>
15*24bb6e13SAxel Dörfler #ifdef __HAIKU__
1678c9dabdSAxel Dörfler #	include <parsedate.h>
17*24bb6e13SAxel Dörfler #endif
1817049c45SAxel Dörfler 
19c8fa948bSStephan Aßmus #include <ctype.h>
20c8fa948bSStephan Aßmus #include <errno.h>
2117049c45SAxel Dörfler #include <stdlib.h>
2217049c45SAxel Dörfler #include <string.h>
233aeed660SJérôme Duval #include <strings.h>
24c8fa948bSStephan Aßmus #include <unistd.h>
2517049c45SAxel Dörfler 
2617049c45SAxel Dörfler 
2717049c45SAxel Dörfler template<class Type>
2817049c45SAxel Dörfler ssize_t
writeAttrValue(int fd,const char * name,type_code type,Type value)2917049c45SAxel Dörfler writeAttrValue(int fd, const char* name, type_code type, Type value)
3017049c45SAxel Dörfler {
3117049c45SAxel Dörfler 	ssize_t bytes = fs_write_attr(fd, name, type, 0, &value, sizeof(Type));
3217049c45SAxel Dörfler 	if (bytes < 0)
3317049c45SAxel Dörfler 		return errno;
3417049c45SAxel Dörfler 
3517049c45SAxel Dörfler 	return bytes;
3617049c45SAxel Dörfler }
3717049c45SAxel Dörfler 
3817049c45SAxel Dörfler 
3906732c7cSAxel Dörfler /*!	Writes an attribute to a node, taking the type into account and
4006732c7cSAxel Dörfler 	converting the value accordingly
4117049c45SAxel Dörfler 
4206732c7cSAxel Dörfler 	On success it will return the amount of bytes written
4306732c7cSAxel Dörfler 	On failure it returns an error code (negative number)
4406732c7cSAxel Dörfler */
4517049c45SAxel Dörfler static ssize_t
writeAttr(int fd,type_code type,const char * name,const char * value,size_t length)46fcdd9a92SAxel Dörfler writeAttr(int fd, type_code type, const char* name, const char* value, size_t length)
4717049c45SAxel Dörfler {
4817049c45SAxel Dörfler 	uint64 uint64value = 0;
4917049c45SAxel Dörfler 	int64 int64value = 0;
5017049c45SAxel Dörfler 	double floatValue = 0.0;
5117049c45SAxel Dörfler 
5217049c45SAxel Dörfler 	// parse number input at once
5317049c45SAxel Dörfler 
5417049c45SAxel Dörfler 	switch (type) {
5517049c45SAxel Dörfler 		case B_BOOL_TYPE:
5617049c45SAxel Dörfler 		case B_INT8_TYPE:
5717049c45SAxel Dörfler 		case B_INT16_TYPE:
5817049c45SAxel Dörfler 		case B_INT32_TYPE:
5917049c45SAxel Dörfler 		case B_INT64_TYPE:
6017049c45SAxel Dörfler 			int64value = strtoll(value, NULL, 0);
6117049c45SAxel Dörfler 			break;
6217049c45SAxel Dörfler 
6317049c45SAxel Dörfler 		case B_UINT8_TYPE:
6417049c45SAxel Dörfler 		case B_UINT16_TYPE:
6517049c45SAxel Dörfler 		case B_UINT32_TYPE:
6617049c45SAxel Dörfler 		case B_UINT64_TYPE:
6717049c45SAxel Dörfler 			uint64value = strtoull(value, NULL, 0);
6817049c45SAxel Dörfler 			break;
6917049c45SAxel Dörfler 
7017049c45SAxel Dörfler 		case B_FLOAT_TYPE:
7117049c45SAxel Dörfler 		case B_DOUBLE_TYPE:
7217049c45SAxel Dörfler 			floatValue = strtod(value, NULL);
7317049c45SAxel Dörfler 			break;
7417049c45SAxel Dörfler 	}
7517049c45SAxel Dörfler 
7617049c45SAxel Dörfler 	switch (type) {
7717049c45SAxel Dörfler 		case B_INT8_TYPE:
7817049c45SAxel Dörfler 			return writeAttrValue<int8>(fd, name, type, (int8)int64value);
7917049c45SAxel Dörfler 		case B_INT16_TYPE:
8017049c45SAxel Dörfler 			return writeAttrValue<int16>(fd, name, type, (int16)int64value);
8117049c45SAxel Dörfler 		case B_INT32_TYPE:
8217049c45SAxel Dörfler 			return writeAttrValue<int32>(fd, name, type, (int32)int64value);
8317049c45SAxel Dörfler 		case B_INT64_TYPE:
8417049c45SAxel Dörfler 			return writeAttrValue<int64>(fd, name, type, int64value);
8517049c45SAxel Dörfler 
8617049c45SAxel Dörfler 		case B_UINT8_TYPE:
8717049c45SAxel Dörfler 			return writeAttrValue<uint8>(fd, name, type, (uint8)uint64value);
8817049c45SAxel Dörfler 		case B_UINT16_TYPE:
8917049c45SAxel Dörfler 			return writeAttrValue<uint16>(fd, name, type, (uint16)uint64value);
9017049c45SAxel Dörfler 		case B_UINT32_TYPE:
9117049c45SAxel Dörfler 			return writeAttrValue<uint32>(fd, name, type, (uint32)uint64value);
9217049c45SAxel Dörfler 		case B_UINT64_TYPE:
9317049c45SAxel Dörfler 			return writeAttrValue<uint64>(fd, name, type, uint64value);
9417049c45SAxel Dörfler 
9517049c45SAxel Dörfler 		case B_FLOAT_TYPE:
9617049c45SAxel Dörfler 			return writeAttrValue<float>(fd, name, type, (float)floatValue);
9717049c45SAxel Dörfler 		case B_DOUBLE_TYPE:
9817049c45SAxel Dörfler 			return writeAttrValue<double>(fd, name, type, (double)floatValue);
9917049c45SAxel Dörfler 
10017049c45SAxel Dörfler 		case B_BOOL_TYPE:
10117049c45SAxel Dörfler 		{
10217049c45SAxel Dörfler 			uint8 boolValue = 0;
10317049c45SAxel Dörfler 
10417049c45SAxel Dörfler 			if (!strcasecmp(value, "true") || !strcasecmp(value, "t")
10517049c45SAxel Dörfler 				|| !strcasecmp(value, "on") || !strcasecmp(value, "enabled")
10617049c45SAxel Dörfler 				|| (isdigit(value[0]) && int64value == 1))
10717049c45SAxel Dörfler 				boolValue = 1;
10817049c45SAxel Dörfler 			else if (!strcasecmp(value, "false") || !strcasecmp(value, "f")
10917049c45SAxel Dörfler 				|| !strcasecmp(value, "off") || !strcasecmp(value, "disabled")
11017049c45SAxel Dörfler 				|| (isdigit(value[0]) && int64value == 0))
11117049c45SAxel Dörfler 				boolValue = 0;
11217049c45SAxel Dörfler 			else
11317049c45SAxel Dörfler 				return B_BAD_VALUE;
11417049c45SAxel Dörfler 
11517049c45SAxel Dörfler 			return writeAttrValue<uint8>(fd, name, B_BOOL_TYPE, boolValue);
11617049c45SAxel Dörfler 		}
11717049c45SAxel Dörfler 
118*24bb6e13SAxel Dörfler #ifdef __HAIKU__
11978c9dabdSAxel Dörfler 		case B_TIME_TYPE:
12078c9dabdSAxel Dörfler 		{
12178c9dabdSAxel Dörfler 			time_t timeValue = parsedate(value, time(NULL));
12278c9dabdSAxel Dörfler 			if (timeValue < 0)
12378c9dabdSAxel Dörfler 				return B_BAD_VALUE;
12478c9dabdSAxel Dörfler 
12578c9dabdSAxel Dörfler 			return writeAttrValue<time_t>(fd, name, B_TIME_TYPE, timeValue);
12678c9dabdSAxel Dörfler 		}
127*24bb6e13SAxel Dörfler #endif
12878c9dabdSAxel Dörfler 
12917049c45SAxel Dörfler 		case B_STRING_TYPE:
13017049c45SAxel Dörfler 		case B_MIME_STRING_TYPE:
13117049c45SAxel Dörfler 		default:
13217049c45SAxel Dörfler 			// For string, mime-strings and any other type we just write the value
133fcdd9a92SAxel Dörfler 			// Note that the trailing NULL is added. If a length was given, we write
134fcdd9a92SAxel Dörfler 			// the value directly, though.
135fcdd9a92SAxel Dörfler 			ssize_t bytes = fs_write_attr(fd, name, type, 0, value,
136fcdd9a92SAxel Dörfler 				length ? length : strlen(value) + 1);
13717049c45SAxel Dörfler 			if (bytes < 0)
13817049c45SAxel Dörfler 				return errno;
139fcdd9a92SAxel Dörfler 
14017049c45SAxel Dörfler 			return bytes;
14117049c45SAxel Dörfler 	}
14217049c45SAxel Dörfler }
14317049c45SAxel Dörfler 
14417049c45SAxel Dörfler 
14506732c7cSAxel Dörfler /*!	Adds an attribute to a file for the given type, name and value
14606732c7cSAxel Dörfler 	Converts the value accordingly in case of numeric or boolean types
14717049c45SAxel Dörfler 
14806732c7cSAxel Dörfler 	On success, it returns B_OK, or else an appropriate error code.
14906732c7cSAxel Dörfler */
15017049c45SAxel Dörfler status_t
addAttr(const char * file,type_code type,const char * name,const char * value,size_t length,bool resolveLinks)151fcdd9a92SAxel Dörfler addAttr(const char* file, type_code type, const char* name,
1528b20dbc8SJérôme Duval 	const char* value, size_t length, bool resolveLinks)
15317049c45SAxel Dörfler {
1548b20dbc8SJérôme Duval 	int fd = open(file, O_RDONLY | (resolveLinks ? 0 : O_NOTRAVERSE));
15517049c45SAxel Dörfler 	if (fd < 0)
15617049c45SAxel Dörfler 		return errno;
15717049c45SAxel Dörfler 
15817049c45SAxel Dörfler 	fs_remove_attr(fd, name);
159fcdd9a92SAxel Dörfler 	ssize_t bytes = writeAttr(fd, type, name, value, length);
16017049c45SAxel Dörfler 
1618e619472SStephan Aßmus 	close(fd);
1628e619472SStephan Aßmus 
16317049c45SAxel Dörfler 	return bytes >= 0 ? B_OK : bytes;
16417049c45SAxel Dörfler }
16517049c45SAxel Dörfler 
166