/** * @function net.listen * * ### Synopsis * * var sock = net.listen(port); * var sock = net.listen(port, backlog); * var sock = net.listen(port, backlog, ip); * * This function creates a TCP SOCK_STREAM socket, binds it to the specified port, and does a listen(2) on the socket. * * Connections to the socket from the outside world can be accepted via net.accept(). * * The backlog argument specifies the maximum length for the queue of pending connections. If the queue fills and another connection attempt is made, the client will likely receive a "connection refused" error. * * The ip argument specifies what IP address to listen on. By default, it will be 0.0.0.0 for "listen on any IP." If you set this to a different value, only that IP will be listened on, and the socket will not be reachable via localhost (for example). * * @param {int} port - port number to listen on * @param {int} backlog - length of pending connection queue * @param {string} ip - ip address to listen on * @return {int} sock - file descriptor of socket in listen mode * * ### Exceptions * This function throws an exception of the socket(), bind(), or listen() OS calls fail. */ static JSVAL net_listen (JSARGS args) { int port = args[0]->IntegerValue(); int backlog = 30; if (args.Length() > 1) { backlog = args[1]->IntegerValue(); } int listenAddress = INADDR_ANY; // char *listenAddressString = (char *)"0.0.0.0"; if (args.Length() > 2) { String::AsciiValue addr(args[2]); // listenAddressString = *addr; listenAddress = inet_addr(*addr); } int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { return ThrowException(String::Concat(String::New("socket() Error: "), String::New(strerror(errno)))); } { int on = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)); } struct sockaddr_in my_addr; bzero(&my_addr, sizeof (my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(port); // printf("listenAddress: '%s' %08x\n", listenAddressString, listenAddress); my_addr.sin_addr.s_addr = listenAddress; // htonl(listenAddress); if (bind(sock, (struct sockaddr *) &my_addr, sizeof (my_addr))) { return ThrowException(String::Concat(String::New("bind()Error: "), String::New(strerror(errno)))); } if (listen(sock, backlog)) { return ThrowException(String::Concat(String::New("listen() Error: "), String::New(strerror(errno)))); } return Integer::New(sock); }
/** * writeFile(path, data, size [,mode=0644]) * @param args * @return */ static JSVAL fs_writefile(JSARGS args) { HandleScope scope; String::Utf8Value path(args[0]->ToString()); String::Utf8Value data(args[1]->ToString()); ssize_t size; if (args.Length() > 2) { size = args[2]->IntegerValue(); } else { size = strlen(*data); } mode_t mode = 0644; if (args.Length() > 3) { mode = args[3]->IntegerValue(); } int fd = open(*path, O_WRONLY | O_CREAT | O_TRUNC, mode); if (fd == -1) { return scope.Close(False()); } if (write(fd, *data, size) != size) { close(fd); return scope.Close(False()); } close(fd); return scope.Close(True()); }
/** * @function net.sendfile * * ### Synopsis * * net.sendFile(sock, path); * net.sendFile(sock, path, offset); * net.sendFile(sock, path, offset, size); * * This function calls the OS sendfile() function to send a complete or partial file to the network entirely within kernel space. It is a HUGE speed win for HTTP and FTP type servers. * * @param {int} sock - file descriptor of socket to send the file to. * @param {string} path - file system path to file to send. * @param {int} offset - offset from beginning of file to send (for partial). If omitted, the entire file is sent. * @param {int} size - number of bytes of the file to send. If omitted, the remainder of the file is sent (or all of it). * * ### Exceptions * An exception is thrown if the file cannot be opened or if there is a sendfile(2) OS call error. */ static JSVAL net_sendfile (JSARGS args) { HandleScope handle_scope; int sock = args[0]->IntegerValue(); String::AsciiValue filename(args[1]); off_t offset = 0; if (args.Length() > 2) { offset = args[2]->IntegerValue(); } size_t size; if (args.Length() > 3) { size = args[3]->IntegerValue(); } else { struct stat buf; if (stat(*filename, &buf)) { printf("%s\n", *filename); perror("SendFile stat"); return False(); } size = buf.st_size - offset; } int fd = open(*filename, O_RDONLY); if (fd < 0) { return ThrowException(String::Concat(String::New("sendFile open Error: "), String::New(strerror(errno)))); } while (size > 0) { #ifdef __APPLE__ off_t count = size; if (sendfile(fd, sock, offset, &count, NULL, 0) == -1) { close(fd); return ThrowException(String::Concat(String::New("sendFile Error: "), String::New(strerror(errno)))); } #else ssize_t count = sendfile(sock, fd, &offset, size); if (count == -1) { close(fd); return ThrowException(String::Concat(String::New("sendFile Error: "), String::New(strerror(errno)))); } #endif size -= count; offset += count; } close(fd); int flag = 0; setsockopt(fd, IPPROTO_TCP, TCP_CORK, &flag, sizeof (flag)); flag = 1; setsockopt(fd, IPPROTO_TCP, TCP_CORK, &flag, sizeof (flag)); return Undefined(); }
static JSVAL list_fields(JSARGS args) { HandleScope scope; MYSQL *handle = (MYSQL *) args[0]->IntegerValue(); const char *table = NULL; const char *wild = NULL; if (args.Length() > 1) { String::Utf8Value tbl(args[1]->ToString()); table = *tbl; } if (args.Length() > 2) { String::Utf8Value pat(args[1]->ToString()); wild = *pat; } return scope.Close(Integer::New((unsigned long)mysql_list_fields(handle, table, wild))); }
/** * @function memcached.append * * ### Synopsis * * var rc = memcached.append(handle, key, value); * var rc = memcached.append(handle, key, value, expiration); * var rc = memcached.append(handle, key, value, expiration, flags); * * Appends the given value string to the value of an existing item. * * If an object identified by key does not exist, an error occurs. * * @param {object} handle - handle to memcached connection. * @param {string} key - key of data to set in memcached. * @param {string} value - value of data to append in memcached. * @param {int} expiration - length of time value is valid (after this it will be removed from memcached automatically). * @param {int} flags - user defined integer value stored along with the value. * @return {int} rc - result code; 0 if no error, otherwise the error code. */ JSVAL _memcached_append (JSARGS args) { HandleScope scope; M *handle = HANDLE(args[0]); String::Utf8Value key(args[1]); String::Utf8Value value(args[2]); time_t expiration = 0; if (args.Length() > 3) { expiration = args[3]->IntegerValue(); } uint32_t flags = 0; if (args.Length() > 4) { flags = args[4]->IntegerValue(); } return scope.Close(Integer::New(memcached_append(handle, *key, strlen(*key), *value, strlen(*value), expiration, flags))); }
JSVAL connect(JSARGS args) { HandleScope scope; String::AsciiValue host(args[0]->ToString()); String::AsciiValue user(args[1]->ToString()); String::AsciiValue passwd(args[2]->ToString()); String::AsciiValue db(args[3]->ToString()); int port = 3306; if (args.Length() > 4) { port = args[4]->IntegerValue(); } if (!handle) { handle = mysql_init(NULL); // handle = mysql_real_connect(handle, "localhost", "mschwartz", "", "sim", 3306, NULL, 0); handle = mysql_real_connect(handle, *host, *user, *passwd, *db, port, NULL, 0); if (!handle) { printf("MYSQL ERROR '%d'\n", mysql_errno(handle)); return False(); } currentDb = strdup(*db); my_bool reconnect = 1; mysql_options(handle, MYSQL_OPT_RECONNECT, &reconnect); } else if (strcmp(*db, currentDb)) { if (mysql_select_db(handle, *db)) { return ThrowException(Exception::Error(String::New(mysql_error(handle)))); } delete [] currentDb; currentDb = strdup(*db); } mysql_ping(handle); return Undefined(); }
/** * @function ssh.writeFile * * ### Synopsis * * var status = ssh.writeFile(handle, srcPath, dstPath); * var status = ssh.writeFile(handle, srcPath, dstPath, mode); * * Write file to remote server via SCP. * * @param {object} handle - opaque handle to already open SSH2 connection. * @param {string} srcPath - path to file in local file system to send. * @param {string} dstPath - path to file in remote file system to create. * @param {int} mode - desired resulting file permissions of file on remote end. * @return {boolean} success - true if the transfer succeeded, string error message if transfer failed. * * ### Note * If mode is not provided, the file mode of the file being sent will be used. */ static JSVAL ssh2_scp_send(JSARGS args) { HandleScope scope; SSH2 *ssh2 = HANDLE(args[0]); String::Utf8Value srcPath(args[1]); String::Utf8Value dstPath(args[2]); int mode; struct stat fileinfo; if (stat(*srcPath, &fileinfo) != 0) { return scope.Close(String::New(strerror(errno))); } if (args.Length() > 3) { mode = args[3]->IntegerValue(); } else { mode = fileinfo.st_mode; } mode &= 0777; int fd = open(*srcPath, O_RDONLY); if (fd < 0) { return scope.Close(String::New(strerror(errno))); } #ifdef libssh2_scp_send64 LIBSSH2_CHANNEL *channel = libssh2_scp_send64(ssh2->mSession, *dstPath, mode, fileinfo.st_size, 0, 0); #else LIBSSH2_CHANNEL *channel = libssh2_scp_send(ssh2->mSession, *dstPath, mode, fileinfo.st_size); #endif if (!channel) { char *errmsg; int errlen; libssh2_session_last_error(ssh2->mSession, &errmsg, &errlen, 0); return scope.Close(String::New(errmsg, errlen)); } char mem[1024]; ssize_t toWrite = fileinfo.st_size; while (toWrite > 0) { ssize_t nRead = read(fd, mem, 1024); if (nRead < 0) { int eNum = errno; libssh2_channel_free(channel); close(fd); return scope.Close(String::New(strerror(eNum))); } int rc = libssh2_channel_write(channel, mem, nRead); if (rc < 0) { char *errmsg; int errlen; libssh2_session_last_error(ssh2->mSession, &errmsg, &errlen, 0); libssh2_channel_free(channel); close(fd); return scope.Close(String::New(errmsg)); } toWrite -= nRead; } close(fd); libssh2_channel_free(channel); return scope.Close(True()); }
/** * @function memcached.flush * * ### Synopsis * * var rc = memcached.flush(handle); * var rc = memcached.flush(handle, expiration); * * Wipe clean the contents of memcached servers. It will either do this immediately or expire the content based on the expiration time passed to the method (a value of zero causes an immediate flush). The operation is not atomic to multiple servers, just atomic to a single server. That is, it will flush the servers in the order that they were added. * * @param {object} handle - handle to memcached connection. * @param {int} expiration - length of time value is valid (after this it will be removed from memcached automatically). * @return {int} rc - result code; 0 if no error, otherwise the error code. */ JSVAL _memcached_flush (JSARGS args) { HandleScope scope; M *handle = HANDLE(args[0]); time_t expiration = 0; if (args.Length() > 1) { expiration = args[1]->IntegerValue(); } return scope.Close(Integer::New(memcached_flush(handle, expiration))); }
/** * @function memcached.remove * * ### Synopsis * * var rc = memcached.remove(handle, key); * * Remove an item from memcached by key. * * @param {object} handle - handle to memcached connection. * @param {string} key - key of data to set in memcached. * @return {int} rc - result code; 0 if no error, otherwise the error code. */ JSVAL _memcached_remove (JSARGS args) { HandleScope scope; M *handle = HANDLE(args[0]); String::Utf8Value key(args[1]); time_t expiration = 0; if (args.Length() > 2) { expiration = args[2]->IntegerValue(); } return scope.Close(Integer::New(memcached_delete(handle, *key, strlen(*key), expiration))); }
static JSVAL fs_mkdir(JSARGS args) { HandleScope scope; String::Utf8Value path(args[0]->ToString()); mode_t mode = 0700; if (args.Length() > 1) { mode = args[1]->IntegerValue(); } if (mkdir(*path, mode) == -1) { return scope.Close(False()); } return scope.Close(True()); }
/** * @function ssh.connect * * ### Synopsis * * var conn = ssh.connect(host, username, password); * var conn = ssh.connect(host, username, password, port); * * Connect to a remote host via SSH. * * @param {string} host - name of remote host. * @param {string} username - username for password authentication at remote host. * @param {string} password - password for authentication at remote host. * @param {int} port - SSH port at remote host (defaults to 21).. * @return {object} conn - connection ready to use for other methods. */ static JSVAL ssh2_connect(JSARGS args) { HandleScope scope; String::Utf8Value host(args[0]); String::Utf8Value username(args[1]); String::Utf8Value password(args[2]); int port = 22; if (args.Length() > 3) { port = args[3]->IntegerValue(); } SSH2 *ssh2 = new SSH2(*host, *username, *password, port); return scope.Close(External::New(ssh2)); }
/** * @function SFTP.mkdir * * ### Synopsis * * var success = SFTP.mkdir(handle, path, mode); * * Make a directory on the remote host. * * @param {object} handle - opaque handle to existing SFTP connection (already connected). * @param {string} path - path on remote server to create. * @returns {boolean} success - true if directory was created. */ JSVAL sftp_mkdir (JSARGS args) { HandleScope scope; SFTP *handle = HANDLE(args[0]); String::Utf8Value path(args[1]); int mode = 0755; if (args.Length() > 2) { mode = args[2]->IntegerValue(); } if (libssh2_sftp_mkdir(handle->sftp_session, *path, mode)) { return scope.Close(String::New("Could not create directory")); } return scope.Close(True()); }
static JSVAL connect(JSARGS args) { char *host = strdup("127.0.0.1"); int port = 6379; if (args.Length() > 0) { free(host); String::Utf8Value _host(args[0]->ToString()); host = strdup(*_host); } if (args.Length() > 1) { port = args[1]->IntegerValue(); } struct timeval timeout = { 1, 500000}; // 1.5 seconds redisContext *c = redisConnectWithTimeout(host, port, timeout); if (c->err) { printf("connect error %s %d - %s\n", host, port, c->errstr); Handle<String> s = String::New(c->errstr); redisFree(c); free(host); return ThrowException(String::Concat(String::New("Redis connect error: "), s)); } free(host); return Opaque::New(c); }
/** * @function SFTP.writeFile * * ### Synopsis * * var status = SFTP.writeFile(handle, srcPath, dstPath); * var status = SFTP.writeFile(handle, srcPath, dstPath, mode); * * Write file to remote server via SFTP. * * @param {object} handle - opaque handle to already open SFTP connection. * @param {string} srcPath - path to file in local file system to send. * @param {string} dstPath - path to file in remote file system to create. * @param {int} mode - desired resulting file permissions of file on remote end. * @return {boolean} success - true if the transfer succeeded. * * ### Note * If mode is not provided, the file mode of the file being sent will be used. */ static JSVAL sftp_writeFile (JSARGS args) { HandleScope scope; SFTP *handle = HANDLE(args[0]); String::Utf8Value srcPath(args[1]); String::Utf8Value dstPath(args[2]); int mode; struct stat fileinfo; if (stat(*srcPath, &fileinfo) != 0) { return scope.Close(String::New(strerror(errno))); } if (args.Length() > 3) { mode = args[3]->IntegerValue(); } else { mode = fileinfo.st_mode; } mode &= 0777; int fd = open(*srcPath, O_RDONLY); if (fd < 0) { return scope.Close(String::New(strerror(errno))); } LIBSSH2_SFTP_HANDLE *sftp_handle = libssh2_sftp_open(handle->sftp_session, *dstPath, LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC, mode); char mem[1024]; ssize_t toWrite = fileinfo.st_size; while (toWrite > 0) { ssize_t nRead = read(fd, mem, 1024); if (nRead < 0) { int eNum = errno; libssh2_sftp_close(sftp_handle); close(fd); errno = eNum; return scope.Close(False()); } int rc = libssh2_sftp_write(sftp_handle, mem, nRead); if (rc < 0) { libssh2_sftp_close(sftp_handle); close(fd); return scope.Close(False()); } toWrite -= nRead; } close(fd); libssh2_sftp_close(sftp_handle); return scope.Close(True()); }
static JSVAL popen_gets (JSARGS args) { HandleScope scope; FILE *fp = (FILE *) JSEXTERN(args[0]); int size = 4096; if (args.Length() > 1) { size = args[1]->IntegerValue(); } char *buf = new char[size]; char *result = fgets(buf, size, fp); if (!result) { delete [] buf; return scope.Close(False()); } Handle<String>s = String::New(buf); delete [] buf; return scope.Close(s); }
/** * @function logfile.write * * ### Synopsis * * logfile.write(handle, s); * logfile.write(handle, s, len); * * Write a string to the log file. * * The string is appended to the shared memory block. The memory block is first flushed to disk if there is not enough room for the string. * * @param {object} handle - handle of the log file. * @param {string} s - string to write to the log file. * @param {int} len - optional length of string to write; defaults to strlen(s). * */ static JSVAL logfile_write (JSARGS args) { STATE *state = HANDLE(args[0]); String::AsciiValue buf(args[1]); int len; if (args.Length() > 2) { len = args[2]->IntegerValue(); } else { len = strlen(*buf); } lock_logfile(state); if (*state->length + len >= LOGFILE_CHUNK_SIZE) { flush_logfile(state); } memcpy(&state->logBuffer[*state->length], *buf, len); *state->length += len; unlock_logfile(state); return Undefined(); }
/** * writeFile(path, data, size [,mode=0644]) * @param args * @return */ static JSVAL fs_writefile64(JSARGS args) { HandleScope scope; String::Utf8Value path(args[0]->ToString()); String::Utf8Value data(args[1]->ToString()); mode_t mode = 0644; if (args.Length() > 2) { mode = args[2]->IntegerValue(); } string out = Base64Decode(*data); int fd = open(*path, O_WRONLY | O_CREAT | O_TRUNC, mode); if (fd == -1) { return scope.Close(False()); } ssize_t size = out.size(); if (write(fd, out.c_str(), size) != size) { close(fd); return scope.Close(False()); } close(fd); return scope.Close(True()); }
/** * @function net.sendfile * * ### Synopsis * * net.sendFile(sock, path); * net.sendFile(sock, path, offset); * net.sendFile(sock, path, offset, size); * * This function calls the OS sendfile() function to send a complete or partial file to the network entirely within kernel space. It is a HUGE speed win for HTTP and FTP type servers. * * @param {int} sock - file descriptor of socket to send the file to. * @param {string} path - file system path to file to send. * @param {int} offset - offset from beginning of file to send (for partial). If omitted, the entire file is sent. * @param {int} size - number of bytes of the file to send. If omitted, the remainder of the file is sent (or all of it). * * ### Exceptions * An exception is thrown if the file cannot be opened or if there is a sendfile(2) OS call error. */ static JSVAL net_sendfile (JSARGS args) { HandleScope handle_scope; int sock = args[0]->IntegerValue(); String::AsciiValue filename(args[1]); off_t offset = 0; if (args.Length() > 2) { offset = args[2]->IntegerValue(); } size_t size; if (args.Length() > 3) { size = args[3]->IntegerValue(); } else { struct stat buf; if (stat(*filename, &buf)) { printf("%s\n", *filename); perror("SendFile stat"); { FILE* fp=fopen("c:\\error.txt", "a+b"); fprintf(fp, "%d", __LINE__); fclose(fp); } return handle_scope.Close(False()); } size = buf.st_size - offset; } #ifdef WIN32 HANDLE fd = CreateFile(*filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL); if (fd == INVALID_HANDLE_VALUE) { #else int fd = open(*filename, O_RDONLY); if (fd < 0) { #endif return ThrowException(String::Concat(String::New("sendFile open Error: "), String::New(strerror(errno)))); } while (size > 0) { #ifdef __APPLE__ off_t count = size; if (sendfile(fd, sock, offset, &count, NULL, 0) == -1) { close(fd); return ThrowException(String::Concat(String::New("sendFile Error: "), String::New(strerror(errno)))); } #else #ifdef WIN32 SetFilePointer(fd, offset, NULL, FILE_BEGIN); TransmitFile(sock, fd, size, 0, NULL, NULL,0); ssize_t count = size; if (count == -1) { CloseHandle(fd); return ThrowException(String::Concat(String::New("sendFile Error: "), String::New(strerror(errno)))); } #else ssize_t count = sendfile(sock, fd, &offset, size); if (count == -1) { close(fd); return ThrowException(String::Concat(String::New("sendFile Error: "), String::New(strerror(errno)))); } #endif #endif size -= count; offset += count; } #ifdef WIN32 CloseHandle(fd); int flag = 0; setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof (flag)); flag = 1; setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof (flag)); #else close(fd); int flag = 0; setsockopt(fd, IPPROTO_TCP, TCP_CORK, &flag, sizeof (flag)); flag = 1; setsockopt(fd, IPPROTO_TCP, TCP_CORK, &flag, sizeof (flag)); #endif return Undefined(); } void init_net_object () { HandleScope scope; Handle<ObjectTemplate>net = ObjectTemplate::New(); net->Set(String::New("connect"), FunctionTemplate::New(net_connect)); net->Set(String::New("listen"), FunctionTemplate::New(net_listen)); net->Set(String::New("accept"), FunctionTemplate::New(net_accept)); net->Set(String::New("remote_addr"), FunctionTemplate::New(net_remote_addr)); net->Set(String::New("cork"), FunctionTemplate::New(net_cork)); net->Set(String::New("close"), FunctionTemplate::New(net_close)); net->Set(String::New("read"), FunctionTemplate::New(net_read)); net->Set(String::New("write"), FunctionTemplate::New(net_write)); net->Set(String::New("writeBuffer"), FunctionTemplate::New(net_writebuffer)); net->Set(String::New("sendFile"), FunctionTemplate::New(net_sendfile)); net->Set(String::New("duplicateSocket"), FunctionTemplate::New(net_duplicateSocket)); net->Set(String::New("getSocketDescriptor"), FunctionTemplate::New(net_getSocketDescriptor)); builtinObject->Set(String::New("net"), net); }
/** * @function net.listen * * ### Synopsis * * var sock = net.listen(port); * var sock = net.listen(port, backlog); * var sock = net.listen(port, backlog, ip); * * This function creates a TCP SOCK_STREAM socket, binds it to the specified port, and does a listen(2) on the socket. * * Connections to the socket from the outside world can be accepted via net.accept(). * * The backlog argument specifies the maximum length for the queue of pending connections. If the queue fills and another connection attempt is made, the client will likely receive a "connection refused" error. * * The ip argument specifies what IP address to listen on. By default, it will be 0.0.0.0 for "listen on any IP." If you set this to a different value, only that IP will be listened on, and the socket will not be reachable via localhost (for example). * * @param {int} port - port number to listen on * @param {int} backlog - length of pending connection queue * @param {string} ip - ip address to listen on * @return {int} sock - file descriptor of socket in listen mode * * ### Exceptions * This function throws an exception of the socket(), bind(), or listen() OS calls fail. */ static JSVAL net_listen (JSARGS args) { HandleScope scope; int port = args[0]->IntegerValue(); int backlog = 30; if (args.Length() > 1) { backlog = args[1]->IntegerValue(); } int listenAddress = INADDR_ANY; #ifdef WIN32 char *listenAddressString = (char *)"0.0.0.0"; WSADATA wsaData = {0}; int iResult = 0; int sock = INVALID_SOCKET; int iFamily = AF_UNSPEC; int iType = 0; int iProtocol = 0; iFamily = AF_INET; iType = SOCK_STREAM; iProtocol = 0; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { char str_ret[128]; scanf(str_ret, L"%d\n", iResult); return ThrowException(String::Concat(String::New("socket() Error: "), String::New(str_ret))); } #else char *listenAddressString = (char *)'0.0.0.0'; #endif if (args.Length() > 2) { String::AsciiValue addr(args[2]); listenAddressString = *addr; listenAddress = inet_addr(*addr); } #ifdef WIN32 sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { char str_int[128]; scanf(str_int, "%d", 0); return ThrowException(String::Concat(String::New("socket() Error: "), String::New(str_int))); } #else int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { return ThrowException(String::Concat(String::New("socket() Error: "), String::New(strerror(errno)))); } #endif { int on = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)); } struct sockaddr_in my_addr; #ifdef WIN32 memset(&my_addr, 0, sizeof(my_addr)); #else bzero(&my_addr, sizeof (my_addr)); #endif my_addr.sin_family = AF_INET; my_addr.sin_port = htons(port); // printf("listenAddress: '%s' %08x\n", listenAddressString, listenAddress); my_addr.sin_addr.s_addr = listenAddress; // htonl(listenAddress); if (bind(sock, (struct sockaddr *) &my_addr, sizeof (my_addr))) { return ThrowException(String::Concat(String::New("bind()Error: "), String::New(strerror(errno)))); } if (listen(sock, backlog)) { return ThrowException(String::Concat(String::New("listen() Error: "), String::New(strerror(errno)))); } return scope.Close(Integer::New(sock)); }
/** * @function SFTP.connect * * ### Synopsis * * var handle = SFTP.connect(host, username, password); * var handle = SFTP.connect(host, username, password, port); * * Create an SFTP connection to a remote host and log in. * * @param {string} host - name of host to connect to. * @param {string} username - name of user on remote host to log in as. * @param {string} password - password for user on remote host. * @param {int} port - port to connect to on remote host. Default is port #21. * * @return {object} handle - handle to use with other SFTP methods. */ static JSVAL sftp_connect (JSARGS args) { HandleScope scope; String::AsciiValue host(args[0]); String::AsciiValue username(args[1]); String::AsciiValue password(args[2]); int port = 22; if (args.Length() > 3) { port = args[3]->IntegerValue(); } struct hostent *hp = gethostbyname(*host); if (!hp) { return scope.Close(String::New("Failed to get IP address of server")); } struct sockaddr_in s; s.sin_addr = *(struct in_addr *) hp->h_addr_list[0]; s.sin_family = hp->h_addrtype; s.sin_port = htons(port); int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { char msg[4096]; sprintf(msg, "Failed to create socket: %s", strerror(errno)); return scope.Close(String::New(msg)); } if (connect(sock, (struct sockaddr *) &s, sizeof (s)) < 0) { char msg[4096]; sprintf(msg, "Failed to connect: %s", strerror(errno)); close(sock); return scope.Close(String::New(msg)); } LIBSSH2_SESSION *session = libssh2_session_init(); if (!session) { close(sock); return scope.Close(String::New("Could not initialize SSH2 session")); } if (libssh2_session_startup(session, sock)) { close(sock); sock = -1; return scope.Close(String::New("Could not initialize SSH2 session")); } libssh2_session_set_blocking(session, 1); if (libssh2_userauth_password(session, *username, *password)) { close(sock); libssh2_session_free(session); return scope.Close(String::New("Invalid credentials")); } LIBSSH2_SFTP *sftp = libssh2_sftp_init(session); if (!sftp) { char *errmsg; int errlen; libssh2_session_last_error(session, &errmsg, &errlen, 0); libssh2_session_free(session); close(sock); return scope.Close(String::New(errmsg)); } SFTP *p = new SFTP; p->sock = sock; p->session = session; p->sftp_session = sftp; return scope.Close(External::New(p)); }