Example #1
0
//parse apache access.log entry into components
bool ApacheCombinedLog::parseCommit(RCommit& commit) {

    std::string line;
    std::vector<std::string> matches;

    if(!logf->getNextLine(line)) return false;

    apache_entry_start.match(line, &matches);

    if(matches.size()!=4) {
        return 0;
    }

    //get details
    commit.username = matches[0];
    //std::string user      = matches[1];

    //parse timestamp
    struct tm time_str;

    std::string request_str = matches[3];
    std::string datestr     = matches[2];

    apache_entry_date.match(datestr, &matches);

    if(matches.size()!=8) {
        return 0;
    }

    int day    = atoi(matches[0].c_str());
    int year   = atoi(matches[2].c_str());
    int hour   = atoi(matches[3].c_str());
    int minute = atoi(matches[4].c_str());
    int second = atoi(matches[5].c_str());

//    int zone   = atoi(matches[7].c_str());
    //negative timezone
//    if(strcmp(matches[6].c_str(), "-")==0) {
//        zone = -zone;
//    }

    int month=0;

    for(int i=0;i<12;i++) {
        if(matches[1] == months[i]) {
            month=i;
            break;
        }
    }

    time_str.tm_year = year - 1900;
    time_str.tm_mon  = month;
    time_str.tm_mday = day;
    time_str.tm_hour = hour;
    time_str.tm_min = minute;
    time_str.tm_sec = second;
    time_str.tm_isdst = -1;

    commit.timestamp = mktime(&time_str);

    matches.clear();
    apache_entry_request.match(request_str, &matches);

    if(matches.size() < 5) {
        return false;
    }

    std::string rtype = matches[0];
    std::string file  = matches[1];
    std::string proto = matches[2];

    int code      = atoi(matches[3].c_str());
    int bytes     = atol(matches[4].c_str());

    //remove args from url
    int argpos = file.rfind("?");
    if(argpos != std::string::npos) {
        file = file.substr(0,argpos);
    }

    if(file.size()==0) file = "/";

   //name index pages
    if(file[file.size()-1] == '/') {
        file += "index.html";
    }

    std::string action = "A";
    commit.addFile(file, action);

    std::string refer;
    std::string agent;

    if(matches.size() > 5) {
        std::string agentstr = matches[5];
        matches.clear();
        apache_entry_agent.match(agentstr, &matches);

        if(matches.size()>1) {
            refer     = matches[0];
            agent     = matches[1];
        }
    }

    return true;
}
Example #2
0
bool SVNCommitLog::parseCommit(RCommit& commit) {

    //fprintf(stderr,"parsing svn log\n");

    std::string line;

    if(!getNextLine(line)) return false;

    //start of log entry
    if(!svn_logentry_start.match(line)) {

        //is this the start of the document
        if(!svn_xml_tag.match(line)) return false;

        //fprintf(stderr,"found xml tag\n");

        //if so find the first logentry tag

        bool found_logentry = false;
        
        while(getNextLine(line)) {
            if(svn_logentry_start.match(line)) {
                found_logentry = true;
                break;
            }
        }

        if(!found_logentry) return false;   
    }

    //fprintf(stderr,"found logentry\n");

    logentry.clear();

    logentry.append(line);
    logentry.append("\n");

    //fprintf(stderr,"found opening tag\n");

    bool endfound = false;
    
    while(getNextLine(line)) {
        logentry.append(line);
        logentry.append("\n");
        if(svn_logentry_end.match(line)) {
            //fprintf(stderr,"found closing tag\n");
            endfound=true;
            break;
        }
    }

    //incomplete commit
    if(!endfound) return false;

    //fprintf(stderr,"read logentry\n");

    TiXmlDocument doc;

    if(!doc.Parse(logentry.c_str())) return false;

    //fprintf(stderr,"try to parse logentry: %s\n", logentry.c_str());
    
    TiXmlElement* leE = doc.FirstChildElement( "logentry" );
    
    std::vector<std::string> entries;
    
    if(!leE) return false;

    //parse date
    TiXmlElement* dateE = leE->FirstChildElement( "date" );

    if(!dateE) return false;

    std::string timestamp_str(dateE->GetText());

    if(!svn_logentry_timestamp.match(timestamp_str, &entries))
        return false;
                    
    struct tm time_str;

    time_str.tm_year  = atoi(entries[0].c_str()) - 1900;
    time_str.tm_mon   = atoi(entries[1].c_str()) - 1;
    time_str.tm_mday  = atoi(entries[2].c_str());
    time_str.tm_hour  = atoi(entries[3].c_str());
    time_str.tm_min   = atoi(entries[4].c_str());
    time_str.tm_sec   = atoi(entries[5].c_str());
    time_str.tm_isdst = -1;

    commit.timestamp = timegm(&time_str);            
   
    //parse author
    TiXmlElement* authorE = leE->FirstChildElement("author");
    
    if(authorE != 0) {
    
        std::string author(authorE->GetText());

        if(author.empty()) author = "Unknown";
    
        commit.username = author;
    }

    TiXmlElement* pathsE = leE->FirstChildElement( "paths" );

    //log entries sometimes dont have any paths
    if(!pathsE) return true;

    //parse changes
    
    for(TiXmlElement* pathE = pathsE->FirstChildElement("path"); pathE != 0; pathE = pathE->NextSiblingElement()) {
        //parse path
        
        const char* kind   = pathE->Attribute("kind");
        const char* action = pathE->Attribute("action");

        //check for action
        if(action == 0) continue;

        bool is_dir = false;

        //if has the 'kind' attribute (old versions of svn dont have this), check if it is a dir
        if(kind != 0 && strcmp(kind,"dir") == 0) {

            //accept only deletes for directories
            if(strcmp(action, "D") != 0) continue;

            is_dir = true;
        }

        std::string file(pathE->GetText());
        std::string status(action);       
        
        if(file.empty()) continue;
        if(status.empty()) continue;

        //append trailing slash if is directory
        if(is_dir && file[file.size()-1] != '/') {
            file = file + std::string("/");
        }

        commit.addFile(file, status);
    }
    
    //fprintf(stderr,"parsed logentry\n");

    //read files
    
    return true;
}
Example #3
0
bool CVS2CLCommitLog::parseCommit(RCommit& commit) {

    //fprintf(stderr,"parsing cvs2cl log\n");

    std::string line;

    if(!getNextLine(line)) return false;

    //start of log entry
    if(!cvs2cl_logentry_start.match(line)) {

        //is this the start of the document
        if(!cvs2cl_xml_tag.match(line)) return false;

        //fprintf(stderr,"found xml tag\n");

        //if so find the first logentry tag

        bool found_logentry = false;
        
        while(getNextLine(line)) {
            if(cvs2cl_logentry_start.match(line)) {
                found_logentry = true;
                break;
            }
        }

        if(!found_logentry) return false;   
    }

    //fprintf(stderr,"found logentry\n");

    logentry.clear();

    logentry.append(line);
    logentry.append("\n");

    //fprintf(stderr,"found opening tag\n");

    bool endfound = false;
    
    while(getNextLine(line)) {
        logentry.append(line);
        logentry.append("\n");
        if(cvs2cl_logentry_end.match(line)) {
            //fprintf(stderr,"found closing tag\n");
            endfound=true;
            break;
        }
    }

    //incomplete commit
    if(!endfound) return false;

    //fprintf(stderr,"read logentry\n");

    TiXmlDocument doc;

    if(!doc.Parse(logentry.c_str())) return false;

    //fprintf(stderr,"try to parse logentry: %s\n", logentry.c_str());
    
    TiXmlElement* leE = doc.FirstChildElement( "entry" );
    
    std::vector<std::string> entries;
    
    if(!leE) return false;

    //parse date
    TiXmlElement* dateE = leE->FirstChildElement( "isoDate" );

    if(!dateE) return false;

    std::string timestamp_str(dateE->GetText());

    if(!cvs2cl_logentry_timestamp.match(timestamp_str, &entries))
        return false;
                    
    struct tm time_str;

    time_str.tm_year  = atoi(entries[0].c_str()) - 1900;
    time_str.tm_mon   = atoi(entries[1].c_str()) - 1;
    time_str.tm_mday  = atoi(entries[2].c_str());
    time_str.tm_hour  = atoi(entries[3].c_str());
    time_str.tm_min   = atoi(entries[4].c_str());
    time_str.tm_sec   = atoi(entries[5].c_str());
    time_str.tm_isdst = -1;

    commit.timestamp = mktime(&time_str);            
   
    //parse author
    TiXmlElement* authorE = leE->FirstChildElement("author");
    
    if(authorE != 0) {
    
        std::string author(authorE->GetText());

        if(author.empty()) author = "Unknown";
    
        commit.username = author;
    }

    //parse changes
    
    for(TiXmlElement* fileE = leE->FirstChildElement("file"); fileE != 0; fileE = fileE->NextSiblingElement()) {
        
        TiXmlElement* state = fileE->FirstChildElement("cvsstate");
        TiXmlElement* name  = fileE->FirstChildElement("name");

        //check for state
        if(name == 0 || state == 0) continue;

        std::string status = strcmp(state->GetText(), "dead") == 0 ? "D" : "M";
        std::string file(name->GetText());

        if(file.empty()) continue;
        
        commit.addFile(file, status);
    }
    
    //fprintf(stderr,"parsed logentry\n");

    //read files
    
    return true;
}
Example #4
0
bool GitCommitLog::parseCommit(RCommit& commit) {

    std::string line;
    char filesizeBuf[256];

    commit.username = "";

    while(logf->getNextLine(line) && line.size()) {

        if(line.find("commit_id:") == 0) {
           commit.commit_id = line.substr(10); 

           if(!logf->getNextLine(line)) return false;

            //username follows user prefix
            commit.username = line.substr(5);

            if(!logf->getNextLine(line)) return false;

            commit.timestamp = atol(line.c_str());

            //this isnt a commit we are parsing, abort
            if(commit.timestamp == 0) return false;

            continue;
        }

        //should see username before files
        if(commit.username.empty()) return false;

        size_t tab = line.find('\t');

        //incorrect log format
        if(tab == std::string::npos || tab == 0 || tab == line.size()-1) continue;

        std::string status = line.substr(tab - 1, 1);
        std::string file   = line.substr(tab + 1);

        if(file.empty()) continue;

        //check for and remove double quotes
        if(file.find('"') == 0 && file.rfind('"') == file.size()-1) {
            if(file.size()<=2) continue;

            file = file.substr(1,file.size()-2);
        }


        std::string size_temp_file = temp_file + "_filesize";

        memset(filesizeBuf, 0, sizeof(char) * 256);
        snprintf(filesizeBuf, sizeof(char) * 256, GitGetFileSizeCommand.c_str(), commit.commit_id.c_str(), file.c_str(), size_temp_file.c_str());

        systemCommand(filesizeBuf);

        std::ifstream ifs ( size_temp_file );
        std::string filesize_str;
        ifs >> filesize_str;

        size_t filesize = 0;
        if(!filesize_str.empty()) {
            filesize = std::stoi(filesize_str);
        }

        commit.addFile(file, status, filesize);
    }

    //check we at least got a username
    if(commit.username.empty()) return false;

    return true;
}