bool Condor_Auth_X509::CheckServerName(char const *fqh,char const *ip,ReliSock *sock,CondorError *errstack)
{
	if( param_boolean("GSI_SKIP_HOST_CHECK",false) ) {
		return true;
	}

	char const *server_dn = getAuthenticatedName();
	if( !server_dn ) {
		std::string msg;
		formatstr(msg,"Failed to find certificate DN for server on GSI connection to %s",ip);
		errstack->push("GSI", GSI_ERR_DNS_CHECK_ERROR, msg.c_str());
		return false;
	}

	std::string skip_check_pattern;
	if( param(skip_check_pattern,"GSI_SKIP_HOST_CHECK_CERT_REGEX") ) {
		Regex re;
		const char *errptr=NULL;
		int erroffset=0;
		std::string full_pattern;
		formatstr(full_pattern,"^(%s)$",skip_check_pattern.c_str());
		if( !re.compile(full_pattern.c_str(),&errptr,&erroffset) ) {
			dprintf(D_ALWAYS,"GSI_SKIP_HOST_CHECK_CERT_REGEX is not a valid regular expression: %s\n",skip_check_pattern.c_str());
			return false;
		}
		if( re.match(server_dn,NULL) ) {
			return true;
		}
	}

	ASSERT( errstack );
	ASSERT( m_gss_server_name );
	ASSERT( ip );
	if( !fqh || !fqh[0] ) {
		std::string msg;
		formatstr(msg,"Failed to look up server host address for GSI connection to server with IP %s and DN %s.  Is DNS correctly configured?  This server name check can be bypassed by making GSI_SKIP_HOST_CHECK_CERT_REGEX match the DN, or by disabling all hostname checks by setting GSI_SKIP_HOST_CHECK=true or defining GSI_DAEMON_NAME.",ip,server_dn);
		errstack->push("GSI", GSI_ERR_DNS_CHECK_ERROR, msg.c_str());
		return false;
	}

	std::string connect_name;
	gss_buffer_desc gss_connect_name_buf;
	gss_name_t gss_connect_name;
	OM_uint32 major_status = 0;
	OM_uint32 minor_status = 0;

	char const *connect_addr = sock->get_connect_addr();
	std::string alias_buf;
	if( connect_addr ) {
		Sinful s(connect_addr);
		char const *alias = s.getAlias();
		if( alias ) {
			dprintf(D_FULLDEBUG,"GSI host check: using host alias %s for %s %s\n",alias,fqh,sock->peer_ip_str());
			alias_buf = alias;
			fqh = alias_buf.c_str();
		}
	}

	formatstr(connect_name,"%s/%s",fqh,sock->peer_ip_str());

	gss_connect_name_buf.value = strdup(connect_name.c_str());
	gss_connect_name_buf.length = connect_name.size()+1;

	major_status = gss_import_name(&minor_status,
								   &gss_connect_name_buf,
								   GLOBUS_GSS_C_NT_HOST_IP,
								   &gss_connect_name);

	free( gss_connect_name_buf.value );

	if( major_status != GSS_S_COMPLETE ) {
		std::string comment;
		formatstr(comment,"Failed to create gss connection name data structure for %s.\n",connect_name.c_str());
		print_log( major_status, minor_status, 0, comment.c_str() );
		return false;
	}

	int name_equal = 0;
	major_status = gss_compare_name( &minor_status,
									 m_gss_server_name,
									 gss_connect_name,
									 &name_equal );

	gss_release_name( &major_status, &gss_connect_name );

	if( !name_equal ) {
		std::string msg;
		formatstr(msg,"We are trying to connect to a daemon with certificate DN (%s), but the host name in the certificate does not match any DNS name associated with the host to which we are connecting (host name is '%s', IP is '%s', Condor connection address is '%s').  Check that DNS is correctly configured.  If the certificate is for a DNS alias, configure HOST_ALIAS in the daemon's configuration.  If you wish to use a daemon certificate that does not match the daemon's host name, make GSI_SKIP_HOST_CHECK_CERT_REGEX match the DN, or disable all host name checks by setting GSI_SKIP_HOST_CHECK=true or by defining GSI_DAEMON_NAME.\n",
				server_dn,
				fqh,
				ip,
				connect_addr ? connect_addr : sock->peer_description() );
		errstack->push("GSI", GSI_ERR_DNS_CHECK_ERROR, msg.c_str());
	}
	return name_equal != 0;
}
Example #2
0
void FormatHTMLChunk(TreeBuilder &treeBuilder,const char *buffer, size_t count)
{
    RegexMatch match;

 
    while (regexElementFinder.Match(buffer, count, match))
    {
        PrintMatches("link finder ", buffer, match);
        FormatString(treeBuilder, buffer, match.End(1));
        bool close = (match.Start(2) != match.End(2));
        bool hasAttrs = (match.Start(4) != match.End(4));
        string tagname(buffer + match.Start(3), match.Length(3));
        size_t pos;
        for (pos = 0; pos < tagname.length() && !isspace(tagname[pos]); ++pos)
        {}
        if (pos < tagname.length())
        {
            tagname.erase(pos, string::npos);
        }

        if (close)
        {
            treeBuilder.Pop(tagname);
        }
        else
        {
            ParseTreeNodePtr node(treeBuilder.NodeFactory(tagname));
            treeBuilder.Push(node);
            if (hasAttrs)
            {
                RegexMatch attrMatch;
                const char *attrs = buffer + match.Start(4);
                int attrLength = match.Length(4);
//                printf("Attrs: %.*s\n", attrLength, attrs);

                while (regexAttrMatch1.Match(attrs, attrLength, attrMatch)
                       || regexAttrMatch2.Match(attrs, attrLength, attrMatch)
                       || regexAttrMatch3.Match(attrs, attrLength, attrMatch))
                {
                    PrintMatches("Attributes",attrs,attrMatch);
                    string attr(attrs + attrMatch.Start(1), attrMatch.Length(1));
                    treeBuilder.CurrentNode()->AddAttribute(attr.c_str());
//                    string val(attrs + attrMatch.Start(2), attrMatch.Length(2));
//                    treeBuilder.CurrentNode()->AddAttributeValue(val.c_str());
                    FormatAttribute(treeBuilder.CurrentNode(),
                                    attrs + attrMatch.Start(2), attrMatch.Length(2));
                    attrs += attrMatch.End(3);
                    attrLength -= attrMatch.End(3);
                }
                if (match.Start(5) != match.End(5))
                {
                    treeBuilder.Pop();
                }
            }
        }
        buffer += match.End(6);
        count -= match.End(6);
    }
    FormatString(treeBuilder, buffer, count);

}
Example #3
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 #4
0
void MachAttributes::init_machine_resources() {
    // defines the space of local machine resources, and their quantity
    m_machres_map.clear();

    // this may be filled from resource inventory scripts
    m_machres_attr.Clear();

    // these are reserved for standard/fixed resources
    std::set<string> fixedRes;
    fixedRes.insert("cpu");
    fixedRes.insert("cpus");
    fixedRes.insert("disk");
    fixedRes.insert("swap");
    fixedRes.insert("mem");
    fixedRes.insert("memory");
    fixedRes.insert("ram");

    // get the list of defined local resource names:
    char* ptmp = param("MACHINE_RESOURCE_NAMES");
    string resnames;
    if (NULL != ptmp) {
        // if admin defined MACHINE_RESOURCE_NAMES, then use this list
        // as the source of expected custom machine resources
        resnames = ptmp;
        free(ptmp);
    } else {
        // otherwise, build the list of custom machine resources from
        // all occurrences of MACHINE_RESOURCE_<resname>
        std::set<string> resset;
        Regex re;
        int err = 0;
        const char* pszMsg = 0;
        const string prefix = "MACHINE_RESOURCE_";
        const string invprefix = "INVENTORY_";
        const string restr = prefix + "(.+)";
        ASSERT(re.compile(restr.c_str(), &pszMsg, &err, PCRE_CASELESS));
	std::vector<std::string> resdef;
        const int n = param_names_matching(re, resdef);
        for (int j = 0;  j < n;  ++j) {
            string rname = resdef[j].substr(prefix.length());
            string testinv = rname.substr(0, invprefix.length());
            if (0 == strcasecmp(testinv.c_str(), invprefix.c_str())) {
                // if something was defined via MACHINE_RESOURCE_INVENTORY_<rname>, strip "INVENTORY_"
                rname = rname.substr(invprefix.length());
            }
            std::transform(rname.begin(), rname.end(), rname.begin(), ::tolower);
            resset.insert(rname);
        }
        for (std::set<string>::iterator j(resset.begin());  j != resset.end();  ++j) {
            resnames += " ";
            resnames += *j;
        }
    }

    // scan the list of local resources, to obtain their quantity and associated attributes (if any)
    StringList reslist(resnames.c_str());
    reslist.rewind();
    while (const char* rnp = reslist.next()) {
        string rname(rnp);
        std::transform(rname.begin(), rname.end(), rname.begin(), ::tolower);
        if (fixedRes.count(rname) > 0) {
            EXCEPT("pre-defined resource name '%s' is reserved", rname.c_str());
        }

        // If MACHINE_RESOURCE_<rname> is present, use that and move on:
        string pname;
        formatstr(pname, "MACHINE_RESOURCE_%s", rname.c_str());
        char* machresp = param(pname.c_str());
        if (machresp) {
            int v = param_integer(pname.c_str(), 0, 0, INT_MAX);
            m_machres_map[rname] = v;
            free(machresp);
            continue;
        }

        // current definition of REMIND macro is not working with gcc
        #pragma message("MACHINE_RESOURCE_INVENTORY_<rname> is deprecated, and will be removed when a solution using '|' in config files is fleshed out")
        // if we didn't find MACHINE_RESOURCE_<rname>, then try MACHINE_RESOURCE_INVENTORY_<rname>
        formatstr(pname, "MACHINE_RESOURCE_INVENTORY_%s", rname.c_str());
        char* invscriptp = param(pname.c_str());
        if (NULL == invscriptp) {
            EXCEPT("Missing configuration for local machine resource %s", rname.c_str());
        }

        // if there is an inventory script, then attempt to execute it and use its output to
        // identify the local resource quantity, and any associated attributes:
        string invscript = invscriptp;
        free(invscriptp);

        ArgList invcmd;
        StringList invcmdal(invscript.c_str());
        invcmdal.rewind();
        while (char* invarg = invcmdal.next()) {
            invcmd.AppendArg(invarg);
        }
        FILE* fp = my_popen(invcmd, "r", FALSE);
        if (NULL == fp) {
            EXCEPT("Failed to execute local resource inventory script \"%s\"\n", invscript.c_str());
        }

        ClassAd invad;
        char invline[1000];
        while (fgets(invline, sizeof(invline), fp)) {
            if (!invad.Insert(invline)) {
                dprintf(D_ALWAYS, "Failed to insert \"%s\" into machine resource attributes: ignoring\n", invline);
            }
        }
        my_pclose(fp);

        // require the detected machine resource to be present as an attribute
        string ccname(rname.c_str());
        *(ccname.begin()) = toupper(*(ccname.begin()));
        string detname;
        formatstr(detname, "%s%s", ATTR_DETECTED_PREFIX, ccname.c_str());
        int v = 0;
        if (!invad.LookupInteger(detname.c_str(), v)) {
            EXCEPT("Missing required attribute \"%s = <n>\" from output of %s\n", detname.c_str(),  invscript.c_str());
        }

        // success
        m_machres_map[rname] = v;
        invad.Delete(rname.c_str());
        m_machres_attr.Update(invad);
    }

    for (slotres_map_t::iterator j(m_machres_map.begin());  j != m_machres_map.end();  ++j) {
        dprintf(D_ALWAYS, "Local machine resource %s = %d\n", j->first.c_str(), int(j->second));
    }
}
Example #5
0
//parse NCSA format access.log entry into components
bool NCSALog::parseLine(std::string& line, LogEntry& entry) {

    std::vector<std::string> matches;
    ls_ncsa_entry_start.match(line, &matches);

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

    //get details
    entry.vhost    = matches[0];
    entry.hostname = matches[1];
    //entry.username = matches[1];

    //parse timestamp
    struct tm time_str;

    int day, month, year, hour, minute, second;

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

    matches.clear();
    ls_ncsa_entry_date.match(datestr, &matches);

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

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

    if(month) {
        month--;
    } else {
        //parse non numeric month
        for(int i=0;i<12;i++) {
            if(strcmp(matches[1].c_str(), ls_ncsa_months[i])==0) {
                month=i;
                break;
            }
        }
    }

    //could not parse month (range 0-11 as used by mktime)
    if(month<0 || month>11) return 0;
    
    int tz_offset = 0;

    //there is a timezone delta
    if (matches.size() == 8) {

        //convert zone to utc offset
        int tz_hour = atoi(matches[7].substr(0,2).c_str());
        int tz_min  = atoi(matches[7].substr(2,2).c_str());

        tz_offset = tz_hour * 3600 + tz_min * 60;

        if(matches[6] == "-") {
            tz_offset = -tz_offset;
        }
    }

    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;

    entry.timestamp = mktime(&time_str);

    //apply utc offset
    entry.timestamp -= tz_offset;

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

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

//    entry.method    = matches[0];
    entry.path      = matches[1];
//    entry.protocol  = matches[2];

    entry.response_code = matches[3].c_str();
    entry.response_size = atol(matches[4].c_str());

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

        if(matches.size()==3) {
            entry.referrer   = matches[0];
            entry.user_agent = matches[1];
            entry.pid        = matches[2];
        }
    }

    //successful if response code less than 400
    int code = atoi(entry.response_code.c_str());

    entry.setSuccess();
    entry.setResponseColour();

    return entry.validate();
}
bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut )
{
	ASSERT_M( NOTESKIN != NULL, "The Noteskin Manager must be loaded in order to process mods." );

	RString sBit = sOneMod;
	sBit.MakeLower();
	Trim( sBit );

	/* "drunk"
	 * "no drunk"
	 * "150% drunk"
	 * "*2 100% drunk": approach at 2x normal speed */

	float level = 1;
	float speed = 1;
	vector<RString> asParts;
	split( sBit, " ", asParts, true );

	FOREACH_CONST( RString, asParts, s )
	{
		if( *s == "no" )
		{
			level = 0;
		}
		else if( isdigit((*s)[0]) || (*s)[0] == '-' )
		{
			/* If the last character is a *, they probably said "123*" when
			 * they meant "*123". */
			if( s->Right(1) == "*" )
			{
				// XXX: We know what they want, is there any reason not to handle it?
				// Yes. We should be strict in handling the format. -Chris
				sErrorOut = ssprintf("Invalid player options \"%s\"; did you mean '*%d'?", s->c_str(), StringToInt(*s) );
				return false;
			}
			else
			{
				level = StringToFloat( *s ) / 100.0f;
			}
		}
		else if( *s[0]=='*' )
		{
			sscanf( *s, "*%f", &speed );
			if( !isfinite(speed) )
				speed = 1.0f;
		}
	}

	sBit = asParts.back();

#define SET_FLOAT( opt ) { m_ ## opt = level; m_Speed ## opt = speed; }
	const bool on = (level > 0.5f);

	static Regex mult("^([0-9]+(\\.[0-9]+)?)x$");
	vector<RString> matches;
	if( mult.Compare(sBit, matches) )
	{
		StringConversion::FromString( matches[0], level );
		SET_FLOAT( fScrollSpeed )
		SET_FLOAT( fTimeSpacing )
		m_fTimeSpacing = 0;
		m_fMaxScrollBPM = 0;
	}
	else if( sscanf( sBit, "c%f", &level ) == 1 )
	{
		if( !isfinite(level) || level <= 0.0f )
			level = CMOD_DEFAULT;
		SET_FLOAT( fScrollBPM )
		SET_FLOAT( fTimeSpacing )
		m_fTimeSpacing = 1;
		m_fMaxScrollBPM = 0;
	}
	// oITG's m-mods
	else if( sscanf( sBit, "m%f", &level ) == 1 )
	{
		// OpenITG doesn't have this block:
		/*
		if( !isfinite(level) || level <= 0.0f )
			level = CMOD_DEFAULT;
		*/
		SET_FLOAT( fMaxScrollBPM )
		m_fTimeSpacing = 0;
	}

	else if( sBit == "clearall" )
	{
		Init();
		m_sNoteSkin= NOTESKIN->GetDefaultNoteSkinName();
	}
	else if( sBit == "resetspeed" )
	{
		/* level is set to the values from Init() because all speed related
		   fields are being reset to initial values, and they each have different
		   initial values.  -kyz */
		level= 0;
		SET_FLOAT(fMaxScrollBPM);
		SET_FLOAT(fTimeSpacing);
		level= 1.0f;
		SET_FLOAT(fScrollSpeed);
		level= CMOD_DEFAULT;
		SET_FLOAT(fScrollBPM)
	}
Example #7
0
int main(int argc, char** argv) {
  time_t currentTime = time(0);
  fprintf(stderr, "Analysis started at: %s", ctime(&currentTime));

  PARSE_PARAMETER(argc, argv);
  PARAMETER_STATUS();

  if (FLAG_REMAIN_ARG.size() > 0) {
    fprintf(stderr, "Unparsed arguments: ");
    for (unsigned int i = 0; i < FLAG_REMAIN_ARG.size(); i++) {
      fprintf(stderr, " %s", FLAG_REMAIN_ARG[i].c_str());
    }
    fprintf(stderr, "\n");
    abort();
  }

  REQUIRE_STRING_PARAMETER(FLAG_inVcf,
                           "Please provide input file using: --inVcf");

  const char* fn = FLAG_inVcf.c_str();
  VCFInputFile vin(fn);

  // set range filters here
  // e.g.
  // vin.setRangeList("1:69500-69600");
  vin.setRangeList(FLAG_rangeList.c_str());
  vin.setRangeFile(FLAG_rangeFile.c_str());

  // set people filters here
  if (FLAG_peopleIncludeID.size() || FLAG_peopleIncludeFile.size()) {
    vin.excludeAllPeople();
    vin.includePeople(FLAG_peopleIncludeID.c_str());
    vin.includePeopleFromFile(FLAG_peopleIncludeFile.c_str());
  }
  vin.excludePeople(FLAG_peopleExcludeID.c_str());
  vin.excludePeopleFromFile(FLAG_peopleExcludeFile.c_str());

  // let's write it out.
  if (FLAG_updateId != "") {
    int ret = vin.updateId(FLAG_updateId.c_str());
    fprintf(stdout, "%d samples have updated id.\n", ret);
  }

  // load gene ranges
  std::map<std::string, std::string> geneRange;
  if (FLAG_geneName.size()) {
    if (FLAG_geneFile.size() == 0) {
      fprintf(stderr, "Have to provide --geneFile to extract by gene.\n");
      abort();
    }
    LineReader lr(FLAG_geneFile);
    std::vector<std::string> fd;
    while (lr.readLineBySep(&fd, "\t ")) {
      if (FLAG_geneName != fd[0]) continue;
      fd[2] = chopChr(fd[2]);  // chop "chr1" to "1"
      if (geneRange.find(fd[0]) == geneRange.end()) {
        geneRange[fd[0]] = fd[2] + ":" + fd[4] + "-" + fd[5];
      } else {
        geneRange[fd[0]] += "," + fd[2] + ":" + fd[4] + "-" + fd[5];
      }
    };
  }
  std::string range;
  for (std::map<std::string, std::string>::iterator it = geneRange.begin();
       it != geneRange.end(); it++) {
    if (range.size() > 0) {
      range += ",";
    }
    range += it->second;
  };
  fprintf(stderr, "range = %s\n", range.c_str());
  vin.setRangeList(range.c_str());

  Regex regex;
  if (FLAG_annoType.size()) {
    regex.readPattern(FLAG_annoType);
  }

  // print header
  std::vector<std::string> names;
  vin.getVCFHeader()->getPeopleName(&names);
  printf("CHROM\tPOS");
  for (unsigned int i = 0; i < names.size(); i++) {
    printf("\t%s", names[i].c_str());
  }
  printf("\n");

  // real working part
  int nonVariantSite = 0;
  while (vin.readRecord()) {
    VCFRecord& r = vin.getVCFRecord();
    VCFPeople& people = r.getPeople();
    VCFIndividual* indv;
    if (FLAG_variantOnly) {
      bool hasVariant = false;
      int geno;
      int GTidx = r.getFormatIndex("GT");
      for (size_t i = 0; i < people.size(); i++) {
        indv = people[i];
        geno = indv->justGet(GTidx).getGenotype();
        if (geno != 0 && geno != MISSING_GENOTYPE) hasVariant = true;
      }
      if (!hasVariant) {
        nonVariantSite++;
        continue;
      }
    }

    if (FLAG_annoType.size()) {
      bool isMissing = false;
      const char* tag = r.getInfoTag("ANNO", &isMissing).toStr();
      if (isMissing) continue;
      // fprintf(stdout, "ANNO = %s", tag);
      bool match = regex.match(tag);
      // fprintf(stdout, " %s \t", match ? "match": "noMatch");
      // fprintf(stdout, " %s \n", exists ? "exists": "missing");
      if (!match) {
        continue;
      }
    }

    fprintf(stdout, "%s\t%s", r.getChrom(), r.getPosStr());

    for (size_t i = 0; i < people.size(); i++) {
      indv = people[i];
      fprintf(stdout, "\t%d", indv->justGet(0).getGenotype());
    }
    fprintf(stdout, "\n");
  };

  currentTime = time(0);
  fprintf(stderr, "Analysis ends at: %s", ctime(&currentTime));

  return 0;
};
Example #8
0
void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const CString &sTexturePath, const CString &sPageName, CString sChars )
{
	cfg.m_sTexturePath = sTexturePath;

	/* If we have any characters to map, add them. */
	for( unsigned n=0; n<sChars.size(); n++ )
	{
		char c = sChars[n];
		cfg.CharToGlyphNo[c] = n;
	}
	int iNumFramesWide, iNumFramesHigh;
	RageTexture::GetFrameDimensionsFromFileName( sTexturePath, &iNumFramesWide, &iNumFramesHigh );
	int iNumFrames = iNumFramesWide * iNumFramesHigh;
	
	ini.RenameKey("Char Widths", "main");

//	LOG->Trace("Loading font page '%s' settings from page name '%s'",
//		TexturePath.c_str(), sPageName.c_str());
	
	ini.GetValue( sPageName, "DrawExtraPixelsLeft", cfg.m_iDrawExtraPixelsLeft );
	ini.GetValue( sPageName, "DrawExtraPixelsRight", cfg.m_iDrawExtraPixelsRight );
	ini.GetValue( sPageName, "AddToAllWidths", cfg.m_iAddToAllWidths );
	ini.GetValue( sPageName, "ScaleAllWidthsBy", cfg.m_fScaleAllWidthsBy );
	ini.GetValue( sPageName, "LineSpacing", cfg.m_iLineSpacing );
	ini.GetValue( sPageName, "Top", cfg.m_iTop );
	ini.GetValue( sPageName, "Baseline", cfg.m_iBaseline );
	ini.GetValue( sPageName, "DefaultWidth", cfg.m_iDefaultWidth );
	ini.GetValue( sPageName, "AdvanceExtraPixels", cfg.m_iAdvanceExtraPixels );
	ini.GetValue( sPageName, "TextureHints", cfg.m_sTextureHints );

	/* Iterate over all keys. */
	const XNode* pNode = ini.GetChild( sPageName );
	if( pNode )
	{
		FOREACH_CONST_Attr( pNode, pAttr )
		{
			CString sName = pAttr->m_sName;
			const CString &sValue = pAttr->m_sValue;

			sName.MakeUpper();

			/* If val is an integer, it's a width, eg. "10=27". */
			if( IsAnInt(sName) )
			{
				cfg.m_mapGlyphWidths[atoi(sName)] = atoi( sValue );
				continue;
			}

			/* "map codepoint=frame" maps a char to a frame. */
			if( sName.substr(0, 4) == "MAP " )
			{
				/*
				 * map CODEPOINT=frame. CODEPOINT can be
				 * 1. U+hexval
				 * 2. an alias ("oq")
				 * 3. a game type followed by a game alias, eg "pump menuleft"
				 * 4. a character in quotes ("X")
				 *
				 * map 1=2 is the same as
				 * range unicode #1-1=2
				 */
				CString sCodepoint = sName.substr(4); /* "CODEPOINT" */
			
				const Game* pGame = NULL;

				if( sCodepoint.find_first_of(' ') != sCodepoint.npos )
				{
					/* There's a space; the first word should be a game type. Split it. */
					unsigned pos = sCodepoint.find_first_of( ' ' );
					CString gamename = sCodepoint.substr( 0, pos );
					sCodepoint = sCodepoint.substr( pos+1 );

					pGame = GameManager::StringToGameType(gamename);

					if( pGame == NULL )
					{
						LOG->Warn( "Font definition '%s' uses unknown game type '%s'",
							ini.GetPath().c_str(), gamename.c_str() );
						continue;
					}
				}

				wchar_t c;
				if( sCodepoint.substr(0, 2) == "U+" && IsHexVal(sCodepoint.substr(2)) )
					sscanf( sCodepoint.substr(2).c_str(), "%x", &c );
				else if( sCodepoint.size() > 0 &&
						utf8_get_char_len(sCodepoint[0]) == int(sCodepoint.size()) )
				{
					c = utf8_get_char( sCodepoint.c_str() );
					if(c == wchar_t(-1))
						LOG->Warn("Font definition '%s' has an invalid value '%s'.",
							ini.GetPath().c_str(), sName.c_str() );
				}
				else if( !FontCharAliases::GetChar(sCodepoint, c) )
				{
					LOG->Warn("Font definition '%s' has an invalid value '%s'.",
						ini.GetPath().c_str(), sName.c_str() );
					continue;
				}

				cfg.CharToGlyphNo[c] = atoi( sValue );

				continue;
			}

			if( sName.substr(0, 6) == "RANGE " )
			{
				/*
				 * range CODESET=first_frame or
				 * range CODESET #start-end=first_frame
				 * eg
				 * range CP1252=0       (default for 256-frame fonts)
				 * range ASCII=0        (default for 128-frame fonts)
				 *
				 * (Start and end are in hex.)
				 *
				 * Map two high-bit portions of ISO-8859- to one font:
				 * range ISO-8859-2 #80-FF=0
				 * range ISO-8859-3 #80-FF=128
				 *
				 * Map hiragana to 0-84:
				 * range Unicode #3041-3094=0
				 */
				vector<CString> asMatches;
				static Regex parse("^RANGE ([A-Z\\-]+)( ?#([0-9A-F]+)-([0-9A-F]+))?$");
				bool bMatch = parse.Compare( sName, asMatches );
				
				ASSERT( asMatches.size() == 4 ); /* 4 parens */

				if( !bMatch || asMatches[0].empty() )
					RageException::Throw("Font definition '%s' has an invalid range '%s': parse error",
						ini.GetPath().c_str(), sName.c_str() );
				
				/* We must have either 1 match (just the codeset) or 4 (the whole thing). */

				int iCount = -1;
				int iFirst = 0;
				if( !asMatches[2].empty() )
				{
					sscanf( asMatches[2].c_str(), "%x", &iFirst );
					int iLast;
					sscanf( asMatches[3].c_str(), "%x", &iLast );
					if( iLast < iFirst )
						RageException::Throw("Font definition '%s' has an invalid range '%s': %i < %i.",
							ini.GetPath().c_str(), sName.c_str(), iLast < iFirst );

					iCount = iLast - iFirst + 1;
				}

				CString sRet = cfg.MapRange( asMatches[0], iFirst, atoi(sValue), iCount );
				if( !sRet.empty() )
					RageException::Throw( "Font definition '%s' has an invalid range '%s': %s.",
						ini.GetPath().c_str(), sName.c_str(), sRet.c_str() );

				continue;
			}

			if( sName.substr(0, 5) == "LINE " )
			{
				/* line ROW=CHAR1CHAR2CHAR3CHAR4
				 * eg.
				 * line 0=ABCDEFGH
				 *
				 * This lets us assign characters very compactly and readably. */

				CString sRowStr = sName.substr(5);
				ASSERT( IsAnInt(sRowStr) );
				const int iRow = atoi( sRowStr.c_str() );
				const int iFirstFrame = iRow * iNumFramesWide;

				if( iRow > iNumFramesHigh )
					RageException::Throw( "The font definition \"%s\" tries to assign line %i, but the font is only %i characters high",
						ini.GetPath().c_str(), iFirstFrame, iNumFramesHigh );

				/* Decode the string. */
				const wstring wdata( CStringToWstring(sValue) );

				if( int(wdata.size()) > iNumFramesWide )
					RageException::Throw( "The font definition \"%s\" assigns %i characters to row %i (\"%ls\"), but the font only has %i characters wide",
						ini.GetPath().c_str(), wdata.size(), iRow, wdata.c_str(), iNumFramesWide );

				for( unsigned i = 0; i < wdata.size(); ++i )
					cfg.CharToGlyphNo[wdata[i]] = iFirstFrame+i;
			}
		}
	}
Example #9
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 #10
0
void Perl_stack::push(const Regex& regex) {
    XPUSHs(sv_2mortal(SvREFCNT_inc(regex.get_SV())));
}
Example #11
0
SandboxVector SandboxUtils::findSandboxes(Module& M) {
  FunctionIntMap funcToOverhead;
  FunctionIntMap funcToClearances;
  map<Function*,string> funcToSandboxName;
  map<string,FunctionSet> sandboxNameToEntryPoints;
  StringSet ephemeralSandboxes;

  SandboxVector sandboxes;

  // function-level annotations of sandboxed code
  Regex *sboxPerfRegex = new Regex("perf_overhead_\\(([0-9]{1,2})\\)", true);
  SmallVector<StringRef, 4> matches;
  if (GlobalVariable* lga = M.getNamedGlobal("llvm.global.annotations")) {
    ConstantArray* lgaArray = dyn_cast<ConstantArray>(lga->getInitializer()->stripPointerCasts());
    for (User::op_iterator i=lgaArray->op_begin(), e = lgaArray->op_end(); e!=i; i++) {
      ConstantStruct* lgaArrayElement = dyn_cast<ConstantStruct>(i->get());

      // get the annotation value first
      GlobalVariable* annotationStrVar = dyn_cast<GlobalVariable>(lgaArrayElement->getOperand(1)->stripPointerCasts());
      ConstantDataArray* annotationStrArray = dyn_cast<ConstantDataArray>(annotationStrVar->getInitializer());
      StringRef annotationStrArrayCString = annotationStrArray->getAsCString();
      GlobalValue* annotatedVal = dyn_cast<GlobalValue>(lgaArrayElement->getOperand(0)->stripPointerCasts());
      if (isa<Function>(annotatedVal)) {
        Function* annotatedFunc = dyn_cast<Function>(annotatedVal);
        StringRef sandboxName;
        if (annotationStrArrayCString.startswith(SANDBOX_PERSISTENT) || annotationStrArrayCString.startswith(SANDBOX_EPHEMERAL)) {
          sandboxEntryPoints.insert(annotatedFunc);
          outs() << INDENT_1 << "Found sandbox entrypoint " << annotatedFunc->getName() << "\n";
          outs() << INDENT_2 << "Annotation string: " << annotationStrArrayCString << "\n";
          if (annotationStrArrayCString.startswith(SANDBOX_PERSISTENT)) {
            sandboxName = annotationStrArrayCString.substr(strlen(SANDBOX_PERSISTENT)+1);
          }
          else if (annotationStrArrayCString.startswith(SANDBOX_EPHEMERAL)) {
            sandboxName = annotationStrArrayCString.substr(strlen(SANDBOX_EPHEMERAL)+1);
            ephemeralSandboxes.insert(sandboxName);
          }
          outs() << INDENT_2 << "Sandbox name: " << sandboxName << "\n";
          if (funcToSandboxName.find(annotatedFunc) != funcToSandboxName.end()) {
            outs() << INDENT_1 << "*** Error: Function " << annotatedFunc->getName() << " is already an entrypoint for another sandbox\n";
          }
          else {
            funcToSandboxName[annotatedFunc] = sandboxName;
            sandboxNameToEntryPoints[sandboxName].insert(annotatedFunc);
          }
        }
        else if (sboxPerfRegex->match(annotationStrArrayCString, &matches)) {
          int overhead;
          outs() << INDENT_2 << "Threshold set to " << matches[1].str() <<
                  "%\n";
          matches[1].getAsInteger(0, overhead);
          funcToOverhead[annotatedFunc] = overhead;
        }
        else if (annotationStrArrayCString.startswith(CLEARANCE)) {
          StringRef className = annotationStrArrayCString.substr(strlen(CLEARANCE)+1);
          outs() << INDENT_2 << "Sandbox has clearance for \"" << className << "\"\n";
          ClassifiedUtils::assignBitIdxToClassName(className);
          funcToClearances[annotatedFunc] |= (1 << ClassifiedUtils::getBitIdxFromClassName(className));
        }
      }
    }
  }

  // TODO: sanity check overhead and clearance annotations

  // Combine all annotation information for function-level sandboxes to create Sandbox instances
  for (pair<string,FunctionSet> p : sandboxNameToEntryPoints) {
    string sandboxName = p.first;
    FunctionSet entryPoints = p.second;
    int idx = assignBitIdxToSandboxName(sandboxName);
    int overhead = 0;
    int clearances = 0; 
    bool persistent = find(ephemeralSandboxes.begin(), ephemeralSandboxes.end(), sandboxName) == ephemeralSandboxes.end();

    // set overhead and clearances; any of the entry points could be annotated
    for (Function* entryPoint : entryPoints) {
      if (funcToOverhead.find(entryPoint) != funcToOverhead.end()) {
        overhead = funcToOverhead[entryPoint];
      }
      if (funcToClearances.find(entryPoint) != funcToClearances.end()) {
        clearances = funcToClearances[entryPoint];
      }
    }

		SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Creating new Sandbox instance for " << sandboxName << "\n");
    sandboxes.push_back(new Sandbox(sandboxName, idx, entryPoints, persistent, M, overhead, clearances));
		SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Created new Sandbox instance\n");
  }

  /*
  for (map<Function*,string>::iterator I=funcToSandboxName.begin(), E=funcToSandboxName.end(); I!=E; I++) {
    Function* entryPoint = I->first;
    string sandboxName = I->second;
    int idx = assignBitIdxToSandboxName(sandboxName);
    int overhead = funcToOverhead[entryPoint];
    int clearances = funcToClearances[entryPoint];
    bool persistent = find(ephemeralSandboxes.begin(), ephemeralSandboxes.end(), entryPoint) == ephemeralSandboxes.end();
		SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Creating new Sandbox instance\n");
    sandboxes.push_back(new Sandbox(sandboxName, idx, entryPoint, persistent, M, overhead, clearances));
		SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Created new Sandbox instance\n");
  }
  */

  // Handle sandboxed code regions, i.e. start_sandboxed_code(N) and end_sandboxed_code(N) blocks 
  if (Function* SboxStart = M.getFunction("llvm.annotation.i32")) {
    for (User* U : SboxStart->users()) {
      if (IntrinsicInst* annotCall = dyn_cast<IntrinsicInst>(U)) {
        GlobalVariable* annotationStrVar = dyn_cast<GlobalVariable>(annotCall->getOperand(1)->stripPointerCasts());
        ConstantDataArray* annotationStrValArray = dyn_cast<ConstantDataArray>(annotationStrVar->getInitializer());
        StringRef annotationStrValCString = annotationStrValArray->getAsCString();
        
        if (annotationStrValCString.startswith(SOAAP_SANDBOX_REGION_START)) {
          StringRef sandboxName = annotationStrValCString.substr(strlen(SOAAP_SANDBOX_REGION_START)+1); //+1 because of _
          SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_3 << "Found start of sandboxed code region: "; annotCall->dump(););
          InstVector sandboxedInsts;
          findAllSandboxedInstructions(annotCall, sandboxName, sandboxedInsts);
          int idx = assignBitIdxToSandboxName(sandboxName);
          sandboxes.push_back(new Sandbox(sandboxName, idx, sandboxedInsts, false, M)); //TODO: obtain persistent/ephemeral information in a better way (currently we obtain it from the creation point)
        }
      }
Example #12
0
namespace MCPP {


	static const String name("Plugin Message Support");
	static const Word priority=1;
	static const String reg("REGISTER");
	static const String unreg("UNREGISTER");
	static const Regex is_builtin("^MC\\|");
	
	
	static Vector<String> get_strings (const Vector<Byte> & buffer) {
	
		//	Decode
		auto str=UTF8().Decode(buffer.begin(),buffer.end());
		
		//	Separate on NULL character
		Vector<String> retr;
		for (auto cp : str.CodePoints()) {
		
			if (retr.Count()==0) retr.EmplaceBack();
			
			if (cp=='\0') {
			
				retr.EmplaceBack();
				
				continue;
			
			}
			
			retr[retr.Count()-1] << cp;
		
		}
		
		return retr;
	
	}
	
	
	void PluginMessages::reg (SmartPointer<Client> client, Vector<Byte> data) {
		
		auto channels=get_strings(data);
		
		lock.Write([&] () mutable {
		
			auto iter=clients.find(client);
			
			if (iter==clients.end()) return;
			
			for (auto & channel : channels) iter->second.insert(std::move(channel));
		
		});
	
	}
	
	
	void PluginMessages::unreg (SmartPointer<Client> client, Vector<Byte> data) {
	
		auto channels=get_strings(data);
		
		lock.Write([&] () mutable {
		
			auto iter=clients.find(client);
			
			if (iter==clients.end()) return;
			
			for (auto & channel : channels) iter->second.erase(channel);
		
		});
	
	}
	
	
	void PluginMessages::handler (PacketEvent event) {
	
		auto & packet=event.Data.Get<incoming>();
		
		//	Handle register/unregister separately
		if (packet.Channel==MCPP::reg) {
		
			reg(
				std::move(event.From),
				std::move(packet.Data)
			);
			
			return;
		
		} else if (packet.Channel==MCPP::unreg) {
		
			unreg(
				std::move(event.From),
				std::move(packet.Data)
			);
		
			return;
		
		}
	
		//	Try and get associated handler
		auto iter=callbacks.find(packet.Channel);
		
		//	If there's no associated handler,
		//	just pass
		if (iter==callbacks.end()) return;
		
		//	Invoke handler
		iter->second(PluginMessage{
			std::move(event.From),
			std::move(packet.Channel),
			std::move(packet.Data)
		});
	
	}
	
	
	Word PluginMessages::Priority () const noexcept {
	
		return priority;
	
	}
	
	
	const String & PluginMessages::Name () const noexcept {
	
		return name;
	
	}
	
	
	void PluginMessages::Install () {
	
		auto & server=Server::Get();
	
		server.Router(
			incoming::PacketID,
			incoming::State
		)=[this] (PacketEvent event) mutable {	handler(std::move(event));	};
		
		server.OnConnect.Add([this] (SmartPointer<Client> client) mutable {
		
			lock.Write([&] () mutable {
			
				clients.emplace(
					std::move(client),
					std::unordered_set<String>()
				);
			
			});
		
		});
		
		server.OnDisconnect.Add([this] (SmartPointer<Client> client, const String &) mutable {
		
			lock.Write([&] () mutable {
			
				clients.erase(client);
			
			});
		
		});
		
		server.OnShutdown.Add([this] () mutable {	callbacks.clear();	});
	
	}
	
	
	void PluginMessages::Add (String channel, std::function<void (PluginMessage)> callback) {
	
		auto iter=callbacks.find(channel);
		
		//	Replace handler if one already exists
		if (iter==callbacks.end()) {
		
			callbacks.emplace(
				std::move(channel),
				std::move(callback)
			);
		
		} else {
		
			iter->second=std::move(callback);
		
		}
	
	}
	
	
	Nullable<Promise<bool>> PluginMessages::Send (PluginMessage message) {
	
		Nullable<Promise<bool>> retr;
		
		if (message.Endpoint.IsNull()) return retr;
		
		if (
			is_builtin.IsMatch(message.Channel) ||
			lock.Read([&] () mutable {
			
				auto iter=clients.find(message.Endpoint);
				
				return !((iter==clients.end()) || (iter->second.count(message.Channel)==0));
			
			})
		) {
		
			outgoing packet;
			packet.Channel=std::move(message.Channel);
			packet.Data=std::move(message.Buffer);
			
			retr.Construct(message.Endpoint->Send(packet));
		
		}
		
		return retr;
	
	}


	static Singleton<PluginMessages> singleton;
	
	
	PluginMessages & PluginMessages::Get () noexcept {
	
		return singleton.Get();
	
	}


}
Example #13
0
bool
Metric::evaluateDaemonAd(classad::ClassAd &metric_ad,classad::ClassAd const &daemon_ad,int max_verbosity,StatsD *statsd,ExtArray<MyString> *regex_groups,char const *regex_attr)
{
    if( regex_attr ) {
        name = regex_attr;
    }
    if( !evaluateOptionalString(ATTR_NAME,name,metric_ad,daemon_ad,regex_groups) ) return false;

    metric_ad.EvaluateAttrInt(ATTR_VERBOSITY,verbosity);
    if( verbosity > max_verbosity ) {
        // avoid doing more work; this metric requires higher verbosity
        return false;
    }

    std::string target_type_str;
    if( !evaluateOptionalString(ATTR_TARGET_TYPE,target_type_str,metric_ad,daemon_ad,regex_groups) ) return false;
    target_type.initializeFromString(target_type_str.c_str());
    if( target_type.contains_anycase("machine_slot1") ) {
        restrict_slot1 = true;
    }

    std::string my_type;
    daemon_ad.EvaluateAttrString(ATTR_MY_TYPE,my_type);
    if( !target_type.isEmpty() && !target_type.contains_anycase("any") ) {
        if( restrict_slot1 && !strcasecmp(my_type.c_str(),"machine") ) {
            int slotid = 1;
            daemon_ad.EvaluateAttrInt(ATTR_SLOT_ID,slotid);
            if( slotid != 1 ) {
                return false;
            }
            bool dynamic_slot = false;
            daemon_ad.EvaluateAttrBool(ATTR_SLOT_DYNAMIC,dynamic_slot);
            if( dynamic_slot ) {
                return false;
            }
        }
        else if( !target_type.contains_anycase(my_type.c_str()) ) {
            // avoid doing more work; this is not the right type of daemon ad
            return false;
        }
    }

    classad::Value requirements_val;
    requirements_val.SetBooleanValue(true);
    if( !evaluate(ATTR_REQUIREMENTS,requirements_val,metric_ad,daemon_ad,BOOLEAN,regex_groups,regex_attr) ) {
        return false;
    }
    bool requirements = true;
    if( !requirements_val.IsBooleanValue(requirements) || requirements!=true ) {
        return false;
    }

    if( !regex_attr ) {
        std::string regex;
        if( !evaluateOptionalString(ATTR_REGEX,regex,metric_ad,daemon_ad,NULL) ) return false;
        if( !regex.empty() ) {
            Regex re;
            const char *errptr=NULL;
            int erroffset=0;
            if( !re.compile(regex.c_str(),&errptr,&erroffset,PCRE_ANCHORED) ) {
                EXCEPT("Invalid regex %s",regex.c_str());
            }
            for( classad::ClassAd::const_iterator itr = daemon_ad.begin();
                    itr != daemon_ad.end();
                    itr++ )
            {
                ExtArray<MyString> the_regex_groups;
                if( re.match(itr->first.c_str(),&the_regex_groups) ) {
                    // make a new Metric for this attribute that matched the regex
                    counted_ptr<Metric> metric(statsd->newMetric());
                    metric->evaluateDaemonAd(metric_ad,daemon_ad,max_verbosity,statsd,&the_regex_groups,itr->first.c_str());
                }
            }
            return false;
        }
    }

    std::string aggregate_str;
    if( !evaluateOptionalString(ATTR_AGGREGATE,aggregate_str,metric_ad,daemon_ad,regex_groups) ) return false;
    aggregate = NO_AGGREGATE;
    if( strcasecmp(aggregate_str.c_str(),"sum")==0 ) {
        aggregate = SUM;
    }
    else if( strcasecmp(aggregate_str.c_str(),"avg")==0 ) {
        aggregate = AVG;
    }
    else if( strcasecmp(aggregate_str.c_str(),"min")==0 ) {
        aggregate = MIN;
    }
    else if( strcasecmp(aggregate_str.c_str(),"max")==0 ) {
        aggregate = MAX;
    }
    else if( !aggregate_str.empty() ) {
        EXCEPT("Invalid aggregate function %s",aggregate_str.c_str());
    }

    // set default stats grouping
    if( isAggregateMetric() ) {
        group = "HTCondor Pool";
    }
    else if( !strcasecmp(my_type.c_str(),"scheduler") ) {
        group = "HTCondor Schedd";
    }
    else if( !strcasecmp(my_type.c_str(),"machine") ) {
        group = "HTCondor Startd";
        if( !statsd->publishPerExecuteNodeMetrics() ) {
            return false;
        }
    }
    else if( !strcasecmp(my_type.c_str(),"daemonmaster") ) {
        group = "HTCondor Master";

        if( !statsd->publishPerExecuteNodeMetrics() ) {
            std::string machine_name;
            daemon_ad.EvaluateAttrString(ATTR_MACHINE,machine_name);
            if( statsd->isExecuteOnlyNode(machine_name) ) {
                return false;
            }
        }
    }
    else {
        formatstr(group,"HTCondor %s",my_type.c_str());
    }

    if( isAggregateMetric() ) {
        // This is like GROUP BY in SQL.
        // By default, group by the name of the metric.
        aggregate_group = name;
        if( !evaluateOptionalString(ATTR_AGGREGATE_GROUP,aggregate_group,metric_ad,daemon_ad,regex_groups) ) return false;
    }

    if( !evaluateOptionalString(ATTR_GROUP,group,metric_ad,daemon_ad,regex_groups) ) return false;

    if( !evaluateOptionalString(ATTR_TITLE,title,metric_ad,daemon_ad,regex_groups) ) return false;
    if( !evaluateOptionalString(ATTR_DESC,desc,metric_ad,daemon_ad,regex_groups) ) return false;
    if( !evaluateOptionalString(ATTR_UNITS,units,metric_ad,daemon_ad,regex_groups) ) return false;
    if( !evaluateOptionalString(ATTR_CLUSTER,cluster,metric_ad,daemon_ad,regex_groups) ) return false;

    metric_ad.EvaluateAttrBool(ATTR_DERIVATIVE,derivative);
    metric_ad.EvaluateAttrNumber(ATTR_SCALE,scale);

    std::string type_str;
    if( !evaluateOptionalString(ATTR_TYPE,type_str,metric_ad,daemon_ad,regex_groups) ) return false;
    if( type_str.empty() ) {
        type = AUTO;
    }
    else if( strcasecmp(type_str.c_str(),"string")==0 ) {
        type = STRING;
    }
    else if( strcasecmp(type_str.c_str(),"int8")==0 ) {
        type = INT8;
    }
    else if( strcasecmp(type_str.c_str(),"uint8")==0 ) {
        type = UINT8;
    }
    else if( strcasecmp(type_str.c_str(),"int16")==0 ) {
        type = INT16;
    }
    else if( strcasecmp(type_str.c_str(),"uint16")==0 ) {
        type = UINT16;
    }
    else if( strcasecmp(type_str.c_str(),"int32")==0 ) {
        type = INT32;
    }
    else if( strcasecmp(type_str.c_str(),"uint32")==0 ) {
        type = UINT32;
    }
    else if( strcasecmp(type_str.c_str(),"float")==0 ) {
        type = FLOAT;
    }
    else if( strcasecmp(type_str.c_str(),"double")==0 ) {
        type = DOUBLE;
    }
    else if( strcasecmp(type_str.c_str(),"boolean")==0 ) {
        type = BOOLEAN;
    }
    else {
        EXCEPT("Invalid metric attribute type=%s for %s",type_str.c_str(),whichMetric().c_str());
        return false;
    }

    value.SetUndefinedValue();
    if( !evaluate(ATTR_VALUE,value,metric_ad,daemon_ad,type,regex_groups,regex_attr) ) {
        return false;
    }
    if( value.IsUndefinedValue() ) {
        if( regex_attr ) {
            daemon_ad.EvaluateAttr(regex_attr,value);
        }
        else {
            daemon_ad.EvaluateAttr(name,value);
        }
    }
    if( value.IsUndefinedValue() ) {
        return false;
    }
    if ( type == AUTO ) {
        if (value.IsBooleanValue() ) {
            type = BOOLEAN;
        } else if ( value.IsIntegerValue() )  {
            type = INT32;
        } else if ( value.IsNumber() ) {
            type = FLOAT;
        } else if ( value.IsStringValue() ) {
            type = STRING;
        }
    }

    if( isAggregateMetric() ) {
        machine = statsd->getDefaultAggregateHost();
    }
    else {
        if( (!strcasecmp(my_type.c_str(),"machine") && restrict_slot1) || !strcasecmp(my_type.c_str(),"collector") ) {
            // for STARTD_SLOT1 metrics, advertise by default as host.name, not slot1.host.name
            // ditto for the collector, which typically has a daemon name != machine name, even though there is only one collector
            daemon_ad.EvaluateAttrString(ATTR_MACHINE,machine);
        }
        else if( !strcasecmp(my_type.c_str(),"submitter") ) {
            daemon_ad.EvaluateAttrString(ATTR_SCHEDD_NAME,machine);
        }
        else {
            // use the daemon name for the metric machine name
            daemon_ad.EvaluateAttrString(ATTR_NAME,machine);
        }
    }
    if( !evaluateOptionalString(ATTR_MACHINE,machine,metric_ad,daemon_ad,regex_groups) ) return false;

    statsd->getDaemonIP(machine,ip);
    if( !evaluateOptionalString(ATTR_IP,ip,metric_ad,daemon_ad,regex_groups) ) return false;

    if( isAggregateMetric() ) {
        statsd->addToAggregateValue(*this);
    }
    else {
        statsd->publishMetric(*this);
    }
    return true;
}
Example #14
0
 RegexParagraphList(const char *name, const char *regex, const char *listregex) :
     RegexMatcher(name, regex), 
     regexListBreaker("List Breaker", listregex)
 {
     regexListBreaker.Compile();
 }
Example #15
0
void Gource::processCommit(RCommit& commit, float t) {

    //find user of this commit or create them
    RUser* user = 0;

    //see if user already exists but if not wait until
    //we actually use one of their files before adding them
    std::map<std::string, RUser*>::iterator seen_user = users.find(commit.username);
    if(seen_user != users.end()) user = seen_user->second;


    //check user against filters, if found, discard commit
    if(user == 0 && !gGourceSettings.user_filters.empty()) {
        for(std::vector<Regex*>::iterator ri = gGourceSettings.user_filters.begin(); ri != gGourceSettings.user_filters.end(); ri++) {
            Regex* r = *ri;

            if(r->match(commit.username)) {
                return;
            }
        }
    }

    //find files of this commit or create it
    for(std::list<RCommitFile>::iterator it = commit.files.begin(); it != commit.files.end(); it++) {

        RCommitFile& cf = *it;

        RFile* file = 0;

        std::map<std::string, RFile*>::iterator seen_file = files.find(cf.filename);
        if(seen_file != files.end()) file = seen_file->second;

        if(file == 0) {

            //if we already have max files in circulation
            //we cant add any more
            if(files.size() >= gGourceSettings.max_files)
                continue;

            //check filename against filters
            if(!gGourceSettings.file_filters.empty()) {

                bool filtered_filename = false;

                for(std::vector<Regex*>::iterator ri = gGourceSettings.file_filters.begin(); ri != gGourceSettings.file_filters.end(); ri++) {
                    Regex* r = *ri;

                    if(r->match(cf.filename)) {
                        filtered_filename = true;
                        break;
                    }
                }

                if(filtered_filename) continue;

            }

            int tagid = tag_seq++;

            file = new RFile(cf.filename, cf.colour, vec2f(0.0,0.0), tagid);

            files[cf.filename] = file;
            tagfilemap[tagid]  = file;

            root->addFile(file);

            while(root->getParent() != 0) {
                debugLog("parent changed to %s\n", root->getPath().c_str());
                root = root->getParent();
            }
        }

        //create user if havent yet. do it here to ensure at least one of there files
        //was added (incase we hit gGourceSettings.max_files)

        if(user == 0) {
            vec2f pos;

            if(dir_bounds.area() > 0) {
                pos = dir_bounds.centre();
            } else {
                pos = vec2f(0,0);
            }

            int tagid = tag_seq++;

            user = new RUser(commit.username, pos, tagid);

            users[commit.username] = user;
            tagusermap[tagid]     = user;

            if(gGourceSettings.highlight_all_users) {
                user->setHighlighted(true);
            } else {

                // set the highlighted flag if name matches a highlighted user
                for(std::vector<std::string>::iterator hi = gGourceSettings.highlight_users.begin(); hi != gGourceSettings.highlight_users.end(); hi++) {
                    std::string highlight = *hi;

                    if(highlight.size() && user->getName() == highlight) {
                        user->setHighlighted(true);
                        break;
                    }
                }
            }

            debugLog("added user %s, tagid = %d\n", commit.username.c_str(), tagid);
        }

        //create action

        RAction* action = 0;

        int commitNo = commit_seq++;

        if(cf.action == "D") {
            action = new RemoveAction(user, file, t);
        } else {
            if(cf.action == "A") {
                action = new CreateAction(user, file, t);
            } else {
                action = new ModifyAction(user, file, t);
            }
        }

        user->addAction(action);
    }
}
namespace libdnf {

static const Regex RELDEP_REGEX = 
    Regex("^(\\S*)\\s*(<=|>=|<|>|=)?\\s*(.*)$", REG_EXTENDED);

static bool
getCmpFlags(int *cmp_type, std::string matchCmpType)
{
    int subexpr_len = matchCmpType.size();
    auto match_start = matchCmpType.c_str();
    if (subexpr_len == 2) {
        if (strncmp(match_start, "<=", 2) == 0) {
            *cmp_type |= HY_LT;
            *cmp_type |= HY_EQ;
        }
        else if (strncmp(match_start, ">=", 2) == 0) {
            *cmp_type |= HY_GT;
            *cmp_type |= HY_EQ;
        }
        else
            return false;
    } else if (subexpr_len == 1) {
        if (*match_start == '<')
            *cmp_type |= HY_LT;
        else if (*match_start == '>')
            *cmp_type |= HY_GT;
        else if (*match_start == '=')
            *cmp_type |= HY_EQ;
        else
            return false;
    } else
        return false;
    return true;
}

bool
DependencySplitter::parse(const char * reldepStr)
{
    enum { NAME = 1, CMP_TYPE = 2, EVR = 3, _LAST_ };
    auto matchResult = RELDEP_REGEX.match(reldepStr, false, _LAST_);
    if (!matchResult.isMatched() || matchResult.getMatchedLen(NAME) == 0) {
        return false;
    }
    name = matchResult.getMatchedString(NAME);
    evr = matchResult.getMatchedString(EVR);
    cmpType = 0;
    int evrLen = matchResult.getMatchedLen(EVR);
    int cmpTypeLen = matchResult.getMatchedLen(CMP_TYPE);
    if (cmpTypeLen < 1) {
        if (evrLen > 0) {
            // name contains the space char, e.g. filename like "hello world.jpg"
            evr.clear();
            name = reldepStr;
        }
        return true;
    }
    if (evrLen < 1)
        return false;

    return getCmpFlags(&cmpType, matchResult.getMatchedString(CMP_TYPE));
}

}
Example #17
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 #18
0
void GourceSettings::importGourceSettings(ConfFile& conffile, ConfSection* gource_settings) {

    setGourceDefaults();

    if(gource_settings == 0) gource_settings = conffile.getSection(default_section_name);

    if(gource_settings == 0) {
        gource_settings = conffile.addSection("gource");
    }

    ConfEntry* entry = 0;

    //hide flags

    std::vector<std::string> hide_fields;

    if((entry = gource_settings->getEntry("hide")) != 0) {

        if(!entry->hasValue()) conffile.missingValueException(entry);

        std::string hide_string = entry->getString();

        size_t sep;
        while((sep = hide_string.find(",")) != std::string::npos) {

            if(sep == 0 && hide_string.size()==1) break;

            if(sep == 0) {
                hide_string = hide_string.substr(sep+1, hide_string.size()-1);
                continue;
            }

            std::string hide_field  = hide_string.substr(0, sep);
            hide_fields.push_back(hide_field);
            hide_string = hide_string.substr(sep+1, hide_string.size()-1);
        }

        if(hide_string.size() > 0 && hide_string != ",") hide_fields.push_back(hide_string);

        //validate field list

        for(std::vector<std::string>::iterator it = hide_fields.begin(); it != hide_fields.end(); it++) {
            std::string hide_field = (*it);

            if(   hide_field != "date"
               && hide_field != "users"
               && hide_field != "tree"
               && hide_field != "files"
               && hide_field != "usernames"
               && hide_field != "filenames"
               && hide_field != "dirnames"
               && hide_field != "bloom"
               && hide_field != "progress"
               && hide_field != "mouse"
               && hide_field != "root") {
                std::string unknown_hide_option = std::string("unknown option hide ") + hide_field;
                conffile.entryException(entry, unknown_hide_option);
            }
        }
    }

    //check hide booleans
    for(std::map<std::string,std::string>::iterator it = arg_types.begin(); it != arg_types.end(); it++) {
        if(it->first.find("hide-") == 0 && it->second == "bool") {

            if(gource_settings->getBool(it->first)) {
                std::string hide_field = it->first.substr(5, it->first.size()-5);
                hide_fields.push_back(hide_field);
            }
        }
    }

    if(hide_fields.size()>0) {

        for(std::vector<std::string>::iterator it = hide_fields.begin(); it != hide_fields.end(); it++) {
            std::string hidestr = (*it);

                if(hidestr == "date")       hide_date      = true;
            else if(hidestr == "users")     hide_users     = true;
            else if(hidestr == "tree")      hide_tree      = true;
            else if(hidestr == "files")     hide_files     = true;
            else if(hidestr == "usernames") hide_usernames = true;
            else if(hidestr == "filenames") hide_filenames = true;
            else if(hidestr == "dirnames")  hide_dirnames  = true;
            else if(hidestr == "bloom")     hide_bloom     = true;
            else if(hidestr == "progress")  hide_progress  = true;
            else if(hidestr == "root")      hide_root      = true;
            else if(hidestr == "mouse")     {
                hide_mouse     = true;
                hide_progress  = true;
            }
        }
    }

    if((entry = gource_settings->getEntry("date-format")) != 0) {

        if(!entry->hasValue()) conffile.missingValueException(entry);

        date_format = entry->getString();
    }

    if(gource_settings->getBool("disable-auto-rotate")) {
        disable_auto_rotate=true;
    }

    if(gource_settings->getBool("disable-auto-skip")) {
        auto_skip_seconds = -1.0;
    }

    if(gource_settings->getBool("loop")) {
        loop = true;
    }

    if((entry = gource_settings->getEntry("git-branch")) != 0) {

        if(!entry->hasValue()) conffile.missingValueException(entry);

        git_branch = entry->getString();
    }

    if(gource_settings->getBool("colour-images")) {
        colour_user_images = true;
    }

    if((entry = gource_settings->getEntry("crop")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify crop (vertical,horizontal)");

        std::string crop = entry->getString();

        if(crop == "vertical") {
            crop_vertical = true;
        } else if (crop == "horizontal") {
            crop_horizontal = true;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("log-format")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify log-format (format)");

        log_format = entry->getString();

        if(log_format == "cvs") {
            conffile.entryException(entry, "please use either 'cvs2cl' or 'cvs-exp'");
        }

        if(   log_format != "git"
           && log_format != "cvs-exp"
           && log_format != "cvs2cl"
           && log_format != "svn"
           && log_format != "custom"
           && log_format != "hg"
           && log_format != "bzr"
           && log_format != "apache") {

            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("default-user-image")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify default-user-image (image path)");

        default_user_image = entry->getString();
    }

    if((entry = gource_settings->getEntry("user-image-dir")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify user-image-dir (directory)");

        user_image_dir = entry->getString();

        //append slash
        if(user_image_dir[user_image_dir.size()-1] != '/') {
            user_image_dir += std::string("/");
        }

        //get jpg and png images in dir
        DIR *dp;
        struct dirent *dirp;

        user_image_map.clear();

        if((dp = opendir(gGourceSettings.user_image_dir.c_str())) != 0) {

            while ((dirp = readdir(dp)) != 0) {
                std::string dirfile = std::string(dirp->d_name);

                size_t extpos = 0;

                if(   (extpos=dirfile.rfind(".jpg"))  == std::string::npos
                && (extpos=dirfile.rfind(".jpeg")) == std::string::npos
                && (extpos=dirfile.rfind(".png"))  == std::string::npos) continue;


                std::string image_path = gGourceSettings.user_image_dir + dirfile;
                std::string name       = dirfile.substr(0,extpos);

#ifdef __APPLE__
                CFMutableStringRef help = CFStringCreateMutable(kCFAllocatorDefault, 0);
                CFStringAppendCString(help, name.c_str(), kCFStringEncodingUTF8);
                CFStringNormalize(help, kCFStringNormalizationFormC);
                char data[4096];
                CFStringGetCString(help,
                                   data,
                                   sizeof(data),
                                   kCFStringEncodingUTF8);
                name = data;
#endif

                debugLog("%s => %s", name.c_str(), image_path.c_str());

                user_image_map[name] = image_path;
            }

            closedir(dp);
        }
    }

    if((entry = gource_settings->getEntry("caption-file")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify caption file (filename)");

        caption_file = entry->getString();
    }

    if((entry = gource_settings->getEntry("caption-duration")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify caption duration (seconds)");

        caption_duration = entry->getFloat();

        if(caption_duration <= 0.0f) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("caption-size")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify caption size");

        caption_size = entry->getInt();

        if(caption_size<1 || caption_size>100) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("caption-offset")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify caption offset");

        caption_offset = entry->getInt();
    }

    if((entry = gource_settings->getEntry("caption-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify caption colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            caption_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            caption_colour = vec3(r,g,b);
            caption_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("bloom-intensity")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify bloom-intensity (float)");

        bloom_intensity = entry->getFloat();

        if(bloom_intensity<=0.0f) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("bloom-multiplier")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify bloom-multiplier (float)");

        bloom_multiplier = entry->getFloat();

        if(bloom_multiplier<=0.0f) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("elasticity")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify elasticity (float)");

        elasticity = entry->getFloat();

        if(elasticity<=0.0f) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("font-size")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify font size");

        font_size = entry->getInt();

        if(font_size<1 || font_size>100) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("hash-seed")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify hash seed (integer)");

        gStringHashSeed = entry->getInt();
    }

    if((entry = gource_settings->getEntry("font-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify font colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            font_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            font_colour = vec3(r,g,b);
            font_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("background-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify background colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            background_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            background_colour = vec3(r,g,b);
            background_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("highlight-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify highlight colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            highlight_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            highlight_colour = vec3(r,g,b);
            highlight_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("selection-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify selection colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            selection_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            selection_colour = vec3(r,g,b);
            selection_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("dir-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify dir colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            dir_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            dir_colour = vec3(r,g,b);
            dir_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("background-image")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify background image (image path)");

        background_image = entry->getString();
    }

    if((entry = gource_settings->getEntry("title")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify title");

        title = entry->getString();
    }

    if((entry = gource_settings->getEntry("logo")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify logo (image path)");

        logo = entry->getString();
    }

    if((entry = gource_settings->getEntry("logo-offset")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify logo-offset (XxY)");

        std::string logo_offset_str = entry->getString();

        int posx = 0;
        int posy = 0;

        if(parseRectangle(logo_offset_str, posx, posy)) {
            logo_offset = vec2(posx, posy);
        } else {
            conffile.invalidValueException(entry);
        }

    }

    if((entry = gource_settings->getEntry("seconds-per-day")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify seconds-per-day (seconds)");

        float seconds_per_day = entry->getFloat();

        if(seconds_per_day<=0.0f) {
            conffile.invalidValueException(entry);
        }

        // convert seconds-per-day to days-per-second
        days_per_second = 1.0 / seconds_per_day;
    }

    if((entry = gource_settings->getEntry("auto-skip-seconds")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify auto-skip-seconds (seconds)");

        auto_skip_seconds = entry->getFloat();

        if(auto_skip_seconds <= 0.0) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("file-idle-time")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify file-idle-time (seconds)");

        std::string file_idle_str = entry->getString();

        file_idle_time = (float) atoi(file_idle_str.c_str());

        if(file_idle_time<0.0f || (file_idle_time == 0.0f && file_idle_str[0] != '0') ) {
            conffile.invalidValueException(entry);
        }
        if(file_idle_time==0.0f) {
            file_idle_time = 86400.0f;
        }
    }

    if((entry = gource_settings->getEntry("user-idle-time")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify user-idle-time (seconds)");

        user_idle_time = entry->getFloat();

        if(user_idle_time < 0.0f) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("time-scale")) != 0) {

        if(!entry->hasValue())
            conffile.entryException(entry, "specify time-scale (scale)");

        time_scale = entry->getFloat();

        if(time_scale <= 0.0f || time_scale > 4.0f) {
            conffile.entryException(entry, "time-scale outside of range 0.0 - 4.0");
        }
    }

    if((entry = gource_settings->getEntry("start-position")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify start-position (float,random)");

        if(entry->getString() == "random") {
            srand(time(0));
            start_position = (rand() % 1000) / 1000.0f;
        } else {
            start_position = entry->getFloat();

            if(start_position<=0.0 || start_position>=1.0) {
                conffile.entryException(entry, "start-position outside of range 0.0 - 1.0 (non-inclusive)");
            }
        }
    }

    if((entry = gource_settings->getEntry("stop-position")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify stop-position (float)");

        stop_position = entry->getFloat();

        if(stop_position<=0.0 || stop_position>1.0) {
            conffile.entryException(entry, "stop-position outside of range 0.0 - 1.0 (inclusive)");
        }
    }

    if((entry = gource_settings->getEntry("stop-at-time")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify stop-at-time (seconds)");

        stop_at_time = entry->getFloat();

        if(stop_at_time <= 0.0) {
            conffile.invalidValueException(entry);
        }
    }

    if(gource_settings->getBool("key")) {
        show_key = true;
    }

    if(gource_settings->getBool("ffp")) {
        ffp = true;
    }

    if(gource_settings->getBool("realtime")) {
        days_per_second = 1.0 / 86400.0;
    }

    if(gource_settings->getBool("dont-stop")) {
        dont_stop = true;
    }

    if(gource_settings->getBool("stop-at-end")) {
        stop_at_end = true;
    }

    //NOTE: this no longer does anything
    if(gource_settings->getBool("stop-on-idle")) {
        stop_on_idle = true;
    }

    if((entry = gource_settings->getEntry("max-files")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify max-files (number)");

        max_files = entry->getInt();

        if( max_files<0 || (max_files == 0 && entry->getString() != "0") ) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("max-file-lag")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify max-file-lag (seconds)");

        max_file_lag = entry->getFloat();

        if(max_file_lag==0.0) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("user-friction")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify user-friction (seconds)");

        user_friction = entry->getFloat();

        if(user_friction<=0.0) {
            conffile.invalidValueException(entry);
        }

        user_friction = 1.0 / user_friction;
    }

    if((entry = gource_settings->getEntry("user-scale")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify user-scale (scale)");

        user_scale = entry->getFloat();

        if(user_scale<=0.0 || user_scale>100.0) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("max-user-speed")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify max-user-speed (units)");

        max_user_speed = entry->getFloat();

        if(max_user_speed<=0) {
            conffile.invalidValueException(entry);
        }
    }

    if(   gource_settings->getBool("highlight-users")
       || gource_settings->getBool("highlight-all-users")) {
        highlight_all_users = true;
    }

    if(gource_settings->getBool("highlight-dirs")) {
        highlight_dirs = true;
    }

    if((entry = gource_settings->getEntry("camera-mode")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify camera-mode (overview,track)");

        camera_mode = entry->getString();

        if(camera_mode != "overview" && camera_mode != "track") {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("padding")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify padding (float)");

        padding = entry->getFloat();

        if(padding <= 0.0f || padding >= 2.0f) {
            conffile.invalidValueException(entry);
        }
    }

    // multi-value entries

    if((entry = gource_settings->getEntry("highlight-user")) != 0) {

        ConfEntryList* highlight_user_entries = gource_settings->getEntries("highlight-user");

        for(ConfEntryList::iterator it = highlight_user_entries->begin(); it != highlight_user_entries->end(); it++) {

            entry = *it;

            if(!entry->hasValue()) conffile.entryException(entry, "specify highlight-user (user)");

            highlight_users.push_back(entry->getString());
        }
    }

    if((entry = gource_settings->getEntry("follow-user")) != 0) {

        ConfEntryList* follow_user_entries = gource_settings->getEntries("follow-user");

        for(ConfEntryList::iterator it = follow_user_entries->begin(); it != follow_user_entries->end(); it++) {

            entry = *it;

            if(!entry->hasValue()) conffile.entryException(entry, "specify follow-user (user)");

            follow_users.push_back(entry->getString());
        }
    }

    if(gource_settings->getBool("file-extensions")) {
        file_extensions=true;
    }

    if((entry = gource_settings->getEntry("file-filter")) != 0) {

        ConfEntryList* filters = gource_settings->getEntries("file-filter");

        for(ConfEntryList::iterator it = filters->begin(); it != filters->end(); it++) {

            entry = *it;

            if(!entry->hasValue()) conffile.entryException(entry, "specify file-filter (regex)");

            std::string filter_string = entry->getString();

            Regex* r = new Regex(filter_string, 1);

            if(!r->isValid()) {
                delete r;
                conffile.entryException(entry, "invalid file-filter regular expression");
            }

            file_filters.push_back(r);
        }
    }

    if((entry = gource_settings->getEntry("user-filter")) != 0) {

        ConfEntryList* filters = gource_settings->getEntries("user-filter");

        for(ConfEntryList::iterator it = filters->begin(); it != filters->end(); it++) {

            entry = *it;

            if(!entry->hasValue()) conffile.entryException(entry, "specify user-filter (regex)");

            std::string filter_string = entry->getString();

            Regex* r = new Regex(filter_string, 1);

            if(!r->isValid()) {
                delete r;
                conffile.entryException(entry, "invalid user-filter regular expression");
            }

            user_filters.push_back(r);
        }
    }

    //validate path
    if(gource_settings->hasValue("path")) {
        path = gource_settings->getString("path");
        default_path = false;
    }

    if(path == "-") {

        if(log_format.size() == 0) {
            throw ConfFileException("log-format required when reading from STDIN", "", 0);
        }

#ifdef _WIN32
        DWORD available_bytes;
        HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);

        while(PeekNamedPipe(stdin_handle, 0, 0, 0,
            &available_bytes, 0) && available_bytes==0 && !std::cin.fail()) {
            SDL_Delay(100);
        }
#else
        while(std::cin.peek() == EOF && !std::cin.fail()) SDL_Delay(100);
#endif

        std::cin.clear();
    }

    //remove trailing slash and check if path is a directory
    if(path.size() &&
    (path[path.size()-1] == '\\' || path[path.size()-1] == '/')) {
        path = path.substr(0,path.size()-1);
    }

#ifdef _WIN32
    //on windows, pre-open console window if we think this is a directory the
    //user is trying to open, as system() commands will create a console window
    //if there isn't one anyway.

    bool isdir = false;

    if(path.size()>0) {
        struct stat fileinfo;
        int rc = stat(path.c_str(), &fileinfo);

        if(rc==0 && fileinfo.st_mode & S_IFDIR) isdir = true;
    }

    if(path.size()==0 || isdir) {
        SDLAppCreateWindowsConsole();
    }
#endif
}
void OpenLayersNode::AsHTML(HTMLOutputter &outputter)
{
    static const char * str_width = "width";
    static const char * str_height = "height";
    static const char * str_px = "px";

    attrs[string("mapnum")] = to_string(++mapNum);
    set_default(attrs, str_width, to_string(640));
    set_default(attrs, str_height, to_string(480));

    if (debug) cout << "Outputing OpenLayers node " << mapNum << endl;

    attrs[str_width] = attrs[str_width] + str_px;
    attrs[str_height] = attrs[str_height] + str_px;
    
    {
        map<string, string> vars;

        CopyMap(attrs, vars);

        static const char *prefix =
            "<div class=\"map\" id=\"map$mapnum\" style=\"width: $width; height: $height; direction: ltr;\"></div>"
            "<script type=\"text/javascript\">\n"
            "//<![CDATA[\n";

        outputter.AddString(subst(prefix, vars));
        outputter.AddString(subst(sections_preamble,vars));
    }

    

    bool markerlayer = false;
    const char *buffer = text.data();
    size_t bufferLength = text.length();
 
    while (bufferLength && isspace(*buffer))
    {
        --bufferLength;
        ++buffer;
    }
    if (debug) cout << "Processing line (" << bufferLength << ") '" << string(buffer, bufferLength) << "'" << endl;
    while (bufferLength)
    {
        RegexMatch match;
        bool changed(false);

        if (regex_kml.Match(buffer, bufferLength, match))
        {
            buffer += match.End(0); bufferLength -= match.End(0);

            map<string, string> vars;
            CopyMap(attrs, vars);
            if (debug) cout << "Outputting kml URL '" << match.Match(2) << "'" << endl;
            vars[string("kmlurl")] = match.Match(2);
	    outputter.AddString(subst(sections_KML, vars));
            changed = true;
		} else if (regex_gpstrack.Match(buffer, bufferLength, match)) {
            buffer += match.End(0); bufferLength -= match.End(0);

            map<string, string> vars;
            CopyMap(attrs, vars);
            
            vars[string("fromdate")] = match.Match(2);
            vars[string("todate")] = match.Match(3);
            vars[string("imgoffset")] = match.Match(4);
            if (vars.find("imgoffset") == vars.end())
                vars[string("imgoffset")] = string("14");
            outputter.AddString(subst(sections_gpstracklayer, vars));
            changed = true;
        } else if (regex_dotkml.Match(buffer, bufferLength, match)) 
        {
            buffer += match.End(0); bufferLength -= match.End(0);

            map<string, string> vars;
            CopyMap(attrs, vars);
        
            vars[string("kmlurl")] = match.Match(1);
            outputter.AddString(subst(sections_KML, vars));
			changed = true;
        } else if (regex_gpx.Match(buffer, bufferLength, match)) 
        {
            buffer += match.End(0); bufferLength -= match.End(0);

            map<string, string> vars;
            CopyMap(attrs, vars);
        
            vars[string("gpxurl")] = match.Match(2);
            vars[string("gpxtitle")] = match.Match(3);
            outputter.AddString(subst(sections_GPX, vars));
			changed = true;
        } else if (regex_dotgpx.Match(buffer, bufferLength, match)) 
        {
            buffer += match.End(0); bufferLength -= match.End(0);

            map<string, string> vars;
            CopyMap(attrs, vars);
        
            vars[string("gpxurl")] = match.Match(1);
            outputter.AddString(subst(sections_GPX, vars));
			changed = true;
		} else if (regex_georss.Match(buffer, bufferLength, match))
        {
            buffer += match.End(0); bufferLength -= match.End(0);

            map<string, string> vars;
            CopyMap(attrs, vars);
            
			vars[string("georsslayer")] = match.Match(3);
			vars[string("georssurl")] = match.Match(2) + match.Match(3);
			outputter.AddString(subst(sections_GeoRSS, vars));
			changed = true;
		}
        else if (regex_latloncsv.Match(buffer, bufferLength, match))
        {
            if (debug) cout << "Latlon csv " << match.Match(0) << endl;
            buffer += match.End(0); bufferLength -= match.End(0);

            string lat = match.Match(1);
            string lon = match.Match(2);
			string caption;
            string title;

			if (!match.Match(3).empty()) {
                title = match.Match(4);
				caption = "<p><b>" + match.Match(4) + "</b></p>";
			}

			while (regex_label.Match(buffer, bufferLength, match))
            {
                buffer += match.End(0); bufferLength -= match.End(0);

				caption = caption + match.Match(1);
			}

            caption = JavaScriptQuote(caption);
            title = JavaScriptQuote(title);

			if (!markerlayer)
            {
				markerlayer = true;
                map<string, string> vars;
                CopyMap(attrs, vars);
				outputter.AddString(subst(sections_markerlayerbegin, vars));
			}

            map<string, string> vars;
            CopyMap(attrs, vars);

			vars[string("caption")] = caption;
			vars[string("title")] = title;
			vars[string("lat")] = lat;
			vars[string("lon")] = lon;
			outputter.AddString(subst(sections_marker, vars));
			changed = true;
		}
		else if (regex_lat_lon_title.Match(buffer, bufferLength, match))
		{
            if (debug) cout << "Latlon title " << match.Match(0) << endl;
            buffer += match.End(0); bufferLength -= match.End(0);

			string lat = match.Match(1);
			string lon = match.Match(2);
			string caption;
			string title;

            if (match.Count() > 3 && match.Start(3) != match.End(3))
            {
				title = match.Match(3);
				caption = "<p><b>" + match.Match(3) + "</b></p>";
			}
			
			while (regex_label.Match(buffer, bufferLength, match))
            {
                buffer += match.End(0); bufferLength -= match.End(0);

				caption = caption + match.Match(1);
			}
			
            caption = JavaScriptQuote(caption);

            map<string, string> vars;
            CopyMap(attrs, vars);
			
			if (markerlayer)
            {
				markerlayer = true;
				outputter.AddString(subst(sections_markerlayerbegin, vars));
			}
        
        
            vars[string("caption")] = caption;
            vars[string("title")] = title;
			vars[string("lat")] = lat;
			vars[string("lon")] = lon;
			outputter.AddString(subst(sections_marker, vars));
			changed = true;
		}
        else if (regex_zoom_color.Match(buffer, bufferLength, match))
		{
            buffer += match.End(0); bufferLength -= match.End(0);

			string zoomq = match.Match(1);
			string huh = match.Match(2);
			string color = match.Match(3);
            map<string, string> vars;
            CopyMap(attrs, vars);

			vars[string("zoomq")] = zoomq;
			vars[string("huh")] = huh;
			vars[string("color")] = color;

			outputter.AddString(subst(sections_vectorlayerpreamble, vars));
            
			while (regex_latloncsv_no_label.Match(buffer, bufferLength, match))
			{
                buffer += match.End(0); bufferLength -= match.End(0);

				vars[string("lat")] = match.Match(1);
				vars[string("lon")] = match.Match(2);
				outputter.AddString(subst(sections_vectorlayerpoint, vars));
			}
            vars.erase(vars.find("lat"));
            vars.erase(vars.find("lon"));
			outputter.AddString(subst(sections_vectorlayerpost, vars));
			changed = true;
		}
        // THIS LOOKS WRONG!
        else if (regex_latloncsv.Match(buffer, bufferLength, match))
		{
            buffer += match.End(0); bufferLength -= match.End(0);

			string zoomq = match.Match(1);
			string huh = match.Match(2);
			string color = "#758BC5";
            map<string, string> vars;
            CopyMap(attrs, vars);

			vars[string("zoomq")] = zoomq;
			vars[string("huh")] = huh;
			vars[string("color")] = color;

            if (debug) cout << "Outputting latloncsv for " << match.Match(0) << endl;

			outputter.AddString(subst(sections_vectorlayerpreamble, vars));
			while (regex_latloncsv_no_label.Match(buffer, bufferLength, match))
			{
                buffer += match.End(0); bufferLength -= match.End(0);

				vars[string("lat")] = match.Match(1);
				vars[string("lon")] = match.Match(2);
				outputter.AddString(subst(sections_vectorlayerpoint, vars));
                vars.erase(vars.find(string("lat")));
                vars.erase(vars.find(string("lon")));
			}
			outputter.AddString(subst(sections_vectorlayerpost, vars));
			changed = true;
		}

        if (!changed)
        {
            cout << "Parse failure: '" << string(buffer, bufferLength) << "'" << endl;
            break;
        }
    }


    {
        map<string, string> vars;
        CopyMap(attrs, vars);
        outputter.AddString(subst(sections_post, vars));
    }

    static const char *suffix =
        "//]]>\n"
        "</script>\n";
    outputter.AddString(suffix);
}