Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Copyright 2009 Ryan Dahl <ry@tinyclouds.org>
- #include <v8.h>
- #include <node.h>
- #include <node_os.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <assert.h>
- #include <string.h>
- #include <errno.h>
- #include <limits.h>
- #include <pwd.h> /* getpwuid() */
- #include <grp.h> /* getgrgid() */
- namespace node {
- using namespace v8;
- // User
- static Persistent<String> username_symbol;
- static Persistent<String> password_symbol;
- static Persistent<String> uid_symbol;
- static Persistent<String> gid_symbol;
- static Persistent<String> class_symbol;
- static Persistent<String> dir_symbol;
- static Persistent<String> shell_symbol;
- static Persistent<String> change_symbol;
- static Persistent<String> expire_symbol;
- static Persistent<String> gecos_symbol;
- static Persistent<String> fields_symbol;
- // Group
- // static Persistent<String> name_symbol;
- // static Persistent<String> members_symbol;
- // Buffer for getpwnam_r(), getgrpam_r(); keep this scoped at file-level rather
- // than method-level to avoid excess stack usage.
- static char getbuf[1024];
- /*-----------------------------------------------
- Constructs a JS::Object from a *passwd
- -----------------------------------------------*/
- Local<Object> BuildUserObject(struct passwd *u) {
- HandleScope scope;
- if (username_symbol.IsEmpty()) {
- username_symbol = NODE_PSYMBOL("username");
- password_symbol = NODE_PSYMBOL("password");
- uid_symbol = NODE_PSYMBOL("uid");
- gid_symbol = NODE_PSYMBOL("gid");
- class_symbol = NODE_PSYMBOL("class");
- gecos_symbol = NODE_PSYMBOL("gecos");
- dir_symbol = NODE_PSYMBOL("dir");
- shell_symbol = NODE_PSYMBOL("shell");
- change_symbol = NODE_PSYMBOL("change");
- expire_symbol = NODE_PSYMBOL("expire");
- }
- Local<Object> user = Object::New();
- user->Set(username_symbol, String::New(u->pw_name));
- user->Set(password_symbol, String::New(u->pw_passwd));
- user->Set(uid_symbol, Integer::New(u->pw_uid));
- user->Set(gid_symbol, Integer::New(u->pw_gid));
- user->Set(class_symbol, String::New(u->pw_class));
- user->Set(gecos_symbol, String::New(u->pw_gecos));
- user->Set(dir_symbol, String::New(u->pw_dir));
- user->Set(shell_symbol, String::New(u->pw_shell));
- user->Set(change_symbol, Undefined()); //atldate(u->pw_change/1000));
- user->Set(expire_symbol, Undefined());
- return scope.Close(user);
- }
- struct custom_request {
- int type; // 0 is with uid, 1 is with uname
- int uid;
- char *uname;
- void *cb;
- struct passwd result;
- };
- static int EIO_AfterGetUser(eio_req *req) {
- }
- static int EIO_GetUser(eio_req *req) {
- struct custom_request *creq = (struct custom_request *)(req->data);
- struct passwd pwd, *pwdp = NULL;
- int err;
- if(creq->type == 0){
- if ((err = getpwuid_r(creq->uid, &pwd, getbuf, sizeof(getbuf), &pwdp)) || pwdp == NULL) {
- req->errorno = errno;
- }
- memcpy(&creq->result, pwdp, sizeof(struct passwd));
- } else {
- if ((err = getpwnam_r(creq->uname, &pwd, getbuf, sizeof(getbuf), &pwdp)) ||
- pwdp == NULL) {
- req->errorno = errno;
- }
- memcpy(&creq->result, pwdp, sizeof(struct passwd));
- }
- return 0;
- }
- static Handle<Value> GetUser(const Arguments& args) {
- HandleScope scope;
- if ( args.Length() < 1) {
- return THROW_BAD_ARGS;
- }
- if (args[1]->IsFunction()) {
- struct custom_request *creq = (struct custom_request *)
- calloc(1, sizeof(struct custom_request)+32);
- if (!creq) {
- V8::LowMemoryNotification();
- return ThrowException(Exception::Error(
- String::New("Could not allocate enough memory")));
- }
- if (args[0]->IsInt32()) {
- creq->uid = args[0]->Int32Value();
- creq->type = 0;
- } else {
- String::Utf8Value pwnam(args[0]->ToString());
- creq->uname = strdup(*pwnam);
- creq->type = 1;
- }
- creq->cb = cb_persist(args[1]);
- //ASYNC_CUSTOM_CALL(blocking_func, callback, data);
- ASYNC_CUSTOM_CALL(EIO_GetUser, EIO_AfterGetUser, creq);
- return Undefined();
- } else {
- struct passwd pwd, *pwdp = NULL;
- int err;
- if (args[0]->IsInt32()) {
- if ((err = getpwuid_r(args[0]->Int32Value(), &pwd, getbuf, sizeof(getbuf), &pwdp)) ||
- pwdp == NULL) {
- return ThrowException(ErrnoException(errno, "getpwuid_r"));
- }
- } else {
- String::Utf8Value pwnam(args[0]->ToString());
- if ((err = getpwnam_r(*pwnam, &pwd, getbuf, sizeof(getbuf), &pwdp)) ||
- pwdp == NULL) {
- return ThrowException(ErrnoException(errno, "getpwnam_r"));
- }
- }
- return scope.Close(BuildUserObject(*&pwdp));
- }
- }
- /*
- Local<Object> BuildGroupObject(struct group *g) {
- HandleScope scope;
- if (name_symbol.IsEmpty()) {
- name_symbol = NODE_PSYMBOL("name");
- password_symbol = NODE_PSYMBOL("password");
- gid_symbol = NODE_PSYMBOL("gid");
- members_symbol = NODE_PSYMBOL("members");
- }
- Local<Object> group = Object::New();
- group->Set(name_symbol, String::New(g->gr_name));
- group->Set(password_symbol, String::New(g->gr_passwd));
- group->Set(gid_symbol, Integer::New(g->gr_gid));
- // group->Set(members_symbol, String::New(g->gr_mem[1]));
- return scope.Close(group);
- }
- static Handle<Value> GetGroup(const Arguments& args) {
- HandleScope scope;
- if ( args.Length() < 1) {
- return THROW_BAD_ARGS;
- }
- if (args[1]->IsFunction()) {
- // Handle with EIO_CUSTOM
- return Undefined();
- } else {
- if (args[0]->IsString()) {
- String::Utf8Value grpnam(args[0]->ToString());
- struct group grp, *grpp = NULL;
- int err;
- if ((err = getgrnam_r(*grpnam, &grp, getbuf, sizeof(getbuf), &grpp)) ||
- grpp == NULL) {
- return ThrowException(ErrnoException(errno, "getgrnam_r"));
- }
- //uid = (pwdp->pw_uid);
- return scope.Close(BuildGroupObject(*&grpp));
- } else {
- return Undefined();
- }
- }
- }
- */
- void Os::Initialize(Handle<Object> target) {
- HandleScope scope;
- NODE_SET_METHOD(target, "getUser", GetUser);
- // NODE_SET_METHOD(target, "getGroup", GetGroup);
- }
- } // end namespace node
Add Comment
Please, Sign In to add comment