static void LinuxProcessList_readVServerData(LinuxProcess* process, const char* dirname, const char* name) { char filename[MAX_NAME+1]; snprintf(filename, MAX_NAME, "%s/%s/status", dirname, name); FILE* file = fopen(filename, "r"); if (!file) return; char buffer[PROC_LINE_LENGTH + 1]; process->vxid = 0; while (fgets(buffer, PROC_LINE_LENGTH, file)) { if (String_startsWith(buffer, "VxID:")) { int vxid; int ok = sscanf(buffer, "VxID:\t%32d", &vxid); if (ok >= 1) { process->vxid = vxid; } } #if defined HAVE_ANCIENT_VSERVER else if (String_startsWith(buffer, "s_context:")) { int vxid; int ok = sscanf(buffer, "s_context:\t%32d", &vxid); if (ok >= 1) { process->vxid = vxid; } } #endif } fclose(file); }
String CRhodesAppBase::resolveDBFilesPath(const String& strFilePath) { if ( String_startsWith(strFilePath, getRhoRootPath()) ) return strFilePath; return CFilePath::join(getRhoRootPath(), strFilePath); }
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, uid_t userId) { LinuxProcessList* this = calloc(1, sizeof(LinuxProcessList)); ProcessList* pl = &(this->super); ProcessList_init(pl, Class(LinuxProcess), usersTable, pidWhiteList, userId); // Update CPU count: FILE* file = fopen(PROCSTATFILE, "r"); if (file == NULL) { CRT_fatalError("Cannot open " PROCSTATFILE); } char buffer[PROC_LINE_LENGTH + 1]; int cpus = -1; do { cpus++; char * s = fgets(buffer, PROC_LINE_LENGTH, file); (void) s; } while (String_startsWith(buffer, "cpu")); fclose(file); pl->cpuCount = MAX(cpus - 1, 1); this->cpus = calloc(cpus, sizeof(CPUData)); for (int i = 0; i < cpus; i++) { this->cpus[i].totalTime = 1; this->cpus[i].totalPeriod = 1; } return pl; }
String CRhodesAppBase::resolveDBFilesPath(const String& strFilePath) { #ifndef RHODES_EMULATOR String strDbFileRoot = rho_native_rhodbpath();//getRhoRootPath(); #else String strDbFileRoot = getRhoRootPath() + RHO_EMULATOR_DIR; #endif if ( strFilePath.length() == 0 || String_startsWith(strFilePath, strDbFileRoot) || String_startsWith(strFilePath, "file://")) return strFilePath; return CFilePath::join(strDbFileRoot, strFilePath); }
ProcessList* ProcessList_new(UsersTable* usersTable) { ProcessList* this; this = calloc(sizeof(ProcessList), 1); this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare); this->processTable = Hashtable_new(70, false); assert(Hashtable_count(this->processTable) == Vector_count(this->processes)); this->usersTable = usersTable; /* tree-view auxiliary buffers */ this->processes2 = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare); FILE* file = fopen(PROCSTATFILE, "r"); assert(file != NULL); char buffer[256]; int cpus = -1; do { cpus++; fgets(buffer, 255, file); } while (String_startsWith(buffer, "cpu")); fclose(file); this->cpuCount = cpus - 1; this->cpus = calloc(sizeof(CPUData), cpus); for (int i = 0; i < cpus; i++) { this->cpus[i].totalTime = 1; this->cpus[i].totalPeriod = 1; } this->fields = calloc(sizeof(ProcessField), LAST_PROCESSFIELD+1); // TODO: turn 'fields' into a Vector, // (and ProcessFields into proper objects). for (int i = 0; defaultHeaders[i]; i++) { this->fields[i] = defaultHeaders[i]; } this->sortKey = PERCENT_CPU; this->direction = 1; this->hideThreads = false; this->shadowOtherUsers = false; this->showThreadNames = false; this->showingThreadNames = false; this->hideKernelThreads = false; this->hideUserlandThreads = false; this->treeView = false; this->highlightBaseName = false; this->highlightMegabytes = false; this->detailedCPUTime = false; this->countCPUsFromZero = false; return this; }
ProcessList *cpudata_new(void) { int i; ProcessList *this; FILE *file = fopen(PROCSTATFILE, "r"); assert(file != NULL); char buffer[BUFLEN]; int cpus = -1; do { cpus++; if (fgets(buffer, BUFLEN - 1, file) == NULL) { perror("Failed to get CPU number"); exit(1); } } while (String_startsWith(buffer, "cpu")); fclose(file); if (cpu > cpus -1) { error("too many cpus"); exit(1); } this = calloc(sizeof(ProcessList), 1); if (this == NULL) { perror("Failed to allocate memory"); exit(1); } this->cpudata = calloc(sizeof(CPUData), cpus); if (this->cpudata == NULL) { perror("Failed to allocate memory"); exit(1); } this->cpuload = calloc(sizeof(CPUData), cpus); if (this->cpuload == NULL) { perror("Failed to allocate memory"); exit(1); } this->cpuCount = cpus - 1; for (i = 0; i < cpus; i++) { this->cpudata[i].totalTime = 1; this->cpudata[i].totalPeriod = 1; } return this; }
bool CHttpServer::decide(String const &method, String const &arg_uri, String const &query, HeaderList const &headers, String const &body/*, IResponseSender& respSender*/ ) { if (verbose) RAWTRACE1("Decide what to do with uri %s", arg_uri.c_str()); callback_t callback = registered(arg_uri); if (callback) { if (verbose) RAWTRACE1("Uri %s is registered callback, so handle it appropriately", arg_uri.c_str()); if ( callback == rho_http_ruby_proc_callback ) call_ruby_proc( query, body ); else callback(this, query.length() ? query : body); return false; } String uri = arg_uri; String fullPath = CFilePath::join(m_root, uri); #ifndef RHO_NO_RUBY_API if (rho_ruby_is_started()) { Route route; if (dispatch(uri, route)) { if (verbose) RAWTRACE1("Uri %s is correct route, so enable MVC logic", uri.c_str()); VALUE req = create_request_hash(route.application, route.model, route.action, route.id, method, uri, query, headers, body); VALUE data = callFramework(req); String reply(getStringFromValue(data), getStringLenFromValue(data)); rho_ruby_releaseValue(data); bool isRedirect = String_startsWith(reply, "HTTP/1.1 301") || String_startsWith(reply, "HTTP/1.1 302"); if (!send_response(reply, isRedirect)) return false; if (method == "GET") rho_rhodesapp_keeplastvisitedurl(uri.c_str()); if ( sync::RhoconnectClientManager::haveRhoconnectClientImpl() ) { if (!route.id.empty()) { sync::RhoconnectClientManager::rho_sync_addobjectnotify_bysrcname(route.model.c_str(), route.id.c_str()); } } return true; } if (isdir(fullPath)) { if (verbose) RAWTRACE1("Uri %s is directory, redirecting to index", uri.c_str()); String q = query.empty() ? "" : "?" + query; HeaderList headers; headers.push_back(Header("Location", CFilePath::join( uri, "index" RHO_ERB_EXT) + q)); send_response(create_response("301 Moved Permanently", headers), true); return false; } if (isindex(uri)) { if (!isfile(fullPath)) { if (verbose) RAWLOG_ERROR1("The file %s was not found", fullPath.c_str()); String error = "<!DOCTYPE html><html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + uri + " was not found.</font></html>"; send_response(create_response("404 Not Found",error)); return false; } if (verbose) RAWTRACE1("Uri %s is index file, call serveIndex", uri.c_str()); VALUE req = create_request_hash(route.application, route.model, route.action, route.id, method, uri, query, headers, body); VALUE data = callServeIndex((char *)fullPath.c_str(), req); String reply(getStringFromValue(data), getStringLenFromValue(data)); rho_ruby_releaseValue(data); if (!send_response(reply)) return false; if (method == "GET") rho_rhodesapp_keeplastvisitedurl(uri.c_str()); return true; } } #endif // Try to send requested file if (verbose) RAWTRACE1("Uri %s should be regular file, trying to send it", uri.c_str()); PROF_START("READ_FILE"); bool bRes = send_file(uri, headers); PROF_STOP("READ_FILE"); return bRes; }
bool CHttpServer::send_file(String const &path, HeaderList const &hdrs) { String fullPath = CFilePath::normalizePath(path); if (String_startsWith(fullPath,"/app/db/db-files") ) fullPath = CFilePath::join( rho_native_rhodbpath(), path.substr(4) ); else if (fullPath.find(m_root) != 0 && fullPath.find(m_strRhoRoot) != 0 && fullPath.find(m_strRuntimeRoot) != 0 && fullPath.find(m_userroot) != 0 && fullPath.find(m_strRhoUserRoot) != 0) fullPath = CFilePath::join( m_root, path ); struct stat st; bool bCheckExist = true; #ifdef RHODES_EMULATOR String strPlatform = RHOSIMCONF().getString("platform"); if ( strPlatform.length() > 0 ) { String fullPath1 = fullPath; int nDot = fullPath1.rfind('.'); if ( nDot >= 0 ) fullPath1.insert(nDot, String(".") + strPlatform); else fullPath1 += String(".") + strPlatform; if (stat(fullPath1.c_str(), &st) == 0 && S_ISREG(st.st_mode)) { fullPath = fullPath1; bCheckExist = false; } } #endif bool doesNotExists = bCheckExist && (stat(fullPath.c_str(), &st) != 0 || !S_ISREG(st.st_mode)); if ( doesNotExists ) { // looking for files at 'rho/apps' at runtime folder fullPath = CFilePath::join( m_strRuntimeRoot, path ); } if (verbose) RAWTRACE1("Sending file %s...", fullPath.c_str()); if ( doesNotExists ) { if ( stat(fullPath.c_str(), &st) != 0 || !S_ISREG(st.st_mode) ) { doesNotExists = true; }else doesNotExists = false; } #ifdef RHODES_EMULATOR if ( doesNotExists ) { CTokenizer oTokenizer( RHOSIMCONF().getString("ext_path"), ";" ); while (oTokenizer.hasMoreTokens()) { String tok = oTokenizer.nextToken(); tok = String_trim(tok); String fullPath1 = CFilePath::join( tok, path ); if (stat(fullPath1.c_str(), &st) == 0 && S_ISREG(st.st_mode)) { fullPath = fullPath1; doesNotExists = false; break; } } } #endif if ( doesNotExists ) { if (verbose) RAWLOG_ERROR1("The file %s was not found", path.c_str()); String error = "<!DOCTYPE html><html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + path + " was not found.</font></html>"; send_response(create_response("404 Not Found",error)); return false; } PROF_START("LOW_FILE"); FILE *fp = fopen(fullPath.c_str(), "rb"); PROF_STOP("LOW_FILE"); if (!fp) { if (verbose) RAWLOG_ERROR1("The file %s could not be opened", path.c_str()); String error = "<!DOCTYPE html><html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + path + " could not be opened.</font></html"; send_response(create_response("404 Not Found",error)); return false; } HeaderList headers; // Detect mime type headers.push_back(Header("Content-Type", get_mime_type(path))); if ( String_startsWith(path, "/public") ) { headers.push_back(Header("Expires", "Thu, 15 Apr 2020 20:00:00 GMT") ); headers.push_back(Header("Cache-Control", "max-age=2592000") ); } // Content length char* buf = new char[FILE_BUF_SIZE]; String start_line; size_t file_size = st.st_size; size_t range_begin = 0, range_end = file_size - 1; size_t content_size = file_size; if (parse_range(hdrs, &range_begin, &range_end)) { if (range_end >= file_size) range_end = file_size - 1; if (range_begin >= range_end) range_begin = range_end - 1; content_size = range_end - range_begin + 1; if (fseek(fp, range_begin, SEEK_SET) == -1) { RAWLOG_ERROR1("Can not seek to specified range start: %lu", (unsigned long)range_begin); snprintf(buf, FILE_BUF_SIZE, "bytes */%lu", (unsigned long)file_size); headers.push_back(Header("Content-Range", buf)); send_response(create_response("416 Request Range Not Satisfiable",headers)); fclose(fp); delete[] buf; return false; } snprintf(buf, FILE_BUF_SIZE, "bytes %lu-%lu/%lu", (unsigned long)range_begin, (unsigned long)range_end, (unsigned long)file_size); headers.push_back(Header("Content-Range", buf)); start_line = "206 Partial Content"; } else { start_line = "200 OK"; } snprintf(buf, FILE_BUF_SIZE, "%lu", (unsigned long)content_size); headers.push_back(Header("Content-Length", buf)); // Send headers if (!send_response(create_response(start_line, headers))) { if (verbose) RAWLOG_ERROR1("Can not send headers while sending file %s", path.c_str()); fclose(fp); delete[] buf; return false; } // Send body for (size_t start = range_begin; start < range_end + 1;) { size_t need_to_read = range_end - start + 1; if (need_to_read == 0) break; if (need_to_read > FILE_BUF_SIZE) need_to_read = FILE_BUF_SIZE; PROF_START("LOW_FILE"); size_t n = fread(buf, 1, need_to_read, fp);//fread(buf, 1, need_to_read, fp); PROF_STOP("LOW_FILE"); if (n < need_to_read) { if (ferror(fp) ) { if (verbose) RAWLOG_ERROR2("Can not read part of file (at position %lu): %s", (unsigned long)start, strerror(errno)); } else if ( feof(fp) ) { if (verbose) RAWLOG_ERROR1("End of file reached, but we expect data (%lu bytes)", (unsigned long)need_to_read); } fclose(fp); delete[] buf; return false; } start += n; if (!send_response_body(String(buf, n))) { if (verbose) RAWLOG_ERROR1("Can not send part of data while sending file %s", path.c_str()); fclose(fp); delete[] buf; return false; } } PROF_START("LOW_FILE"); fclose(fp); PROF_STOP("LOW_FILE"); delete[] buf; if (verbose) RAWTRACE1("File %s was sent successfully", path.c_str()); return false; }
boolean CRhodesAppBase::isBaseUrl(const String& strUrl) { return String_startsWith(strUrl, m_strHomeUrl); }
void CRT_init(int delay, int colorScheme) { initscr(); noecho(); CRT_delay = delay; if (CRT_delay == 0) { CRT_delay = 1; } CRT_colors = CRT_colorSchemes[colorScheme]; CRT_colorScheme = colorScheme; for (int i = 0; i < LAST_COLORELEMENT; i++) { unsigned int color = CRT_colorSchemes[COLORSCHEME_DEFAULT][i]; CRT_colorSchemes[COLORSCHEME_BROKENGRAY][i] = color == (A_BOLD | ColorPairGrayBlack) ? ColorPair(White,Black) : color; } halfdelay(CRT_delay); nonl(); intrflush(stdscr, false); keypad(stdscr, true); mouseinterval(0); curs_set(0); if (has_colors()) { start_color(); CRT_hasColors = true; } else { CRT_hasColors = false; } CRT_termType = getenv("TERM"); if (String_eq(CRT_termType, "linux")) CRT_scrollHAmount = 20; else CRT_scrollHAmount = 5; if (String_startsWith(CRT_termType, "xterm") || String_eq(CRT_termType, "vt220")) { define_key("\033[H", KEY_HOME); define_key("\033[F", KEY_END); define_key("\033[7~", KEY_HOME); define_key("\033[8~", KEY_END); define_key("\033OP", KEY_F(1)); define_key("\033OQ", KEY_F(2)); define_key("\033OR", KEY_F(3)); define_key("\033OS", KEY_F(4)); define_key("\033[11~", KEY_F(1)); define_key("\033[12~", KEY_F(2)); define_key("\033[13~", KEY_F(3)); define_key("\033[14~", KEY_F(4)); define_key("\033[17;2~", KEY_F(18)); char sequence[3] = "\033a"; for (char c = 'a'; c <= 'z'; c++) { sequence[1] = c; define_key(sequence, KEY_ALT('A' + (c - 'a'))); } } #ifndef DEBUG signal(11, CRT_handleSIGSEGV); #endif signal(SIGTERM, CRT_handleSIGTERM); signal(SIGQUIT, CRT_handleSIGTERM); use_default_colors(); if (!has_colors()) CRT_colorScheme = 1; CRT_setColors(CRT_colorScheme); /* initialize locale */ setlocale(LC_CTYPE, ""); #ifdef HAVE_LIBNCURSESW if(strcmp(nl_langinfo(CODESET), "UTF-8") == 0) CRT_utf8 = true; else CRT_utf8 = false; #endif CRT_treeStr = #ifdef HAVE_LIBNCURSESW CRT_utf8 ? CRT_treeStrUtf8 : #endif CRT_treeStrAscii; #if NCURSES_MOUSE_VERSION > 1 mousemask(BUTTON1_RELEASED | BUTTON4_PRESSED | BUTTON5_PRESSED, NULL); #else mousemask(BUTTON1_RELEASED, NULL); #endif }
bool CHttpServer::decide(String const &method, String const &arg_uri, String const &query, HeaderList const &headers, String const &body) { RAWTRACE1("Decide what to do with uri %s", arg_uri.c_str()); callback_t callback = registered(arg_uri); if (callback) { RAWTRACE1("Uri %s is registered callback, so handle it appropriately", arg_uri.c_str()); if ( callback == rho_http_ruby_proc_callback ) call_ruby_proc( query, body ); else callback(this, query.length() ? query : body); return false; } String uri = arg_uri; //#ifdef OS_ANDROID // //Work around malformed Android WebView URLs // if (!String_startsWith(uri, "/app") && // !String_startsWith(uri, "/public") && // !String_startsWith(uri, "/data")) // { // RAWTRACE1("Malformed URL: '%s', adding '/app' prefix.", uri.c_str()); // uri = CFilePath::join("/app", uri); // } //#endif String fullPath = CFilePath::join(m_root, uri); Route route; if (dispatch(uri, route)) { RAWTRACE1("Uri %s is correct route, so enable MVC logic", uri.c_str()); VALUE req = create_request_hash(route.application, route.model, route.action, route.id, method, uri, query, headers, body); VALUE data = callFramework(req); String reply(getStringFromValue(data), getStringLenFromValue(data)); rho_ruby_releaseValue(data); bool isRedirect = String_startsWith(reply, "HTTP/1.1 301") || String_startsWith(reply, "HTTP/1.1 302"); if (!send_response(reply, isRedirect)) return false; if (method == "GET") rho_rhodesapp_keeplastvisitedurl(uri.c_str()); if ( sync::RhoconnectClientManager::haveRhoconnectClientImpl() ) { if (!route.id.empty()) { sync::RhoconnectClientManager::rho_sync_addobjectnotify_bysrcname(route.model.c_str(), route.id.c_str()); } } return true; } //#ifndef OS_ANDROID if (isdir(fullPath)) { RAWTRACE1("Uri %s is directory, redirecting to index", uri.c_str()); String q = query.empty() ? "" : "?" + query; HeaderList headers; headers.push_back(Header("Location", CFilePath::join( uri, "index"RHO_ERB_EXT) + q)); send_response(create_response("301 Moved Permanently", headers), true); return false; } //#else // //Work around this Android redirect bug: // //http://code.google.com/p/android/issues/detail?can=2&q=11583&id=11583 // if (isdir(fullPath)) { // RAWTRACE1("Uri %s is directory, override with index", uri.c_str()); // return decide(method, CFilePath::join( uri, "index"RHO_ERB_EXT), query, headers, body); // } //#endif if (isindex(uri)) { if (!isfile(fullPath)) { RAWLOG_ERROR1("The file %s was not found", fullPath.c_str()); String error = "<html><font size=\"+4\"><h2>404 Not Found.</h2> The file " + uri + " was not found.</font></html>"; send_response(create_response("404 Not Found",error)); return false; } RAWTRACE1("Uri %s is index file, call serveIndex", uri.c_str()); VALUE req = create_request_hash(route.application, route.model, route.action, route.id, method, uri, query, headers, body); VALUE data = callServeIndex((char *)fullPath.c_str(), req); String reply(getStringFromValue(data), getStringLenFromValue(data)); rho_ruby_releaseValue(data); if (!send_response(reply)) return false; if (method == "GET") rho_rhodesapp_keeplastvisitedurl(uri.c_str()); return true; } // Try to send requested file RAWTRACE1("Uri %s should be regular file, trying to send it", uri.c_str()); return send_file(uri, headers); }
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) { ProcessList* this; this = calloc(1, sizeof(ProcessList)); this->processes = Vector_new(Class(Process), true, DEFAULT_SIZE); this->processTable = Hashtable_new(140, false); this->usersTable = usersTable; this->pidWhiteList = pidWhiteList; /* tree-view auxiliary buffers */ this->processes2 = Vector_new(Class(Process), true, DEFAULT_SIZE); FILE* file = fopen(PROCSTATFILE, "r"); if (file == NULL) { CRT_fatalError("Cannot open " PROCSTATFILE); } char buffer[256]; int cpus = -1; do { cpus++; fgets(buffer, 255, file); } while (String_startsWith(buffer, "cpu")); fclose(file); this->cpuCount = MAX(cpus - 1, 1); #ifdef HAVE_LIBHWLOC this->topologyOk = false; int topoErr = hwloc_topology_init(&this->topology); if (topoErr == 0) { topoErr = hwloc_topology_load(this->topology); } if (topoErr == 0) { this->topologyOk = true; } #endif this->cpus = calloc(cpus, sizeof(CPUData)); for (int i = 0; i < cpus; i++) { this->cpus[i].totalTime = 1; this->cpus[i].totalPeriod = 1; } this->fields = calloc(LAST_PROCESSFIELD+1, sizeof(ProcessField)); // TODO: turn 'fields' into a Vector, // (and ProcessFields into proper objects). this->flags = 0; for (int i = 0; defaultHeaders[i]; i++) { this->fields[i] = defaultHeaders[i]; this->fields[i] |= Process_fieldFlags[defaultHeaders[i]]; } this->sortKey = PERCENT_CPU; this->direction = 1; this->hideThreads = false; this->shadowOtherUsers = false; this->showThreadNames = false; this->showingThreadNames = false; this->hideKernelThreads = false; this->hideUserlandThreads = false; this->treeView = false; this->highlightBaseName = false; this->highlightMegabytes = false; this->detailedCPUTime = false; this->countCPUsFromZero = false; this->updateProcessNames = false; this->treeStr = NULL; this->following = -1; if (CRT_utf8) this->treeStr = CRT_utf8 ? ProcessList_treeStrUtf8 : ProcessList_treeStrAscii; return this; }