* Added option -f that allows you to read the attribute data from a file.

* No longer exits with error in case you specified "--help" or "-h".
* Now accepts typecodes in "'ABCD'" format as well.
* Can now also be built for BeOS compatible targets.
* Improved parameter check.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18038 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-07-05 11:54:56 +00:00
parent a744b2c60e
commit fcdd9a92b7
4 changed files with 104 additions and 29 deletions

View File

@ -1,6 +1,9 @@
SubDir HAIKU_TOP src bin addattr ;
SetSubDirSupportedPlatformsBeOSCompatible ;
BinCommand addattr :
main.cpp
addAttr.cpp
: be
;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002, Sebastian Nozzi.
*
* Distributed under the terms of the MIT license.
@ -39,7 +39,7 @@ writeAttrValue(int fd, const char *name, type_code type, Type value)
*/
static ssize_t
writeAttr(int fd, type_code type, const char *name, const char *value)
writeAttr(int fd, type_code type, const char *name, const char *value, size_t length)
{
uint64 uint64value = 0;
int64 int64value = 0;
@ -115,10 +115,13 @@ writeAttr(int fd, type_code type, const char *name, const char *value)
case B_MIME_STRING_TYPE:
default:
// For string, mime-strings and any other type we just write the value
// NOTE that the trailing NULL -IS- added
ssize_t bytes = fs_write_attr(fd, name, type, 0, value, strlen(value) + 1);
// Note that the trailing NULL is added. If a length was given, we write
// the value directly, though.
ssize_t bytes = fs_write_attr(fd, name, type, 0, value,
length ? length : strlen(value) + 1);
if (bytes < 0)
return errno;
return bytes;
}
}
@ -131,14 +134,15 @@ writeAttr(int fd, type_code type, const char *name, const char *value)
*/
status_t
addAttr(const char *file, type_code type, const char *name, const char *value)
addAttr(const char *file, type_code type, const char *name,
const char *value, size_t length)
{
int fd = open(file, O_WRONLY);
if (fd < 0)
return errno;
fs_remove_attr(fd, name);
ssize_t bytes = writeAttr(fd, type, name, value);
ssize_t bytes = writeAttr(fd, type, name, value, length);
return bytes >= 0 ? B_OK : bytes;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002, Sebastian Nozzi.
*
* Distributed under the terms of the MIT license.
@ -11,6 +11,7 @@
#include <SupportDefs.h>
status_t addAttr(const char *file, type_code attrType, const char *attrName, const char *attrValue);
status_t addAttr(const char *file, type_code attrType, const char *attrName,
const char *attrValue, size_t length);
#endif /* _ADD_ATTR_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002, Sebastian Nozzi.
*
* Distributed under the terms of the MIT license.
@ -8,8 +8,9 @@
#include "addAttr.h"
#include <TypeConstants.h>
#include <File.h>
#include <Mime.h>
#include <TypeConstants.h>
#include <stdio.h>
#include <stdlib.h>
@ -69,20 +70,35 @@ typeForString(const char *string, type_code *_result)
if (sscanf(string, "%lu", _result) == 1)
return B_OK;
uchar type[4];
if (sscanf(string, "'%c%c%c%c'", &type[0], &type[1], &type[2], &type[3]) == 4) {
*_result = (type[0] << 24) | (type[1] << 16) | (type[2] << 8) | type[3];
return B_OK;
}
return B_BAD_VALUE;
}
void
usage(void)
usage(int returnValue)
{
fprintf(stderr, "usage: %s [-t type] attr value file1 [file2...]\n", gProgramName);
fprintf(stderr, "\tType is one of:\n");
fprintf(stderr, "\t\tstring, mime, int, llong, float, double, bool,\n");
fprintf(stderr, "\t\tor a numeric value (ie. 0x1234, 42, ...)\n");
fprintf(stderr, "\tThe default is `string\'\n");
fprintf(stderr, "usage: %s [-t type] attr value file1 [file2...]\n"
" or: %s [-f value-from-file] [-t type] attr file1 [file2...]\n\n"
"\tType is one of:\n"
"\t\tstring, mime, int, llong, float, double, bool,\n"
"\t\tor a numeric value (ie. 0x1234, 42, 'ABCD', ...)\n"
"\tThe default is \"string\"\n", gProgramName, gProgramName);
exit(1);
exit(returnValue);
}
void
assertArgument(int i, int argc)
{
if (i >= argc)
usage(1);
}
@ -91,7 +107,7 @@ invalidAttrType(const char *attrTypeName)
{
fprintf(stderr, "%s: attribute type \"%s\" is not valid\n", gProgramName, attrTypeName);
fprintf(stderr, "\tTry one of: string, mime, int, llong, float, double,\n");
fprintf(stderr, "\t\tbool, or a numeric value (ie. 0x1234, 42, ...)\n");
fprintf(stderr, "\t\tbool, or a numeric value (ie. 0x1234, 42, 'ABCD', ...)\n");
exit(1);
}
@ -117,27 +133,74 @@ main(int argc, char *argv[])
else
gProgramName++;
if (argc < 3 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))
usage();
assertArgument(1, argc);
if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))
usage(0);
type_code attrType = B_STRING_TYPE;
char *attrValue = NULL;
size_t valueFileLength = 0;
int32 i = 1;
if (!strcmp(argv[1], "-t")) {
if (!strcmp(argv[i], "-f")) {
// retrieve attribute value from file
BFile file;
off_t size;
assertArgument(i, argc);
status_t status = file.SetTo(argv[i + 1], B_READ_ONLY);
if (status < B_OK) {
fprintf(stderr, "%s: can't read attribute value from file %s: %s\n",
gProgramName, argv[i], strerror(status));
return 1;
}
status = file.GetSize(&size);
if (status == B_OK) {
if (size > 4 * 1024 * 1024) {
fprintf(stderr, "%s: attribute value is too large: %Ld bytes\n",
gProgramName, size);
return 1;
}
attrValue = (char *)malloc(size);
if (attrValue != NULL)
status = file.Read(attrValue, size);
else
status = B_NO_MEMORY;
}
if (status < B_OK) {
fprintf(stderr, "%s: can't read attribute value: %s\n",
gProgramName, strerror(status));
return 1;
}
valueFileLength = (size_t)size;
i += 2;
}
assertArgument(i, argc);
if (!strcmp(argv[i], "-t")) {
// Get the attribute type
if (typeForString(argv[2], &attrType) != B_OK)
invalidAttrType(argv[2]);
assertArgument(i, argc);
if (typeForString(argv[i + 1], &attrType) != B_OK)
invalidAttrType(argv[i + 1]);
i += 2;
}
assertArgument(i, argc);
const char *attrName = argv[i++];
const char *attrValue = argv[i++];
// no files specified
if (argv[i] == NULL)
usage();
assertArgument(i, argc);
if (!valueFileLength)
attrValue = argv[i++];
// no files specified?
assertArgument(i, argc);
// Now that we gathered all the information proceed
// to add the attribute to the file(s)
@ -145,14 +208,15 @@ main(int argc, char *argv[])
int result = 0;
for (; i < argc; i++) {
status_t status = addAttr(argv[i], attrType, attrName, attrValue);
status_t status = addAttr(argv[i], attrType, attrName, attrValue,
valueFileLength);
// special case for bool types
if (status == B_BAD_VALUE && attrType == B_BOOL_TYPE)
invalidBoolValue(attrValue);
if (status != B_OK) {
fprintf(stderr, "%s: can\'t add attribute to file %s: %s\n",
fprintf(stderr, "%s: can't add attribute to file %s: %s\n",
gProgramName, argv[i], strerror(status));
// proceed files, but return an error at the end
@ -160,6 +224,9 @@ main(int argc, char *argv[])
}
}
if (valueFileLength)
free(attrValue);
return result;
}