コード例 #1
0
ファイル: headers.cpp プロジェクト: kenba/via-httplib
    bool field_line::parse_char(char c)
    {
      // Ensure that the overall header length is within limitts
      if (++length_ > max_line_length_)
        state_ = HEADER_ERROR_LENGTH;

      switch (state_)
      {
      case HEADER_NAME:
        if (std::isalpha(c) || ('-' == c))
          name_.push_back(static_cast<char>(std::tolower(c)));
        else if (':' == c)
          state_ = HEADER_VALUE_LS;
        else
          return false;
        break;

      case HEADER_VALUE_LS:
        // Ignore leading whitespace
        if (is_space_or_tab(c))
          // but only upto to a limit!
          if (++ws_count_ > max_whitespace_)
          {
            state_ = HEADER_ERROR_WS;
            return false;
          }
          else
            break;
        else
          state_ = HEADER_VALUE;
        [[fallthrough]]; // intentional fall-through

      case HEADER_VALUE:
        // The header line should end with an \r\n...
        if (!is_end_of_line(c))
          value_.push_back(c);
        else if ('\r' == c)
          state_ = HEADER_LF;
        else // ('\n' == c)
        {
          if (strict_crlf_)
          {
            state_ = HEADER_ERROR_CRLF;
            return false;
          }
          else
            state_ = HEADER_VALID;
        }
        break;

      case HEADER_LF:
        if ('\n' == c)
          state_ = HEADER_VALID;
        else
          return false;
        break;

      default:
        return false;
      }

      return true;
    }
コード例 #2
0
ファイル: config.c プロジェクト: inouekazu/booth
int read_config(const char *path, int type)
{
	char line[1024];
	FILE *fp;
	char *s, *key, *val, *end_of_key;
	const char *error;
	char *cp, *cp2;
	int i;
	int lineno = 0;
	int got_transport = 0;
	int min_timeout = 0;
	struct ticket_config defaults = { { 0 } };
	struct ticket_config *current_tk = NULL;


	fp = fopen(path, "r");
	if (!fp) {
		log_error("failed to open %s: %s", path, strerror(errno));
		return -1;
	}

	booth_conf = malloc(sizeof(struct booth_config)
			+ TICKET_ALLOC * sizeof(struct ticket_config));
	if (!booth_conf) {
		fclose(fp);
		log_error("failed to alloc memory for booth config");
		return -ENOMEM;
	}
	memset(booth_conf, 0, sizeof(struct booth_config)
			+ TICKET_ALLOC * sizeof(struct ticket_config));
	ticket_size = TICKET_ALLOC;


	booth_conf->proto = UDP;
	booth_conf->port = BOOTH_DEFAULT_PORT;
	booth_conf->maxtimeskew = BOOTH_DEFAULT_MAX_TIME_SKEW;
	booth_conf->authkey[0] = '\0';


	/* Provide safe defaults. -1 is reserved, though. */
	booth_conf->uid = -2;
	booth_conf->gid = -2;
	strcpy(booth_conf->site_user,  "hacluster");
	strcpy(booth_conf->site_group, "haclient");
	strcpy(booth_conf->arb_user,   "nobody");
	strcpy(booth_conf->arb_group,  "nobody");

	parse_weights("", defaults.weight);
	defaults.clu_test.path  = NULL;
	defaults.clu_test.pid  = 0;
	defaults.clu_test.status  = 0;
	defaults.clu_test.progstate  = EXTPROG_IDLE;
	defaults.term_duration        = DEFAULT_TICKET_EXPIRY;
	defaults.timeout       = DEFAULT_TICKET_TIMEOUT;
	defaults.retries       = DEFAULT_RETRIES;
	defaults.acquire_after = 0;
	defaults.mode          = TICKET_MODE_AUTO;

	error = "";

	log_debug("reading config file %s", path);
	while (fgets(line, sizeof(line), fp)) {
		lineno++;

		s = skip_while(line, isspace);
		if (is_end_of_line(s) || *s == '#')
			continue;
		key = s;


		/* Key */
		end_of_key = skip_while_in(key, isalnum, "-_");
		if (end_of_key == key) {
			error = "No key";
			goto err;
		}

		if (!*end_of_key)
			goto exp_equal;


		/* whitespace, and something else but nothing more? */
		s = skip_while(end_of_key, isspace);


		if (*s != '=') {
exp_equal:
			error = "Expected '=' after key";
			goto err;
		}
		s++;

		/* It's my buffer, and I terminate if I want to. */
		/* But not earlier than that, because we had to check for = */
		*end_of_key = 0;


		/* Value tokenizing */
		s = skip_while(s, isspace);
		switch (*s) {
			case '"':
			case '\'':
				val = s+1;
				s = skip_until(val, *s);
				/* Terminate value */
				if (!*s) {
					error = "Unterminated quoted string";
					goto err;
				}

				/* Remove and skip quote */
				*s = 0;
				s++;
				if (*(s = skip_while(s, isspace)) && *s != '#') {
					error = "Surplus data after value";
					goto err;
				}

				*s = 0;

				break;

			case 0:
no_value:
				error = "No value";
				goto err;
				break;

			default:
				val = s;
				/* Rest of line. */
				i = strlen(s);
				/* i > 0 because of "case 0" above. */
				while (i > 0 && isspace(s[i-1]))
					i--;
				s += i;
				*s = 0;
		}

		if (val == s)
			goto no_value;


		if (strlen(key) > BOOTH_NAME_LEN
				|| strlen(val) > BOOTH_NAME_LEN) {
			error = "key/value too long";
			goto err;
		}

		if (strcmp(key, "transport") == 0) {
			if (got_transport) {
				error = "config file has multiple transport lines";
				goto err;
			}

			if (strcasecmp(val, "UDP") == 0)
				booth_conf->proto = UDP;
			else if (strcasecmp(val, "SCTP") == 0)
				booth_conf->proto = SCTP;
			else {
				error = "invalid transport protocol";
				goto err;
			}
			got_transport = 1;
			continue;
		}

		if (strcmp(key, "port") == 0) {
			booth_conf->port = atoi(val);
			continue;
		}

		if (strcmp(key, "name") == 0) {
			safe_copy(booth_conf->name, 
					val, BOOTH_NAME_LEN,
					"name");
			continue;
		}

#if HAVE_LIBGCRYPT || HAVE_LIBMHASH
		if (strcmp(key, "authfile") == 0) {
			safe_copy(booth_conf->authfile,
					val, BOOTH_PATH_LEN,
					"authfile");
			continue;
		}

		if (strcmp(key, "maxtimeskew") == 0) {
			booth_conf->maxtimeskew = atoi(val);
			continue;
		}
#endif

		if (strcmp(key, "site") == 0) {
			if (add_site(val, SITE))
				goto err;
			continue;
		}

		if (strcmp(key, "arbitrator") == 0) {
			if (add_site(val, ARBITRATOR))
				goto err;
			continue;
		}

		if (strcmp(key, "site-user") == 0) {
			safe_copy(booth_conf->site_user, optarg, BOOTH_NAME_LEN,
					"site-user");
			continue;
		}
		if (strcmp(key, "site-group") == 0) {
			safe_copy(booth_conf->site_group, optarg, BOOTH_NAME_LEN,
					"site-group");
			continue;
		}
		if (strcmp(key, "arbitrator-user") == 0) {
			safe_copy(booth_conf->arb_user, optarg, BOOTH_NAME_LEN,
					"arbitrator-user");
			continue;
		}
		if (strcmp(key, "arbitrator-group") == 0) {
			safe_copy(booth_conf->arb_group, optarg, BOOTH_NAME_LEN,
					"arbitrator-group");
			continue;
		}

		if (strcmp(key, "debug") == 0) {
			if (type != CLIENT && type != GEOSTORE)
				debug_level = max(debug_level, atoi(val));
			continue;
		}

		if (strcmp(key, "ticket") == 0) {
			if (current_tk && strcmp(current_tk->name, "__defaults__")) {
				if (!postproc_ticket(current_tk)) {
					goto err;
				}
			}
			if (!strcmp(val, "__defaults__")) {
				current_tk = &defaults;
			} else if (add_ticket(val, &current_tk, &defaults)) {
				goto err;
			}
			continue;
		}

		/* current_tk must be allocated at this point, otherwise
		 * we don't know to which ticket the key refers
		 */
		if (!current_tk) {
			error = "Unexpected keyword";
			goto err;
		}

		if (strcmp(key, "expire") == 0) {
			current_tk->term_duration = read_time(val);
			if (current_tk->term_duration <= 0) {
				error = "Expected time >0 for expire";
				goto err;
			}
			continue;
		}

		if (strcmp(key, "timeout") == 0) {
			current_tk->timeout = read_time(val);
			if (current_tk->timeout <= 0) {
				error = "Expected time >0 for timeout";
				goto err;
			}
			if (!min_timeout) {
				min_timeout = current_tk->timeout;
			} else {
				min_timeout = min(min_timeout, current_tk->timeout);
			}
			continue;
		}

		if (strcmp(key, "retries") == 0) {
			current_tk->retries = strtol(val, &s, 0);
			if (*s || s == val ||
					current_tk->retries<3 || current_tk->retries > 100) {
				error = "Expected plain integer value in the range [3, 100] for retries";
				goto err;
			}
			continue;
		}

		if (strcmp(key, "renewal-freq") == 0) {
			current_tk->renewal_freq = read_time(val);
			if (current_tk->renewal_freq <= 0) {
				error = "Expected time >0 for renewal-freq";
				goto err;
			}
			continue;
		}

		if (strcmp(key, "acquire-after") == 0) {
			current_tk->acquire_after = read_time(val);
			if (current_tk->acquire_after < 0) {
				error = "Expected time >=0 for acquire-after";
				goto err;
			}
			continue;
		}

		if (strcmp(key, "before-acquire-handler") == 0) {
			if (parse_extprog(val, current_tk)) {
				goto err;
			}
			continue;
		}

		if (strcmp(key, "attr-prereq") == 0) {
			if (parse_attr_prereq(val, current_tk)) {
				goto err;
			}
			continue;
		}

		if (strcmp(key, "mode") == 0) {
			current_tk->mode = retrieve_ticket_mode(val);
			continue;
		}

		if (strcmp(key, "weights") == 0) {
			if (parse_weights(val, current_tk->weight) < 0)
				goto err;
			continue;
		}

		error = "Unknown keyword";
		goto err;
	}
	fclose(fp);

	if ((booth_conf->site_count % 2) == 0) {
		log_warn("Odd number of nodes is strongly recommended!");
	}

	/* Default: make config name match config filename. */
	if (!booth_conf->name[0]) {
		cp = strrchr(path, '/');
		cp = cp ? cp+1 : (char *)path;
		cp2 = strrchr(cp, '.');
		if (!cp2)
			cp2 = cp + strlen(cp);
		if (cp2-cp >= BOOTH_NAME_LEN) {
			log_error("booth config file name too long");
			goto out;
		}
		strncpy(booth_conf->name, cp, cp2-cp);
		*(booth_conf->name+(cp2-cp)) = '\0';
	}

	if (!postproc_ticket(current_tk)) {
		goto out;
	}

	poll_timeout = min(POLL_TIMEOUT, min_timeout/10);
	if (!poll_timeout)
		poll_timeout = POLL_TIMEOUT;

	return 0;


err:
	fclose(fp);
out:
	log_error("%s in config file line %d",
			error, lineno);

	free(booth_conf);
	booth_conf = NULL;
	return -1;
}
コード例 #3
0
ファイル: chunk.cpp プロジェクト: chtq/via-httplib
    bool chunk_header::parse_char(char c)
    {
      static const size_t MAX_SIZE_DIGITS(16); // enough for a 64 bit number

      // Ensure that the overall header length is within limits
      if (++length_ > max_line_length_)
        state_ = CHUNK_ERROR_LENGTH;

      switch (state_)
      {
      case CHUNK_SIZE_LS:
        // Ignore leading whitespace
        if (is_space_or_tab(c))
        {
          // but only upto to a limit!
          if (++ws_count_ > max_whitespace_)
          {
            state_ = CHUNK_ERROR_WS;
            return false;
          }
          else
            break;
        }
        else
          state_ = CHUNK_SIZE;
        // intentional fall-through
      case CHUNK_SIZE:
        if (std::isxdigit (c))
        {
          hex_size_.push_back(c);
          // limit the length of the hex string
          if (hex_size_.size() > MAX_SIZE_DIGITS)
          {
            state_ = CHUNK_ERROR_SIZE;
            return false;
          }
        }
        else
        {
          if (is_end_of_line(c) || (';' == c))
          {
            size_ = from_hex_string(hex_size_);
            size_read_ = true;
            if (size_ > max_chunk_size_)
            {
              state_ = CHUNK_ERROR_SIZE;
              return false;
            }

            if (';' == c)
            {
              ws_count_ = 0;
              state_ = CHUNK_EXTENSION_LS;
            }
            else
            {
              if ('\r' == c)
                state_ = CHUNK_LF;
              else // ('\n' == c)
              {
                if (strict_crlf_)
                  return false;
                else
                  state_ = CHUNK_VALID;
              }
            }
          }
          else
            return false;
        }
        break;

      case CHUNK_EXTENSION_LS:
        // Ignore leading whitespace
        if (is_space_or_tab(c))
        {
          // but only upto to a limit!
          if (++ws_count_ > max_whitespace_)
            return false;
          else
            break;
        }
        else
          state_ = CHUNK_EXTENSION;
        // intentional fall-through
      case CHUNK_EXTENSION:
        if (!is_end_of_line(c))
          extension_.push_back(c);
        else if ('\r' == c)
          state_ = CHUNK_LF;
        else // ('\n' == c)
        {
          if (strict_crlf_)
          {
            state_ = CHUNK_ERROR_CRLF;
            return false;
          }
          else
            state_ = CHUNK_VALID;
        }
        break;

      case CHUNK_LF:
        if ('\n' == c)
          state_ = CHUNK_VALID;
        else
          return false;
        break;

      default:
        return false;
      }

      return true;
    }
コード例 #4
0
ファイル: GCodeReader.cpp プロジェクト: Sebastianv650/Slic3r
const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair<const char*, const char*> &command)
{
    PROFILE_FUNC();
    
    // command and args
    const char *c = ptr;
    {
        PROFILE_BLOCK(command_and_args);
        // Skip the whitespaces.
        command.first = skip_whitespaces(c);
        // Skip the command.
        c = command.second = skip_word(command.first);
        // Up to the end of line or comment.
		while (! is_end_of_gcode_line(*c)) {
            // Skip whitespaces.
            c = skip_whitespaces(c);
			if (is_end_of_gcode_line(*c))
				break;
            // Check the name of the axis.
            Axis axis = NUM_AXES;
            switch (*c) {
            case 'X': axis = X; break;
            case 'Y': axis = Y; break;
            case 'Z': axis = Z; break;
            case 'F': axis = F; break;
            default:
                if (*c == m_extrusion_axis)
                    axis = E;
                break;
            }
            if (axis != NUM_AXES) {
                // Try to parse the numeric value.
                char   *pend = nullptr;
                double  v = strtod(++ c, &pend);
                if (pend != nullptr && is_end_of_word(*pend)) {
                    // The axis value has been parsed correctly.
                    gline.m_axis[int(axis)] = float(v);
                    gline.m_mask |= 1 << int(axis);
                    c = pend;
                } else
                    // Skip the rest of the word.
                    c = skip_word(c);
            } else
                // Skip the rest of the word.
                c = skip_word(c);
        }
    }
    
    if (gline.has(E) && m_config.use_relative_e_distances)
        m_position[E] = 0;

    // Skip the rest of the line.
    for (; ! is_end_of_line(*c); ++ c);

    // Copy the raw string including the comment, without the trailing newlines.
    if (c > ptr) {
        PROFILE_BLOCK(copy_raw_string);
        gline.m_raw.assign(ptr, c);
    }

    // Skip the trailing newlines.
	if (*c == '\r')
		++ c;
	if (*c == '\n')
		++ c;

    if (m_verbose)
        std::cout << gline.m_raw << std::endl;

    return c;
}
コード例 #5
0
ファイル: request.cpp プロジェクト: aestuarium/via-httplib
    bool request_line::parse_char(char c)
    {


      switch (state_)
      {
      case REQ_METHOD:
        // Valid HTTP methods must be uppercase chars
        if (std::isupper(c))
        {
          method_.push_back(c);
          if (method_.size() > max_method_length_)
          {
            state_ = REQ_ERROR_METHOD_LENGTH;
            return false;
          }
        }
        // If this char is whitespace and method has been read
        else if (is_space_or_tab(c) && !method_.empty())
        {
          ws_count_ = 1;
          state_ = REQ_URI;
        }
        else
          return false;
        break;

      case REQ_URI:
        if (is_end_of_line(c))
          return false;
        else if (is_space_or_tab(c))
        {
          // Ignore leading whitespace
          // but only upto to a limit!
          if (++ws_count_ > max_whitespace_)
          {
            state_ = REQ_ERROR_WS;
            return false;
          }

          if (!uri_.empty())
          {
            ws_count_ = 1;
            state_ = REQ_HTTP_H;
          }
        }
        else
        {
          uri_.push_back(c);
          if (uri_.size() > max_uri_length_)
          {
            state_ = REQ_ERROR_URI_LENGTH;
            return false;
          }
        }
        break;

      case REQ_HTTP_H:
        // Ignore leading whitespace
        if (is_space_or_tab(c))
        {
          // but only upto to a limit!
          if (++ws_count_ > max_whitespace_)
          {
            state_ = REQ_ERROR_WS;
            return false;
          }
        }
        else
        {
          if ('H' == c)
            state_ = REQ_HTTP_T1;
          else
            return false;
        }
        break;

      case REQ_HTTP_T1:
        if ('T' == c)
          state_ = REQ_HTTP_T2;
        else
          return false;
        break;

      case REQ_HTTP_T2:
        if ('T' == c)
          state_ = REQ_HTTP_P;
        else
          return false;
        break;

      case REQ_HTTP_P:
        if ('P' == c)
          state_ = REQ_HTTP_SLASH;
        else
          return false;
        break;

      case REQ_HTTP_SLASH:
        if ('/' == c)
          state_ = REQ_HTTP_MAJOR;
        else
          return false;
        break;

      case REQ_HTTP_MAJOR:
        if (std::isdigit(c))
        {
          major_version_ = c;
          state_ = REQ_HTTP_DOT;
        }
        else
          return false;
        break;

      case REQ_HTTP_DOT:
        if ('.' == c)
            state_ = REQ_HTTP_MINOR;
          else
            return false;
        break;

      case REQ_HTTP_MINOR:
        if (std::isdigit(c))
        {
          minor_version_ = c;
          state_ = REQ_CR;
        }
        else
          return false;
        break;

      case REQ_CR:
        // The HTTP line should end with a \r\n...
            if ('\r' == c)
          state_ = REQ_LF;
          else
        {
          // but (if not being strict) permit just \n
          if (!strict_crlf_ && ('\n' == c))
            state_ = REQ_VALID;
          else
          {
            state_ = REQ_ERROR_CRLF;
            return false;
        }
        }
        break;

      case REQ_LF:
        if ('\n' == c)
        {
          state_ = REQ_VALID;
        break;
        }
        // intentional fall-through (for code coverage)

      default:
        return false;
      }

      return true;
    }