/** * Handle a call to gethostbyname() made by JavaScript. * * gethostbyname expects 1 parameter: * 0: The name of the host to look up. * on success, gethostbyname returns a result in |output|: * 0: "gethostbyname" * 1: Host name * 2: Address type (either "AF_INET" or "AF_INET6") * 3: The first address. * 4+ The second, third, etc. addresses. * on failure, gethostbyname returns an error string in |out_error|. */ int HandleGethostbyname(struct PP_Var params, struct PP_Var* output, const char** out_error) { CHECK_PARAM_COUNT(gethostbyname, 1); PARAM_STRING(0, name); struct hostent* info = gethostbyname(name); if (!info) { *out_error = PrintfToNewString("gethostbyname failed, error is \"%s\"", hstrerror(h_errno)); return 1; } CREATE_RESPONSE(gethostbyname); RESPONSE_STRING(info->h_name); RESPONSE_STRING(info->h_addrtype == AF_INET ? "AF_INET" : "AF_INET6"); struct in_addr** addr_list = (struct in_addr**)info->h_addr_list; int i; for (i = 0; addr_list[i] != NULL; i++) { if (info->h_addrtype == AF_INET) { RESPONSE_STRING(inet_ntoa(*addr_list[i])); } else { // IPv6 char addr_str[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, addr_list[i], addr_str, sizeof(addr_str)); RESPONSE_STRING(addr_str); } } return 0; }
/** * Handle a call to getaddrinfo() made by JavaScript. * * getaddrinfo expects 1 parameter: * 0: The name of the host to look up. * on success, getaddrinfo returns a result in |output|: * 0: "getaddrinfo" * 1: The canonical name * 2*n+2: Host name * 2*n+3: Address type (either "AF_INET" or "AF_INET6") * on failure, getaddrinfo returns an error string in |out_error|. */ int HandleGetaddrinfo(struct PP_Var params, struct PP_Var* output, const char** out_error) { CHECK_PARAM_COUNT(getaddrinfo, 2); PARAM_STRING(0, name); PARAM_STRING(1, family); struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; if (!strcmp(family, "AF_INET")) hints.ai_family = AF_INET; else if (!strcmp(family, "AF_INET6")) hints.ai_family = AF_INET6; else if (!strcmp(family, "AF_UNSPEC")) hints.ai_family = AF_UNSPEC; else { *out_error = PrintfToNewString("getaddrinfo uknown family: %s", family); return 1; } struct addrinfo* ai; int rtn = getaddrinfo(name, NULL, &hints, &ai); if (rtn != 0) { *out_error = PrintfToNewString("getaddrinfo failed, error is \"%s\"", gai_strerror(rtn)); return 2; } CREATE_RESPONSE(getaddrinfo); RESPONSE_STRING(ai->ai_canonname); struct addrinfo* current = ai; while (current) { char addr_str[INET6_ADDRSTRLEN]; if (ai->ai_family == AF_INET6) { struct sockaddr_in6* in6 = (struct sockaddr_in6*)current->ai_addr; inet_ntop( ai->ai_family, &in6->sin6_addr.s6_addr, addr_str, sizeof(addr_str)); } else if (ai->ai_family == AF_INET) { struct sockaddr_in* in = (struct sockaddr_in*)current->ai_addr; inet_ntop(ai->ai_family, &in->sin_addr, addr_str, sizeof(addr_str)); } RESPONSE_STRING(addr_str); RESPONSE_STRING(ai->ai_family == AF_INET ? "AF_INET" : "AF_INET6"); current = current->ai_next; } freeaddrinfo(ai); return 0; }
/** * Handle a call to fopen() made by JavaScript. * * fopen expects 2 parameters: * 0: the path of the file to open * 1: the mode string * on success, fopen returns a result in |output|: * 0: "fopen" * 1: the filename opened * 2: the file index * on failure, fopen returns an error string in |out_error|. */ int HandleFopen(struct PP_Var params, struct PP_Var* output, const char** out_error) { CHECK_PARAM_COUNT(fopen, 2); PARAM_STRING(0, filename); PARAM_STRING(1, mode); FILE* file = fopen(filename, mode); if (!file) { *out_error = PrintfToNewString("fopen returned a NULL FILE*"); return 1; } int file_index = AddFileToMap(file); if (file_index == -1) { *out_error = PrintfToNewString("Example only allows %d open file handles", MAX_OPEN_FILES); return 1; } CREATE_RESPONSE(fopen); RESPONSE_STRING(filename); RESPONSE_INT(file_index); return 0; }
/** * Handle a call to opendir() made by JavaScript. * * opendir expects 1 parameter: * 0: The name of the directory * on success, opendir returns a result in |output|: * 0: "opendir" * 1: the directory name * 2: the index of the directory * on failure, opendir returns an error string in |out_error|. */ int HandleOpendir(struct PP_Var params, struct PP_Var* output, const char** out_error) { #if defined(WIN32) *out_error = PrintfToNewString("Win32 does not support opendir"); return 1; #else CHECK_PARAM_COUNT(opendir, 1); PARAM_STRING(0, dirname); DIR* dir = opendir(dirname); if (!dir) { *out_error = PrintfToNewString("opendir returned a NULL DIR*"); return 1; } int dir_index = AddDirToMap(dir); if (dir_index == -1) { *out_error = PrintfToNewString("Example only allows %d open dir handles", MAX_OPEN_DIRS); return 1; } CREATE_RESPONSE(opendir); RESPONSE_STRING(dirname); RESPONSE_INT(dir_index); return 0; #endif }
/** * Handle a call to recv() made by JavaScript. * * recv expects 2 parameters: * 0: The socket file descriptor to recv from. * 1: The size of the buffer to pass to recv. * on success, send returns a result in |output|: * 0: "recv" * 1: The number of bytes received. * 2: The data received. * on failure, recv returns an error string in |out_error|. */ int HandleRecv(struct PP_Var params, struct PP_Var* output, const char** out_error) { CHECK_PARAM_COUNT(recv, 2); PARAM_INT(0, sock); PARAM_INT(1, buffersize); if (buffersize < 0 || buffersize > 65 * 1024) { *out_error = PrintfToNewString("recv buffersize must be between 0 and 65k."); return 1; } char* buffer = alloca(buffersize); memset(buffer, 0, buffersize); int result = (int32_t)recv(sock, buffer, buffersize, 0); if (result <= 0) { *out_error = PrintfToNewString("recv failed: %s", strerror(errno)); return 1; } CREATE_RESPONSE(recv); RESPONSE_INT(result); RESPONSE_STRING(buffer); return 0; }
int Handle_iguana(struct PP_Var params,struct PP_Var *output,const char **out_error) { char *iguana_JSON(char *); char *retstr; PostMessage("inside Handle_iguana\n"); CHECK_PARAM_COUNT(iguana, 1); PARAM_STRING(0,jsonstr); retstr = iguana_JSON(jsonstr); CREATE_RESPONSE(iguana); RESPONSE_STRING(retstr); return 0; }
int HandleSuperNET(struct PP_Var params,struct PP_Var *output,const char **out_error) { char *SuperNET_JSON(char *); char *retstr; //PostMessage("inside handle SuperNET\n"); CHECK_PARAM_COUNT(SuperNET, 1); PARAM_STRING(0,jsonstr); retstr = SuperNET_JSON(jsonstr); CREATE_RESPONSE(SuperNET); //RESPONSE_INT(0); RESPONSE_STRING(retstr); return 0; }
/** * Handle a call to getcwd() made by JavaScript. * * getcwd expects 0 parameters. * on success, getcwd returns a result in |output|: * 0: "getcwd" * 1: the current working directory * on failure, getcwd returns an error string in |out_error|. */ int HandleGetcwd(struct PP_Var params, struct PP_Var* output, const char** out_error) { CHECK_PARAM_COUNT(getcwd, 0); char cwd[PATH_MAX]; char* result = getcwd(cwd, PATH_MAX); if (result == NULL) { *out_error = PrintfToNewString("getcwd returned error: %d", errno); return 1; } CREATE_RESPONSE(getcwd); RESPONSE_STRING(cwd); return 0; }
int HandleJS(struct PP_Var params, struct PP_Var* output, const char** out_error) { PostMessage("JS?"); CHECK_PARAM_COUNT(js, 2); PARAM_STRING(0, jsonstr); PARAM_STRING(1, ptr); int64_t nptr = strtoll(ptr, NULL, 10); char * addr = (char *)nptr; strcpy(addr, jsonstr); CREATE_RESPONSE(js); RESPONSE_STRING(ptr); return 0; }
/** * Handle a call to chdir() made by JavaScript. * * chdir expects 1 parameter: * 0: The name of the directory * on success, chdir returns a result in |output|: * 0: "chdir" * 1: the name of the directory * on failure, chdir returns an error string in |out_error|. */ int HandleChdir(struct PP_Var params, struct PP_Var* output, const char** out_error) { CHECK_PARAM_COUNT(chdir, 1); PARAM_STRING(0, dirname); int result = chdir(dirname); if (result != 0) { *out_error = PrintfToNewString("chdir returned error: %d", errno); return 1; } CREATE_RESPONSE(chdir); RESPONSE_STRING(dirname); return 0; }
/** * Handle a call to stat() made by JavaScript. * * stat expects 1 parameter: * 0: The name of the file * on success, stat returns a result in |output|: * 0: "stat" * 1: the file name * 2: the size of the file * on failure, stat returns an error string in |out_error|. */ int HandleStat(struct PP_Var params, struct PP_Var* output, const char** out_error) { CHECK_PARAM_COUNT(stat, 1); PARAM_STRING(0, filename); struct stat buf; memset(&buf, 0, sizeof(buf)); int result = stat(filename, &buf); if (result == -1) { *out_error = PrintfToNewString("stat returned error %d", errno); return 1; } CREATE_RESPONSE(stat); RESPONSE_STRING(filename); RESPONSE_INT((int32_t)buf.st_size); return 0; }
/** * Handle a call to readdir() made by JavaScript. * * readdir expects 1 parameter: * 0: The index of the directory (which is mapped to a DIR*) * on success, opendir returns a result in |output|: * 0: "readdir" * 1: the inode number of the entry * 2: the name of the entry * if there are no more entries, |output| contains: * 0: "readdir" * on failure, readdir returns an error string in |out_error|. */ int HandleReaddir(struct PP_Var params, struct PP_Var* output, const char** out_error) { #if defined(WIN32) *out_error = PrintfToNewString("Win32 does not support readdir"); return 1; #else CHECK_PARAM_COUNT(readdir, 1); PARAM_DIR(0, dir); struct dirent* entry = readdir(dir); CREATE_RESPONSE(readdir); RESPONSE_INT(dir_index); if (entry != NULL) { RESPONSE_INT((int32_t)entry->d_ino); RESPONSE_STRING(entry->d_name); } return 0; #endif }
/** * Handle a call to fread() made by JavaScript. * * fread expects 2 parameters: * 0: The index of the file (which is mapped to a FILE*) * 1: The number of bytes to read from the file. * on success, fread returns a result in |output|: * 0: "fread" * 1: the file index * 2: the data read from the file * on failure, fread returns an error string in |out_error|. */ int HandleFread(struct PP_Var params, struct PP_Var* output, const char** out_error) { CHECK_PARAM_COUNT(fread, 2); PARAM_FILE(0, file); PARAM_INT(1, data_len); char* buffer = (char*)malloc(data_len + 1); size_t bytes_read = fread(buffer, 1, data_len, file); buffer[bytes_read] = 0; if (ferror(file)) { *out_error = PrintfToNewString( "Read %" PRIuS " bytes, but ferror() returns true", bytes_read); free(buffer); return 1; } CREATE_RESPONSE(fread); RESPONSE_INT(file_index); RESPONSE_STRING(buffer); free(buffer); return 0; }