Ejemplo n.º 1
0
void
svn_config_set(svn_config_t *cfg,
               const char *section, const char *option,
               const char *value)
{
  cfg_section_t *sec;
  cfg_option_t *opt;

  remove_expansions(cfg);

  opt = find_option(cfg, section, option, &sec);
  if (opt != NULL)
    {
      /* Replace the option's value. */
      opt->value = apr_pstrdup(cfg->pool, value);
      opt->expanded = FALSE;
      return;
    }

  /* Create a new option */
  opt = apr_palloc(cfg->pool, sizeof(*opt));
  opt->name = apr_pstrdup(cfg->pool, option);
  opt->hash_key = make_hash_key(apr_pstrdup(cfg->pool, option));

  opt->value = apr_pstrdup(cfg->pool, value);
  opt->x_value = NULL;
  opt->expanded = FALSE;

  if (sec == NULL)
    {
      /* Even the section doesn't exist. Create it. */
      sec = apr_palloc(cfg->pool, sizeof(*sec));
      sec->name = apr_pstrdup(cfg->pool, section);
      sec->hash_key = make_hash_key(apr_pstrdup(cfg->pool, section));
      sec->options = apr_hash_make(cfg->pool);
      apr_hash_set(cfg->sections, sec->hash_key, APR_HASH_KEY_STRING, sec);
    }

  apr_hash_set(sec->options, opt->hash_key, APR_HASH_KEY_STRING, opt);
}
Ejemplo n.º 2
0
/* Return a pointer to an option in CFG, or NULL if it doesn't exist.
   if SECTIONP is non-null, return a pointer to the option's section.
   OPTION may be NULL. */
static cfg_option_t *
find_option(svn_config_t *cfg, const char *section, const char *option,
            cfg_section_t **sectionp)
{
  void *sec_ptr;

  /* Canonicalize the hash key */
  svn_stringbuf_set(cfg->tmp_key, section);
  make_hash_key(cfg->tmp_key->data);

  sec_ptr = apr_hash_get(cfg->sections, cfg->tmp_key->data,
                         cfg->tmp_key->len);
  if (sectionp != NULL)
    *sectionp = sec_ptr;

  if (sec_ptr != NULL && option != NULL)
    {
      cfg_section_t *sec = sec_ptr;
      cfg_option_t *opt;

      /* Canonicalize the option key */
      svn_stringbuf_set(cfg->tmp_key, option);
      make_hash_key(cfg->tmp_key->data);

      opt = apr_hash_get(sec->options, cfg->tmp_key->data,
                         cfg->tmp_key->len);
      /* NOTE: ConfigParser's sections are case sensitive. */
      if (opt == NULL
          && apr_strnatcasecmp(section, SVN_CONFIG__DEFAULT_SECTION) != 0)
        /* Options which aren't found in the requested section are
           also sought after in the default section. */
        opt = find_option(cfg, SVN_CONFIG__DEFAULT_SECTION, option, &sec);
      return opt;
    }

  return NULL;
}
Ejemplo n.º 3
0
static cfg_section_t *
svn_config_addsection(svn_config_t *cfg,
                      const char *section)
{
  cfg_section_t *s;
  const char *hash_key;

  s = apr_palloc(cfg->pool, sizeof(cfg_section_t));
  s->name = apr_pstrdup(cfg->pool, section);
  if(cfg->section_names_case_sensitive)
    hash_key = s->name;
  else
    hash_key = make_hash_key(apr_pstrdup(cfg->pool, section));
  s->options = apr_hash_make(cfg->pool);
  svn_hash_sets(cfg->sections, hash_key, s);

  return s;
}
Ejemplo n.º 4
0
static void
svn_config_create_option(cfg_option_t **opt,
                         const char *option,
                         const char *value,
                         svn_boolean_t option_names_case_sensitive,
                         apr_pool_t *pool)
{
  cfg_option_t *o;

  o = apr_palloc(pool, sizeof(cfg_option_t));
  o->name = apr_pstrdup(pool, option);
  if(option_names_case_sensitive)
    o->hash_key = o->name;
  else
    o->hash_key = make_hash_key(apr_pstrdup(pool, option));

  o->value = apr_pstrdup(pool, value);
  o->x_value = NULL;
  o->expanded = FALSE;

  *opt = o;
}
Ejemplo n.º 5
0
static void handle_query(struct link *query_link)
{
	FILE *stream;
	char line[LINE_MAX];
	char url[LINE_MAX];
	char path[LINE_MAX];
	char action[LINE_MAX];
	char version[LINE_MAX];
	char hostport[LINE_MAX];
	char addr[LINK_ADDRESS_MAX];
	char key[LINE_MAX];
	int port;
	time_t current;

	char *hkey;
	struct nvpair *nv;
	int i, n;

	link_address_remote(query_link, addr, &port);
	debug(D_DEBUG, "www query from %s:%d", addr, port);

	if(link_readline(query_link, line, LINE_MAX, time(0) + HANDLE_QUERY_TIMEOUT)) {
		string_chomp(line);
		if(sscanf(line, "%s %s %s", action, url, version) != 3) {
			return;
		}

		// Consume the rest of the query
		while(1) {
			if(!link_readline(query_link, line, LINE_MAX, time(0) + HANDLE_QUERY_TIMEOUT)) {
				return;
			}

			if(line[0] == 0) {
				break;
			}
		}
	} else {
		return;
	}

	// Output response
	stream = fdopen(link_fd(query_link), "w");
	if(!stream) {
		return;
	}
	link_nonblocking(query_link, 0);

	current = time(0);
	fprintf(stream, "HTTP/1.1 200 OK\n");
	fprintf(stream, "Date: %s", ctime(&current));
	fprintf(stream, "Server: catalog_server\n");
	fprintf(stream, "Connection: close\n");

	if(sscanf(url, "http://%[^/]%s", hostport, path) == 2) {
		// continue on
	} else {
		strcpy(path, url);
	}

	/* load the hash table entries into one big array */

	n = 0;
	nvpair_database_firstkey(table);
	while(nvpair_database_nextkey(table, &hkey, &nv)) {
		array[n] = nv;
		n++;
	}

	/* sort the array by name before displaying */

	qsort(array, n, sizeof(struct nvpair *), compare_nvpair);

	if(!strcmp(path, "/query.text")) {
		fprintf(stream, "Content-type: text/plain\n\n");
		for(i = 0; i < n; i++)
			nvpair_print_text(array[i], stream);
	} else if(!strcmp(path, "/query.json")) {
		fprintf(stream, "Content-type: text/plain\n\n");
		fprintf(stream,"[\n");
		for(i = 0; i < n; i++) {
			nvpair_print_json(array[i], stream);
			fprintf(stream,",\n");
		}
		fprintf(stream,"]\n");
	} else if(!strcmp(path, "/query.oldclassads")) {
		fprintf(stream, "Content-type: text/plain\n\n");
		for(i = 0; i < n; i++)
			nvpair_print_old_classads(array[i], stream);
	} else if(!strcmp(path, "/query.newclassads")) {
		fprintf(stream, "Content-type: text/plain\n\n");
		for(i = 0; i < n; i++)
			nvpair_print_new_classads(array[i], stream);
	} else if(!strcmp(path, "/query.xml")) {
		fprintf(stream, "Content-type: text/xml\n\n");
		fprintf(stream, "<?xml version=\"1.0\" standalone=\"yes\"?>\n");
		fprintf(stream, "<catalog>\n");
		for(i = 0; i < n; i++)
			nvpair_print_xml(array[i], stream);
		fprintf(stream, "</catalog>\n");
	} else if(sscanf(path, "/detail/%s", key) == 1) {
		struct nvpair *nv;
		fprintf(stream, "Content-type: text/html\n\n");
		nv = nvpair_database_lookup(table, key);
		if(nv) {
			const char *name = nvpair_lookup_string(nv, "name");
			if(!name)
				name = "unknown";
			fprintf(stream, "<title>%s catalog server: %s</title>\n", preferred_hostname, name);
			fprintf(stream, "<center>\n");
			fprintf(stream, "<h1>%s catalog server</h1>\n", preferred_hostname);
			fprintf(stream, "<h2>%s</h2>\n", name);
			fprintf(stream, "<p><a href=/>return to catalog view</a><p>\n");
			nvpair_print_html_solo(nv, stream);
			fprintf(stream, "</center>\n");
		} else {
			fprintf(stream, "<title>%s catalog server</title>\n", preferred_hostname);
			fprintf(stream, "<center>\n");
			fprintf(stream, "<h1>%s catalog server</h1>\n", preferred_hostname);
			fprintf(stream, "<h2>Unknown Item!</h2>\n");
			fprintf(stream, "</center>\n");
		}
	} else {
		char avail_line[LINE_MAX];
		char total_line[LINE_MAX];
		INT64_T sum_total = 0;
		INT64_T sum_avail = 0;
		INT64_T sum_devices = 0;

		fprintf(stream, "Content-type: text/html\n\n");
		fprintf(stream, "<title>%s catalog server</title>\n", preferred_hostname);
		fprintf(stream, "<center>\n");
		fprintf(stream, "<h1>%s catalog server</h1>\n", preferred_hostname);
		fprintf(stream, "<a href=/query.text>text</a> - ");
		fprintf(stream, "<a href=/query.html>html</a> - ");
		fprintf(stream, "<a href=/query.xml>xml</a> - ");
		fprintf(stream, "<a href=/query.json>json</a> - ");
		fprintf(stream, "<a href=/query.oldclassads>oldclassads</a> - ");
		fprintf(stream, "<a href=/query.newclassads>newclassads</a>");
		fprintf(stream, "<p>\n");

		for(i = 0; i < n; i++) {
			nv = array[i];
			sum_total += nvpair_lookup_integer(nv, "total");
			sum_avail += nvpair_lookup_integer(nv, "avail");
			sum_devices++;
		}

		string_metric(sum_avail, -1, avail_line);
		string_metric(sum_total, -1, total_line);
		fprintf(stream, "<b>%sB available out of %sB on %d devices</b><p>\n", avail_line, total_line, (int) sum_devices);

		nvpair_print_html_header(stream, html_headers);
		for(i = 0; i < n; i++) {
			nv = array[i];
			make_hash_key(nv, key);
			sprintf(url, "/detail/%s", key);
			nvpair_print_html_with_link(nv, stream, html_headers, "name", url);
		}
		nvpair_print_html_footer(stream, html_headers);
		fprintf(stream, "</center>\n");
	}
	fclose(stream);
}
Ejemplo n.º 6
0
static void handle_updates(struct datagram *update_port)
{
	char data[DATAGRAM_PAYLOAD_MAX * 2];
	char addr[DATAGRAM_ADDRESS_MAX];
	char key[LINE_MAX];
	int port;
	int result;
	struct nvpair *nv;

	while(1) {
		result = datagram_recv(update_port, data, DATAGRAM_PAYLOAD_MAX, addr, &port, 0);
		if(result <= 0)
			return;

		data[result] = 0;

		nv = nvpair_create();
		nvpair_parse(nv, data);

		nvpair_insert_string(nv, "address", addr);
		nvpair_insert_integer(nv, "lastheardfrom", time(0));

		/* If the server reports unbelievable numbers, simply reset them */

		if(max_server_size > 0) {
			INT64_T total = nvpair_lookup_integer(nv, "total");
			INT64_T avail = nvpair_lookup_integer(nv, "avail");

			if(total > max_server_size || avail > max_server_size) {
				nvpair_insert_integer(nv, "total", max_server_size);
				nvpair_insert_integer(nv, "avail", max_server_size);
			}
		}

		/* Do not believe the server's reported name, just resolve it backwards. */

		char name[DOMAIN_NAME_MAX];
		if(domain_name_cache_lookup_reverse(addr, name)) {
			nvpair_insert_string(nv, "name", name);
		} else if (nvpair_lookup_string(nv, "name") == NULL) {
			/* If rDNS is unsuccessful, then we use the name reported if given.
			 * This allows for hostnames that are only valid in the subnet of
			 * the reporting server.  Here we set the "name" field to the IP
			 * Address, addr, because it was not set by the reporting server.
			 */
			nvpair_insert_string(nv, "name", addr);
		}

		make_hash_key(nv, key);

		if(logfile) {
			if(!nvpair_database_lookup(table,key)) {
				nvpair_print_text(nv,logfile);
				fflush(logfile);
			}
		}

		nvpair_database_insert(table, key, nv);

		debug(D_DEBUG, "received udp update from %s", key);
	}
}
Ejemplo n.º 7
0
static void handle_update( const char *addr, int port, const char *raw_data, int raw_data_length, const char *protocol )
{
	char key[LINE_MAX];
	unsigned long data_length;
	struct jx *j;

		// If the packet starts with Control-Z (0x1A), it is compressed,
		// so uncompress it to data[].  Otherwise just copy to data[];.

		if(raw_data[0]==0x1A) {
			data_length = sizeof(data);
			int success = uncompress((Bytef*)data,&data_length,(const Bytef*)&raw_data[1],raw_data_length-1);
			if(success!=Z_OK) {
				debug(D_DEBUG,"warning: %s:%d sent invalid compressed data (ignoring it)\n",addr,port);
				return;
			}
		} else {
			memcpy(data,raw_data,raw_data_length);
			data_length = raw_data_length;
		}

		// Make sure the string data is null terminated.
		data[data_length] = 0;

		// Once uncompressed, if it starts with a bracket,
		// then it is JX/JSON, otherwise it is the legacy nvpair format.

		if(data[0]=='{') {
			j = jx_parse_string(data);
			if(!j) {
				debug(D_DEBUG,"warning: %s:%d sent invalid JSON data (ignoring it)\n%s\n",addr,port,data);
				return;
			}
			if(!jx_is_constant(j)) {
				debug(D_DEBUG,"warning: %s:%d sent non-constant JX data (ignoring it)\n%s\n",addr,port,data);
				jx_delete(j);
				return;
			}
		} else {
			struct nvpair *nv = nvpair_create();
			if(!nv) return;
			nvpair_parse(nv, data);
			j = nvpair_to_jx(nv);
			nvpair_delete(nv);
		}

		jx_insert_string(j, "address", addr);
		jx_insert_integer(j, "lastheardfrom", time(0));

		/* If the server reports unbelievable numbers, simply reset them */

		if(max_server_size > 0) {
			INT64_T total = jx_lookup_integer(j, "total");
			INT64_T avail = jx_lookup_integer(j, "avail");

			if(total > max_server_size || avail > max_server_size) {
				jx_insert_integer(j, "total", max_server_size);
				jx_insert_integer(j, "avail", max_server_size);
			}
		}

		/* Do not believe the server's reported name, just resolve it backwards. */

		char name[DOMAIN_NAME_MAX];
		if(domain_name_cache_lookup_reverse(addr, name)) {
			/*
			Special case: Prior bug resulted in multiple name
			entries in logged data.  When removing the name property,
			keep looking until all items are removed.
			*/
			struct jx *jname = jx_string("name");
			struct jx *n;
			while((n=jx_remove(j,jname))) {
				jx_delete(n);
			}
			jx_delete(jname);

			jx_insert_string(j,"name",name);
	
		} else if (jx_lookup_string(j, "name") == NULL) {
			/* If rDNS is unsuccessful, then we use the name reported if given.
			 * This allows for hostnames that are only valid in the subnet of
			 * the reporting server.  Here we set the "name" field to the IP
			 * Address, addr, because it was not set by the reporting server.
			 */
			jx_insert_string(j, "name", addr);
		}

		make_hash_key(j, key);

		if(logfile) {
			if(!jx_database_lookup(table,key)) {
				jx_print_stream(j,logfile);
				fprintf(logfile,"\n");
				fflush(logfile);
			}
		}

		jx_database_insert(table, key, j);

		debug(D_DEBUG, "received %s update from %s",protocol,key);
}