From bb103dca64528fb2aef6c9e076f745c210a4e451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 7 Oct 2002 22:22:09 +0000 Subject: [PATCH] nitial checkin. Code by Sebastian Nozzi. (sorry for the big lag on this one :p) git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1443 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/bin/addattr/addAttr.cpp | 188 ++++++++++++++++++++++++++++++ src/apps/bin/addattr/addAttr.h | 30 +++++ src/apps/bin/addattr/main.cpp | 136 +++++++++++++++++++++ src/apps/bin/addattr/messages.cpp | 34 ++++++ src/apps/bin/addattr/messages.h | 18 +++ 5 files changed, 406 insertions(+) create mode 100644 src/apps/bin/addattr/addAttr.cpp create mode 100644 src/apps/bin/addattr/addAttr.h create mode 100644 src/apps/bin/addattr/main.cpp create mode 100644 src/apps/bin/addattr/messages.cpp create mode 100644 src/apps/bin/addattr/messages.h diff --git a/src/apps/bin/addattr/addAttr.cpp b/src/apps/bin/addattr/addAttr.cpp new file mode 100644 index 0000000000..fa514bfe12 --- /dev/null +++ b/src/apps/bin/addattr/addAttr.cpp @@ -0,0 +1,188 @@ +// Author: Sebastian Nozzi +// Created: 3 may 2002 + +// Modifications: +// (please include author, date, and description) + +// mmu_man@sf.net: note the original one doesn't link to libbe + + +#include +#include +#include +#include +#include + +#include + +#include "addAttr.h" +#include "messages.h" + +// Adds a certain attribute to many files, specified in an array +// of strings +// +// On success it will return B_OK +// On failure it returns an error code (negative number) +status_t addAttrToFiles( type_code attrType, + const char *attrName, + const char *attrValue, + char **files, + unsigned fileCount ) { + + status_t returnCode; + status_t result; + unsigned fileIdx; + + returnCode = B_OK; + + // Iterate through all the files and add the attribute + // to each of them + + for( fileIdx = 0; fileIdx < fileCount; fileIdx++ ) { + result = addAttr( attrType, attrName, attrValue, files[fileIdx] ); + // Try to keep the first error code, if any + if( returnCode == B_OK && result != B_OK ) + returnCode = result; + } + + return returnCode; +} + +// Adds an attribute to a file for the given type, name and value +// Locks and unlocks the corresponding node to avoid data inconsistence +// Converts the value accordingly in case of numeric or boolean types +// +// On success it will return the amount of bytes writen +// On failure it returns an error code (negative number) +status_t addAttr( type_code attrType, + const char *attrName, + const char *attrValue, + const char *file ) { + + status_t returnCode; + + BNode node; + // Traverse links + BEntry entry(file, true); + + node.SetTo(&entry); + // Release file descriptor + entry.Unset(); + +#ifdef DEBUG + printf("%lu | %s | %s | %s\n", attrType, attrName, attrValue, file ); +#endif + + returnCode = node.InitCheck(); + + if( returnCode == B_OK ) { + + returnCode = node.Lock(); // to avoid data inconsistency + + if( returnCode == B_OK ) { + // Only add the attribute if not already there + if( hasAttribute( &node, attrName ) == false ) { + + ssize_t bytesWrittenCode; + + // Write the attribute now + bytesWrittenCode = writeAttr( &node, attrType, attrName, attrValue ); + + // If negative, then it's an error code + if( bytesWrittenCode < 0 ) { + problemsWithFileMsg( file ); + returnCode = bytesWrittenCode; + } + } + node.Sync(); + node.Unlock(); + } else { // Node could not be locked + problemsWithFileMsg( file ); + } + } else { + // File could not be initialized + // (maybe it doesn't exist) + problemsWithFileMsg( file ); + } + + return returnCode; +} + +// Writes an attribute to a node, taking the type into account and +// convertig the value accordingly +// +// On success it will return the amount of bytes writen +// On failure it returns an error code (negative number) +ssize_t writeAttr( BNode *node, type_code attrType, + const char *attrName, const char *attrValue ) { + + int32 int32buffer = 0; + int64 int64buffer = 0; + int boolBuffer = 0; + float floatBuffer = 0.0; + double doubleBuffer = 0.0; + + ssize_t bytesWrittenOrErrorCode; + + switch( attrType ) { + case B_INT32_TYPE: + sscanf( attrValue, "%ld", &int32buffer ); + bytesWrittenOrErrorCode = + node->WriteAttr( attrName, attrType, 0, &int32buffer, sizeof(int32) ); + break; + case B_INT64_TYPE: + sscanf( attrValue, "%lld", &int64buffer ); + bytesWrittenOrErrorCode = + node->WriteAttr( attrName, attrType, 0, &int64buffer, sizeof(int64) ); + break; + case B_FLOAT_TYPE: + sscanf( attrValue, "%f", &floatBuffer ); + bytesWrittenOrErrorCode = + node->WriteAttr( attrName, attrType, 0, &floatBuffer, sizeof(float) ); + break; + case B_DOUBLE_TYPE: + sscanf( attrValue, "%lf", &doubleBuffer ); + bytesWrittenOrErrorCode = + node->WriteAttr( attrName, attrType, 0, &doubleBuffer, sizeof(double) ); + break; + case B_BOOL_TYPE: + // NOTE: the conversion from "int" to "signed char" might seem strange + // but this is the only way I could think to replicate Be's addattr behaviour + sscanf( attrValue, "%d", &boolBuffer ); + boolBuffer = (signed char) boolBuffer; + bytesWrittenOrErrorCode = + node->WriteAttr( attrName, attrType, 0, &boolBuffer, sizeof(signed char) ); + break; + case B_STRING_TYPE: + 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 + bytesWrittenOrErrorCode = + node->WriteAttr( attrName, attrType, 0, attrValue, strlen(attrValue)+1 ); + break; + }; + + return bytesWrittenOrErrorCode; +} + +// Checks wether a node has an attribute under the given name or not +// +// The user is responsible for locking and unlocking the node, and +// for assuring that we are retrieving all attributes from the beginning +// by calling RewindAttrs() on the node, if necesary +bool hasAttribute( BNode *node, const char *attrName ) { + + char retrievedName[B_ATTR_NAME_LENGTH]; + bool found; + + found = false; + + while( (!found) && (node->GetNextAttrName( retrievedName )==B_OK) ) { + if( strcmp( retrievedName, attrName ) == 0 ) + found = true; + } + + return found; +} + diff --git a/src/apps/bin/addattr/addAttr.h b/src/apps/bin/addattr/addAttr.h new file mode 100644 index 0000000000..51d95538ba --- /dev/null +++ b/src/apps/bin/addattr/addAttr.h @@ -0,0 +1,30 @@ +// Author: Sebastian Nozzi +// Created: 3 may 2002 + +// Modifications: +// (please include author, date, and description) + +// mmu_man@sf.net: note the original one doesn't link to libbe + +#ifndef _ADD_ATTR_H +#define _ADD_ATTR_H + +#include + +status_t addAttrToFiles( type_code attrType, + const char *attrName, + const char *attrValue, + char **files, + unsigned fileCount ); + +status_t addAttr( type_code attrType, + const char *attrName, + const char *attrValue, + const char *file ); + +bool hasAttribute( BNode *node, const char *attrName ); +ssize_t writeAttr( BNode *node, type_code attrType, + const char *attrName, const char *attrValue ); + + +#endif \ No newline at end of file diff --git a/src/apps/bin/addattr/main.cpp b/src/apps/bin/addattr/main.cpp new file mode 100644 index 0000000000..4835f8942d --- /dev/null +++ b/src/apps/bin/addattr/main.cpp @@ -0,0 +1,136 @@ + +// Author: Sebastian Nozzi +// Created: 1st may 2002 + +// Modifications: +// (please include author, date, and description) + +#include +#include +#include + +#include +#include + +#include "addAttr.h" +#include "messages.h" + +status_t typeForString( const char *attrSting, type_code *result ); + +int main( int argc, char*argv[] ) +{ + int returnCode; + + completeToolName = argv[0]; + returnCode = 0; + + if( argc > 1 ) { + type_code attrType; + unsigned minArguments; + bool usingDefaultAttr; + bool validAttrType; + + usingDefaultAttr = true; + validAttrType = true; + minArguments = 3; + + // Get the attribute type + if( strcmp( argv[1], "-t" ) == 0 ) { + if( argc == 2 ) { + invalidAttrMsg( "(null)" ); + validAttrType = false; + returnCode = 1; + } else if( typeForString( argv[2], &attrType ) == B_BAD_VALUE ) { + invalidAttrMsg( argv[2] ); + validAttrType = false; + returnCode = 1; + } else { + usingDefaultAttr = false; + minArguments = 5; + } + } else { + // The user didn't specify a type + // The default is 'string' + attrType = B_STRING_TYPE; + } + + if( validAttrType ) { + if( (unsigned)argc > minArguments ) { + char **files; + char *attrName; + char *attrValue; + + // The location of the rest of the argument + // varies depending on wether there was a + // "-t" switch or not + if( usingDefaultAttr ) { + attrName = argv[1]; + attrValue = argv[2]; + files = &(argv[3]); + } else { + attrName = argv[3]; + attrValue = argv[4]; + files = &(argv[5]); + } + + // Now that we gathered all the information proceed + // to add the attribute to the file(s) + addAttrToFiles( attrType, attrName, attrValue, + files, argc-minArguments ); + + } else { // some arguments are missing + usageMsg(); + returnCode = 1; + } + } + + } else { // called with no arguments + usageMsg(); + returnCode = 1; + } + + return returnCode; +} + +// For the given string that the user specifies as attribute type +// in the command line, this function tries to figure out the +// corresponding Be API value +// +// On success, "result" will contain that value +// On failure, B_BAD_VALUE is returned and "result" is not modified +status_t typeForString( const char *attrString, type_code *result ) +{ + status_t returnCode; + + returnCode = B_OK; + + if( strcmp( attrString, "string" ) == 0 ){ + *result = B_STRING_TYPE; + } else if( strcmp( attrString, "mime" ) == 0 ){ + *result = B_MIME_STRING_TYPE; + } else if( strcmp( attrString, "int" ) == 0 ) { + *result = B_INT32_TYPE; + } else if( strcmp( attrString, "llong" ) == 0 ) { + *result = B_INT64_TYPE; + } else if( strcmp( attrString, "float" ) == 0 ) { + *result = B_FLOAT_TYPE; + } else if( strcmp( attrString, "double" ) == 0 ) { + *result = B_DOUBLE_TYPE; + } else if( strcmp( attrString, "bool" ) == 0 ) { + *result = B_BOOL_TYPE; + } else { + int convertedFields; + type_code tempCode; + + convertedFields = sscanf( attrString, "%lu", &tempCode ); + + if( convertedFields > 0 ) { + *result = tempCode; + } else { + returnCode = B_BAD_VALUE; + } + } + + return returnCode; +} + diff --git a/src/apps/bin/addattr/messages.cpp b/src/apps/bin/addattr/messages.cpp new file mode 100644 index 0000000000..22143e700f --- /dev/null +++ b/src/apps/bin/addattr/messages.cpp @@ -0,0 +1,34 @@ +// Author: Sebastian Nozzi +// Created: 3 may 2002 + +// Modifications: +// (please include author, date, and description) + +// mmu_man@sf.net: note the original one doesn't link to libbe + +#include + +// Keeps the complete name of this binary at run-time +// To be set at the beginning of the programm +char *completeToolName; + +// Predefined command line messages for the user + +void usageMsg() { + fprintf( stderr, "usage: %s [-t type] attr value file1 [file2...]\n", completeToolName); + 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\n"); + fprintf( stderr, "\tThe default is `string\'\n"); +} + +void invalidAttrMsg( const char *attrTypeName ) { + fprintf( stderr, "%s: attribute type %s is not valid\n",completeToolName, attrTypeName); + fprintf( stderr, "\tTry one of: string, mime, int, llong, float, double,\n"); + fprintf( stderr, "\t\tbool, or a \n"); +} + +void problemsWithFileMsg( const char *file ) +{ + fprintf( stderr, "%s: can\'t open file %s to add attribute\n", completeToolName, file ); +} diff --git a/src/apps/bin/addattr/messages.h b/src/apps/bin/addattr/messages.h new file mode 100644 index 0000000000..18f64c3096 --- /dev/null +++ b/src/apps/bin/addattr/messages.h @@ -0,0 +1,18 @@ +// Author: Sebastian Nozzi +// Created: 3 may 2002 + +// Modifications: +// (please include author, date, and description) + +// mmu_man@sf.net: note the original one doesn't link to libbe + +#ifndef _ADDATTR_MSG_H +#define _ADDATTR_MSG_H + +extern char *completeToolName; + +void usageMsg(); +void invalidAttrMsg( const char *attrTypeName ); +void problemsWithFileMsg( const char *file ); + +#endif \ No newline at end of file