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