xref: /haiku/src/bin/addattr/main.cpp (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 /*
2  * Copyright 2004, Axel Dörfler, axeld@pinc-software.de.
3  * Copyright 2002, Sebastian Nozzi.
4  *
5  * Distributed under the terms of the MIT license.
6  */
7 
8 
9 #include "addAttr.h"
10 
11 #include <TypeConstants.h>
12 #include <Mime.h>
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 
19 // supported types (if you add any, make sure that writeAttr() handles them properly)
20 
21 const struct {
22 	type_code	type;
23 	const char	*name;
24 } kSupportedTypes[] = {
25 	{B_STRING_TYPE, "string"},
26 	{B_MIME_STRING_TYPE, "mime"},
27 
28 	{B_INT32_TYPE, "int32"},
29 	{B_INT32_TYPE, "int"},
30 	{B_UINT32_TYPE, "uint32"},
31 	{B_UINT32_TYPE, "uint"},
32 
33 	{B_INT64_TYPE, "int64"},
34 	{B_INT64_TYPE, "llong"},
35 	{B_UINT64_TYPE, "uint64"},
36 	{B_UINT64_TYPE, "ullong"},
37 
38 	{B_FLOAT_TYPE, "float"},
39 	{B_DOUBLE_TYPE, "double"},
40 
41 	{B_BOOL_TYPE, "bool"},
42 };
43 const uint32 kNumSupportedTypes = sizeof(kSupportedTypes) / sizeof(kSupportedTypes[0]);
44 
45 char *gProgramName;
46 
47 
48 /**	For the given string that the user specifies as attribute type
49  *	in the command line, this function tries to figure out the
50  *	corresponding Be API value.
51  *
52  *	On success, "result" will contain that value
53  *	On failure, B_BAD_VALUE is returned and "result" is not modified
54  */
55 
56 static status_t
57 typeForString(const char *string, type_code *_result)
58 {
59 	for (uint32 i = 0; i < kNumSupportedTypes; i++) {
60 		if (!strcmp(string, kSupportedTypes[i].name)) {
61 			*_result = kSupportedTypes[i].type;
62 			return B_OK;
63 		}
64 	}
65 
66 	// type didn't show up - in this case, we parse the string
67 	// as number and use it directly as type code
68 
69 	if (sscanf(string, "%lu", _result) == 1)
70 		return B_OK;
71 
72 	return B_BAD_VALUE;
73 }
74 
75 
76 void
77 usage(void)
78 {
79 	fprintf(stderr, "usage: %s [-t type] attr value file1 [file2...]\n", gProgramName);
80 	fprintf(stderr, "\tType is one of:\n");
81 	fprintf(stderr, "\t\tstring, mime, int, llong, float, double, bool,\n");
82 	fprintf(stderr, "\t\tor a numeric value (ie. 0x1234, 42, ...)\n");
83 	fprintf(stderr, "\tThe default is `string\'\n");
84 
85 	exit(1);
86 }
87 
88 
89 void
90 invalidAttrType(const char *attrTypeName)
91 {
92 	fprintf(stderr, "%s: attribute type \"%s\" is not valid\n", gProgramName, attrTypeName);
93 	fprintf(stderr, "\tTry one of: string, mime, int, llong, float, double,\n");
94 	fprintf(stderr, "\t\tbool, or a numeric value (ie. 0x1234, 42, ...)\n");
95 
96 	exit(1);
97 }
98 
99 
100 void
101 invalidBoolValue(const char *value)
102 {
103 	fprintf(stderr, "%s: attribute value \"%s\" is not valid\n", gProgramName, value);
104 	fprintf(stderr, "\tBool accepts: 0, f, false, disabled, off,\n");
105 	fprintf(stderr, "\t\t1, t, true, enabled, on\n");
106 
107 	exit(1);
108 }
109 
110 
111 int
112 main(int argc, char *argv[])
113 {
114 	gProgramName = strrchr(argv[0], '/');
115 	if (gProgramName == NULL)
116 		gProgramName = argv[0];
117 	else
118 		gProgramName++;
119 
120 	if (argc < 3 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))
121 		usage();
122 
123 	type_code attrType = B_STRING_TYPE;
124 
125 	int32 i = 1;
126 
127 	if (!strcmp(argv[1], "-t")) {
128 		// Get the attribute type
129 		if (typeForString(argv[2], &attrType) != B_OK)
130 			invalidAttrType(argv[2]);
131 
132 		i += 2;
133 	}
134 
135 	const char *attrName = argv[i++];
136 	const char *attrValue = argv[i++];
137 
138 	// no files specified
139 	if (argv[i] == NULL)
140 		usage();
141 
142 	// Now that we gathered all the information proceed
143 	// to add the attribute to the file(s)
144 
145 	int result = 0;
146 
147 	for (; i < argc; i++) {
148 		status_t status = addAttr(argv[i], attrType, attrName, attrValue);
149 
150 		// special case for bool types
151 		if (status == B_BAD_VALUE && attrType == B_BOOL_TYPE)
152 			invalidBoolValue(attrValue);
153 
154 		if (status != B_OK) {
155 			fprintf(stderr, "%s: can\'t add attribute to file %s: %s\n",
156 				gProgramName, argv[i], strerror(status));
157 
158 			// proceed files, but return an error at the end
159 			result = 1;
160 		}
161 	}
162 
163 	return result;
164 }
165 
166