Esempio n. 1
0
void SearchContext::searchProc()
{
    int id = searchID_;
    HANDLE findHandle = INVALID_HANDLE_VALUE;
    StringList paths;
    paths = params_.paths;
    RegexList filespecRegexes;
    pcre *matchRegex = NULL;

    directoriesSearched_ = 0;
    directoriesSkipped_ = 0;
    filesSearched_ = 0;
    filesSkipped_ = 0;
    filesWithHits_ = 0;
    linesWithHits_ = 0;
    hits_ = 0;

    unsigned int startTick = GetTickCount();

    bool filespecUsesRegexes = ((params_.flags & SF_FILESPEC_REGEXES) != 0);
    bool matchUsesRegexes    = ((params_.flags & SF_MATCH_REGEXES) != 0);

	delete pokeData_;
	pokeData_ = new PokeData;

    if(matchUsesRegexes)
    {
        const char *error;
        int erroffset;
        int flags = 0;
        if(!(params_.flags & SF_MATCH_CASE_SENSITIVE))
            flags |= PCRE_CASELESS;
        matchRegex = pcre_compile(params_.match.c_str(), flags, &error, &erroffset, NULL);
        if(!matchRegex)
        {
            MessageBox(window_, error, "Match Regex Error", MB_OK);
            goto cleanup;
        }
    }

    for(StringList::iterator it = params_.filespecs.begin(); it != params_.filespecs.end(); ++it)
    {
        std::string regexString = it->c_str();
        if(!filespecUsesRegexes)
            convertWildcard(regexString);

        int flags = 0;
        if(!(params_.flags & SF_FILESPEC_CASE_SENSITIVE))
            flags |= PCRE_CASELESS;

        const char *error;
        int erroffset;
        pcre *regex = pcre_compile(regexString.c_str(), flags, &error, &erroffset, NULL);
        if(regex)
            filespecRegexes.push_back(regex);
        else
        {
            MessageBox(window_, error, "Filespec Regex Error", MB_OK);
            goto cleanup;
        }
    }

    PostMessage(window_, WM_SEARCHCONTEXT_STATE, 1, 0);

    while(!paths.empty())
    {
        directoriesSearched_++;
        stopCheck();

        std::string currentSearchPath = paths.back();
        std::string currentSearchWildcard = currentSearchPath + "\\*";

        paths.pop_back();

        WIN32_FIND_DATA wfd;
        findHandle = FindFirstFile(currentSearchWildcard.c_str(), &wfd);
        if(findHandle == INVALID_HANDLE_VALUE)
            continue;

        while(FindNextFile(findHandle, &wfd))
        {
            stopCheck();
            bool isDirectory = ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);

            if((wfd.cFileName[0] == '.') || (wfd.cFileName[0] == 0))
            {
                if(isDirectory)
                    directoriesSkipped_++;
                else
                    filesSkipped_++;
                continue;
            }

            std::string filename = currentSearchPath;
            filename += "\\";
            filename += wfd.cFileName;

            if(isDirectory)
            {
                if(params_.flags & SF_RECURSIVE)
                    paths.push_back(filename);
            }
            else
            {
                if(searchFile(id, filename, filespecRegexes, matchRegex))
                {
                    filesSearched_++;
                }
                else
                {
                    filesSkipped_++;
                }
                poke(id, "", HighlightList(), 0, false);
            }
        }

        if(findHandle != INVALID_HANDLE_VALUE)
        {
            FindClose(findHandle);
        }
    }

cleanup:
    for(RegexList::iterator it = filespecRegexes.begin(); it != filespecRegexes.end(); ++it)
    {
        pcre_free(*it);
    }
    if(matchRegex)
        pcre_free(matchRegex);
    filespecRegexes.clear();
    if(!stop_)
    {
        unsigned int endTick = GetTickCount();
        char buffer[512];
        float sec = (endTick - startTick) / 1000.0f;
        const char *verb = "searched";
        if(params_.flags & SF_REPLACE)
            verb = "updated";
        sprintf(buffer, "\n%d hits in %d lines across %d files.\n%d directories scanned, %d files %s, %d files skipped (%3.3f sec)", 
            hits_,
            linesWithHits_,
            filesWithHits_,
            directoriesSearched_,
            filesSearched_,
            verb,
            filesSkipped_,
            sec);
        poke(id, buffer, HighlightList(), 0, true);
    }
    delete pokeData_;
	pokeData_ = NULL;
    PostMessage(window_, WM_SEARCHCONTEXT_STATE, 0, 0);
}
int main(int argc, char **argv)
{
    setvbuf(stdout, NULL, _IOLBF, 0);
#ifdef XP_UNIX
    unlimit();
#endif
    fprintf(stdout, "\n");

    unsigned long limit = 0; // no thread limit by default
    char *addr = NULL;
    PRBool log = PR_FALSE;
    LogLevel logLevel = LOGINFO;
    PLOptState *options;
    PRBool secure = PR_FALSE;
    PRBool NSTests = PR_FALSE; // don't execute Netscape tests by default
    PtrList<char> protlist; // list of security protocols
    PtrList<char> configlist; // list of configurations
    RegexList regexlist; // list of Sun tests/regex to load
    RegexList regexcludelist; // list of Sun tests/regex to exclude
    char* suitename = "suite1";
    PRInt32 concurrent = 0; // number of concurrent threads for each test. 0 means sequential, single-threaded
    PRInt32 delay = 0;
    PRInt32 split = 0;
    PRInt32 timeout = 0; // leave timeout unchanged by default
    char* cert=NULL;
    char* certpwd=NULL;
    char* cipherString = NULL;
    char* version = "ENTERPRISE";
    PRInt32 release = 41;
    PRInt32 hsp = 0; // SSL handshake period
    PRBool performance = PR_FALSE;
    PRInt32 maxtm = 0;
    PRUint16 af = PR_AF_INET;
    PRInt32 displayperiod=0;
    PRBool loop = PR_FALSE;

    Logger::logInitialize(logLevel);

    options = PL_CreateOptState(argc, argv, "X:C:h:H:l:c:d:n:w46r:sx:p:o:t:a:e:k:Ng:v:R:QPE:T:L:");
    long repeat = 1;
    while ( PL_GetNextOpt(options) == PL_OPT_OK)
    {
        switch(options->option)
        {
            case 'L':
                loop = PR_TRUE;
                if (options->value)
                    displayperiod  = (PRInt32) atoi(options->value);
                break;

            case 'E':
                if (options->value)
                    protlist.insert(strdup(options->value));
                break;

            case 'T':
                if (options->value)
                    maxtm  = (PRInt32) atoi(options->value);
                break;

            case 'H':
                if (options->value)
                    hsp  = (PRInt32) atoi(options->value);
                break;

            case 'v':
                if (options->value)
                    version = uppercase(strdup(options->value));
                break;

            case 'g':
                if (options->value)
                    configlist.insert(strdup(options->value));
                break;

            case 'x':
                if (options->value)
                    regexlist.add(options->value);
                break;

            case 'X':
                if (options->value)
                    regexcludelist.add(options->value);
                break;

            case 'w':
                log = PR_TRUE;
                break;

            case 'r':
                if (options->value)
                    repeat = atol(options->value);
                break;

            case 'e':
                if (options->value)
                    timeout = atol(options->value);
                break;

            case 'o':
                if (options->value)
                    split = atol(options->value);
                break;

            case 't':
                if (options->value)
                    delay = atol(options->value);
                break;

            case 'd':
                if (options->value)
                   suitename = strdup(options->value);
                break;

            case 'a':
                if (options->value)
                    arch = strdup(options->value);
                break;

            case 'N':
                NSTests = PR_TRUE;
                break;

            case 'h':
                if (options->value)
                    addr = strdup(options->value);
                break;

            case 'p':
                if (options->value)
                    concurrent = atol(options->value);
                else
                    concurrent = 1; // 1 thread per test
                break;

            case 'P':
                performance = PR_TRUE; // meaure performance only
                break;

            case 'l':
                if (options->value)
                    logLevel = (LogLevel)atoi(options->value);
                break;

            case 'R':
                if (options->value)
                    release = (PRInt32) atoi(options->value);
                break;

            case 's':
                secure = PR_TRUE;
                break;

            case 'n':
                if (options->value)
                    cert = strdup(options->value);
                break;

            case 'k':
                if (options->value)
                    certpwd = strdup(options->value);
                break;

            case 'c':
		if (options->value) {
                  cipherString = strdup(options->value);
                  if (PR_TRUE != EnableCipher(cipherString))
                  {
                         Logger::logError(LOGINFO, "Invalid cipher specified.\n");
                   };
                 }
 		 break;


            case 'C':
                if (options->value)
                    limit = atol(options->value);
                else
                    limit = 0; // no thread limit
                break;

	    case 'Q':
		printCipherOptions();
		break;

	    case '6':
                af = PR_AF_INET6;
		break;

	    case '4':
                af = PR_AF_INET;
		break;

        };
    };

    SecurityProtocols secprots;

    if (PR_TRUE == secure)
    {
        NSString str;
        str.append(suitename);
        str.append("/certs/client");
        secure = InitSecurity((char*)str.data(),
            cert,
            certpwd);
        if (PR_TRUE != secure)
            Logger::logError(LOGINFO, "Unable to initialize security.\n");

        if (protlist.entries())
        {
            secprots = protlist;
        };
    };

    PL_DestroyOptState(options);

    Logger::logInitialize(logLevel);
    nstime_init();

    if (!addr)
    {
        usage(argv[0]);
        return -1;
    };

    HttpServer server(addr, af);
    server.setSSL(secure);
    
    if (PR_FALSE == NSTests)
    {
        if (alltests)
            alltests->clear(); // cancel all the Netscape tests
        if (!regexlist.length())
            regexlist.add(".*");
    };

    if (!configlist.entries())
        configlist.insert("COMMON"); // if no config is specified, select default COMMON configuration

    Engine::globaltimeout = PR_TicksPerSecond()*timeout;

    SunTestSuite suite(configlist, suitename, regexlist, regexcludelist, arch, version, release, log, PR_TicksPerSecond()*timeout, split, delay, hsp, secprots, maxtm);
    PRInt32 percent = suite.runTests(server, concurrent, repeat, limit, performance, loop, displayperiod);

    return percent;
};
Esempio n. 3
0
bool SearchContext::searchFile(int id, const std::string &filename, RegexList &filespecRegexes, pcre *matchRegex)
{
    bool matchesOneFilespec = false;
    for(RegexList::iterator it = filespecRegexes.begin(); it != filespecRegexes.end(); ++it)
    {
        pcre *regex = *it;
        if(pcre_exec(regex, NULL, filename.c_str(), filename.length(), 0, 0, NULL, 0) >= 0)
        {
            matchesOneFilespec = true;
            break;
        }
    }
    if(!matchesOneFilespec)
        return false;

    std::string contents;
    if(!readEntireFile(filename, contents, params_.maxFileSize))
        return false;

    std::string workBuffer = contents;
    std::string updatedContents;

    bool atLeastOneMatch = false;

    int lineNumber = 1;
    char *p = &workBuffer[0];
    char *line;
    while((line = nextToken(&p, '\n')) != NULL)
    {
        char *originalLine = line;
        std::string replacedLine;
		SearchEntry entry;
        int ovector[100];
        do
        {
            bool matches = false;
            int matchPos;
            int matchLen;

            if(matchRegex)
            {
                int rc;
                if(rc = pcre_exec(matchRegex, 0, line, strlen(line), 0, 0, ovector, sizeof(ovector)) >= 0)
                {
                    matches = true;
                    matchPos = ovector[0];
                    matchLen = ovector[1] - ovector[0];
                }
            }
            else
            {
                char *match;
                if(params_.flags & SF_MATCH_CASE_SENSITIVE)
                    match = strstr(line, params_.match.c_str());
                else
                    match = strstri(line, params_.match.c_str());
                if(match != NULL)
                {
                    matches = true;
                    matchPos = match - line;
                    matchLen = params_.match.length();
                }
            }

            if(params_.flags & SF_REPLACE)
            {
                if(matches)
                {
                    replacedLine.append(line, matchPos);
					entry.highlights_.push_back(Highlight(replacedLine.length(), params_.replace.length()));
                    replacedLine.append(params_.replace);
                    line += matchPos + matchLen;
                }
                else
                {
                    break;
                }
            }
            else
            {
                if(matches)
                {
                    entry.filename_ = filename;
                    entry.match_ = originalLine;
                    entry.line_ = lineNumber;
					entry.highlights_.push_back(Highlight(matchPos + (line - originalLine), matchLen));
					line += matchPos + matchLen;
                }
				else
				{
					break;
				}
            }

            if(matches)
                hits_++;
        }
        while(*line);

        if(!entry.filename_.empty())
        {
            linesWithHits_++;
            atLeastOneMatch = true;
        }

        if(params_.flags & SF_REPLACE)
        {
            if(line && *line)
                replacedLine += line;
            if(replacedLine != originalLine)
            {
                entry.filename_ = filename;
                entry.match_ = replacedLine;
                entry.line_ = lineNumber;
                append(id, entry);
            }
            replacedLine += "\n";
            updatedContents += replacedLine;
        }
		else
		{
			if(!entry.filename_.empty())
				append(id, entry);
		}
		lineNumber++;
    }
    if(atLeastOneMatch)
        filesWithHits_++;
    if(params_.flags & SF_REPLACE)
    {
        if((contents != updatedContents))
        {
			bool overwriteFile = true;
			if(params_.flags & SF_BACKUP)
			{
				std::string backupFilename = filename;
				backupFilename += ".";
				backupFilename += params_.backupExtension;

				if(!writeEntireFile(backupFilename, contents))
				{
					std::string err = "WARNING: Couldn't write backup file (skipping replacement): ";
					err += backupFilename;
					err += "\n";
					poke(id, err.c_str(), HighlightList(), 0, false);

					overwriteFile = false;
				}
			}

			if(overwriteFile)
			{
				if(writeEntireFile(filename, updatedContents))
				{
					return true;
				}
				else
				{
					std::string err = "WARNING: Couldn't write to file: ";
					err += filename;
					err += "\n";
					poke(id, err.c_str(), HighlightList(), 0, false);
				}
			}
        }
        return false;
    }
    return true;
}
Esempio n. 4
0
bool SearchContext::searchFile(int id, const std::string &filename, RegexList &filespecRegexes, pcre *matchRegex)
{
    bool matchesOneFilespec = false;
    for(RegexList::iterator it = filespecRegexes.begin(); it != filespecRegexes.end(); ++it)
    {
        pcre *regex = *it;
        if(pcre_exec(regex, NULL, filename.c_str(), filename.length(), 0, 0, NULL, 0) >= 0)
        {
            matchesOneFilespec = true;
            break;
        }
    }
    if(!matchesOneFilespec)
        return false;

    std::string contents;
    if(!readEntireFile(filename, contents, params_.maxFileSize))
        return false;

    std::string workBuffer = contents;
    std::string updatedContents;

    std::deque<char *> contextLines;

    bool atLeastOneMatch = false;

    int trailingContextLines = 0;
    int lineNumber = 1;
    char *p = &workBuffer[0];
    char *line;
    while((line = nextToken(&p, '\n')) != NULL)
    {
        char *originalLine = line;
        std::string replacedLine;
        SearchEntry entry;
        int ovector[100];

        // Strip newline, but remember exactly what kind it was
        bool hasCarriageReturn = false;
        int lineLen = strlen(line);
        if(lineLen && (line[lineLen - 1] == '\r'))
        {
            line[lineLen - 1] = 0;
            hasCarriageReturn = true;
        }

        // Matching loop (we might find our string a few times on a single line)
        bool lineMatched = false;
        do
        {
            bool matches = false;
            int matchPos;
            int matchLen;

            // The actual match. Either invoke PCRE or do a boring strstr
            if(matchRegex)
            {
                int rc;
                if(rc = pcre_exec(matchRegex, 0, line, strlen(line), 0, 0, ovector, sizeof(ovector)) >= 0)
                {
                    matches = true;
                    matchPos = ovector[0];
                    matchLen = ovector[1] - ovector[0];
                }
            }
            else
            {
                char *match;
                if(params_.flags & SF_MATCH_CASE_SENSITIVE)
                    match = strstr(line, params_.match.c_str());
                else
                    match = strstri(line, params_.match.c_str());
                if(match != NULL)
                {
                    matches = true;
                    matchPos = match - line;
                    matchLen = params_.match.length();
                }
            }

            if(matches)
                lineMatched = true;

            // Handle the match. For replace or find, we:
            // * Add output explaining the match
            // * Advance the line pointer for another match attempt
            // ... or ...
            // * "break", which leaves the matching loop
            if(params_.flags & SF_REPLACE)
            {
                if(matches)
                {
                    std::string temp(line, matchPos);
                    replacedLine.append(temp);
                    replacedLine.append(params_.replace);
                    entry.textBlocks.addBlock(temp, config_.textColor_);
                    entry.textBlocks.addBlock(params_.replace, config_.highlightColor_, true);
                    line += matchPos + matchLen;
                }
                else
                {
                    break;
                }
            }
            else
            {
                if(matches)
                {
                    entry.textBlocks.addHighlightedBlock(originalLine, matchPos + (line - originalLine), matchLen, config_.textColor_, config_.highlightColor_, true);
                    line += matchPos + matchLen;
                }
                else
                {
                    break;
                }
            }

            if(matches)
                hits_++;
        }
        while(*line); // end of matching loop

        // If we're doing a replace, finish the line and append to the final updated contents
        if(params_.flags & SF_REPLACE)
        {
            if(line && *line)
            {
                replacedLine += line;
                entry.textBlocks.addBlock(line, config_.textColor_);
            }
            if(hasCarriageReturn)
            {
                replacedLine += "\r";
            }
            replacedLine += "\n";
            updatedContents += replacedLine;
        }

        bool outputMatch = false;
        if(lineMatched)
        {
            // keep stats
            linesWithHits_++;
            atLeastOneMatch = true;

            // If we matched, consider notifying the user. We'll always say something
            // unless the replaced text doesn't actually change the line.
            outputMatch = ( !(params_.flags & SF_REPLACE) ) || (replacedLine != originalLine);

            if(outputMatch)
            {
                entry.filename_ = filename;
                entry.line_ = lineNumber;

                // output all existing context lines
                if(contextLines.size())
                {
                    SearchEntry contextEntry;
                    contextEntry.filename_ = entry.filename_;
                    contextEntry.contextOnly_ = true;
                    int currLine = entry.line_ - contextLines.size();
                    for(std::deque<char *>::iterator it = contextLines.begin(); it != contextLines.end(); ++it)
                    {
                        TextBlockList textBlocks;
                        textBlocks.addBlock(*it, config_.textColor_);
                        contextEntry.textBlocks.swap(textBlocks);
                        contextEntry.line_ = currLine++;
                        append(id, contextEntry);
                    }

                    contextLines.clear();
                }

                append(id, entry);
            }

            // Remember that we'd like the next few lines, even if they don't match
            trailingContextLines = config_.contextLines_;
        }

        if(!outputMatch)
        {
            // Didn't output a match. Keep track or output the line anyway for contextual reasons.

            if(trailingContextLines > 0)
            {
                // A recent match wants to see this line in the output anyway

                SearchEntry trailingEntry;
                trailingEntry.filename_ = filename;
                trailingEntry.line_ = lineNumber;
                trailingEntry.contextOnly_ = true;
                trailingEntry.textBlocks.addBlock(originalLine, config_.textColor_);
                append(id, trailingEntry);
                trailingContextLines--;
            }
            else
            {
                // didn't output a match, and wasn't output as context. stash it in contextLines

                contextLines.push_back(originalLine);
                if((int)contextLines.size() > config_.contextLines_)
                    contextLines.pop_front();
            }
        }

        lineNumber++;
    } // end of line loop (done reading file)

    if(atLeastOneMatch)
        filesWithHits_++;

    if(params_.flags & SF_REPLACE)
    {
        if((contents != updatedContents))
        {
            bool overwriteFile = true;
            if(params_.flags & SF_BACKUP)
            {
                std::string backupFilename = filename;
                backupFilename += ".";
                backupFilename += params_.backupExtension;

                if(!writeEntireFile(backupFilename, contents))
                {
                    std::string err = "WARNING: Couldn't write backup file (skipping replacement): ";
                    err += backupFilename;
                    err += "\n";
                    sendError(id, err);

                    overwriteFile = false;
                }
            }

            if(overwriteFile)
            {
                if(writeEntireFile(filename, updatedContents))
                {
                    return true;
                }
                else
                {
                    std::string err = "WARNING: Couldn't write to file: ";
                    err += filename;
                    err += "\n";
                    sendError(id, err);
                }
            }
        }
        return false;
    }
    return true;
}