Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

more closely match c xattr methods #3

Merged
merged 10 commits into from Jan 15, 2013
12 changes: 8 additions & 4 deletions README.md
Expand Up @@ -2,10 +2,6 @@


node-xattr is a native module wrapping xattr to read and set extended attributes on files. node-xattr is a native module wrapping xattr to read and set extended attributes on files.


## Install

npm install xattr

## Build ## Build


node-waf configure && node-waf build && node-waf install node-waf configure && node-waf build && node-waf install
Expand All @@ -16,11 +12,19 @@ node-waf configure && node-waf build && node-waf install


Get all the extended attributes on a file, returns obj Get all the extended attributes on a file, returns obj


var attrs = xattr.glist("/path/to/file");

Get just the extended attribute names on a file, returns array obj

var attrs = xattr.list("/path/to/file"); var attrs = xattr.list("/path/to/file");


Set an extended attribute on a file. Note at thie moment you can only set string values. Set an extended attribute on a file. Note at thie moment you can only set string values.


xattr.set("/path/to/file", "someAttribute", "someValue"); xattr.set("/path/to/file", "someAttribute", "someValue");


Remove xattr on a file, returns bool

xattr.remove("/path/to/file", "user.attribute");





119 changes: 109 additions & 10 deletions src/node_xattr.cc
Expand Up @@ -40,8 +40,8 @@ using namespace std;
return ThrowException(Exception::TypeError( \ return ThrowException(Exception::TypeError( \
String::New("Argument must be a string"))); \ String::New("Argument must be a string"))); \
String::AsciiValue VAR(args[I]); String::AsciiValue VAR(args[I]);

//toggle strict compatibility with c api

bool compat = false;


string ObjectToString(Local<Value> value) { string ObjectToString(Local<Value> value) {
String::AsciiValue ascii_value(value); String::AsciiValue ascii_value(value);
Expand Down Expand Up @@ -74,7 +74,7 @@ static Handle<Value> set(const Arguments& args) {
return Boolean::New(true); return Boolean::New(true);
} }


static Handle<Value> list(const Arguments& args) { static Handle<Value> glist(const Arguments& args) {
HandleScope scope; HandleScope scope;
char list[XATTR_SIZE],value[XATTR_SIZE]; char list[XATTR_SIZE],value[XATTR_SIZE];
const char *filename; const char *filename;
Expand All @@ -94,30 +94,129 @@ static Handle<Value> list(const Arguments& args) {
// create obj for return // create obj for return
Handle<Object> result = Object::New(); Handle<Object> result = Object::New();


if (listLen<1){
return result;
}

//for each of the attrs, do getxattr and add them as key/val to the obj //for each of the attrs, do getxattr and add them as key/val to the obj
for (ns=0; ns<listLen; ns+= strlen(&list[ns])+1){ for (ns=0; ns<listLen; ns+= strlen(&list[ns])+1){
#ifdef __APPLE__ #ifdef __APPLE__
valueLen = getxattr(filename, &list[ns],value, XATTR_SIZE, 0, 0); valueLen = getxattr(filename, &list[ns],value, XATTR_SIZE, 0, 0);
#else #else
valueLen = getxattr(filename, &list[ns],value, XATTR_SIZE); valueLen = getxattr(filename, &list[ns],value, XATTR_SIZE);
#endif #endif
//if (valueLen > 0){ if (valueLen > 0){
result->Set(String::New(&list[ns]),String::New(value, valueLen)); result->Set(String::New(&list[ns]),String::New(value, valueLen));
//} }
} }
return result; return result;
} }


static Handle<Value> get(const Arguments& args) {
HandleScope scope;
char *attr,value[XATTR_SIZE];
const char *filename;
const char *attribute;

ssize_t valueLen;
int ns;

//make sure we were passed a string
REQ_STR_ARG(0, s1);
filename= ObjectToString(s1).c_str();
REQ_STR_ARG(1, s2);
attribute= ObjectToString(s2).c_str();


// create obj for return
Handle<Object> result = Object::New();

//for each of the attrs, do getxattr and add them as key/val to the obj
#ifdef __APPLE__
valueLen = getxattr(filename, attribute,value, XATTR_SIZE, 0, 0);
#else
valueLen = getxattr(filename, attribute,value, XATTR_SIZE);
#endif
result->Set(String::New(attribute),String::New(value,valueLen));

return result;
}

static Handle<Value> clist(const Arguments& args) {
HandleScope scope;
char list[XATTR_SIZE];
const char *filename;
ssize_t listLen;
int ns;

//make sure we were passed a string
REQ_STR_ARG(0, s);
filename= ObjectToString(s).c_str();

//get all the extended attributes on filename
#ifdef __APPLE__
listLen = listxattr(filename,list,XATTR_SIZE,0);
#else
listLen = listxattr(filename,list,XATTR_SIZE);
#endif
// create obj for return
Handle<Object> result = Object::New();

//for each of the attrs, do getxattr and add them as key/val to the obj
int nc=0;
for (ns=0; ns<listLen; ns+= strlen(&list[ns])+1){
nc++;
result->Set(nc,String::New(&list[ns]));
}
return result;
}
static Handle<Value> remove(const Arguments& args) {
HandleScope scope;
ssize_t res;
int valLen;

REQ_ASCII_ARG(0,filename);
REQ_ASCII_ARG(1,attribute);
#ifdef __APPLE__
res = removexattr(*filename, *attribute,0);
#else
res = removexattr(*filename, *attribute);
#endif
//printf("Setting file: %s, attribute: %s, value: %s, length: %d\n", *filename, *attribute, *val,val.length());


//Error
if (res == -1){
return ThrowException(Exception::TypeError( \
String::Concat(String::New("Error removing extended attribue: "), String::New(strerror(errno)))));
}

return Boolean::New(true);
}

static Handle<Value> list(const Arguments& args){
if(compat)
return(clist(args));
else
return(glist(args));
}



static Handle<Value> ccompat(const Arguments& args){
HandleScope scope;
if(args[0]->IsBoolean())
compat = args[0]->ToBoolean()->Value();
return(Boolean::New(compat));
}

extern "C" { extern "C" {


void init (Handle<Object> target) void init (Handle<Object> target)
{ {
NODE_SET_METHOD(target, "list", list); NODE_SET_METHOD(target, "list", list);
NODE_SET_METHOD(target, "clist", clist);
NODE_SET_METHOD(target, "glist", glist);
NODE_SET_METHOD(target, "set", set); NODE_SET_METHOD(target, "set", set);
NODE_SET_METHOD(target, "get", get);
NODE_SET_METHOD(target, "remove", remove);
NODE_SET_METHOD(target, "ccompat", ccompat);
} }


NODE_MODULE(xattr, init); NODE_MODULE(xattr, init);
Expand Down
2 changes: 1 addition & 1 deletion test/test.js
Expand Up @@ -41,7 +41,7 @@ function runTest(runs){




function check() { function check() {
var data = xattr.list(filename); var data = xattr.glist(filename);


for (var i = 0; i<4; i++){ for (var i = 0; i<4; i++){
if (data["user.p"+i] != vals["v" + i]){ if (data["user.p"+i] != vals["v" + i]){
Expand Down
1 change: 0 additions & 1 deletion test/utils.js
Expand Up @@ -6,7 +6,6 @@ var filename = "/tmp/xattr.test";
//var filename = "/opt/solr_index/perfTest/xattr.test"; //var filename = "/opt/solr_index/perfTest/xattr.test";
//var filename = "/var/glusterfs/galaxy/galaxy_0/testDir/xattr.test"; //var filename = "/var/glusterfs/galaxy/galaxy_0/testDir/xattr.test";
//var filename = "/var/glusterfs/polyomic/polyomic_0/testDir/xattr.test"; //var filename = "/var/glusterfs/polyomic/polyomic_0/testDir/xattr.test";
var filename = "/storage/testDir/xattr.test";


exports.createFile=function(index, cb){ exports.createFile=function(index, cb){
if (index){ if (index){
Expand Down