int BatteryMonitor::readFromFile(const String8& path, char* buf, size_t size) {
    char *cp = NULL;

    if (path.isEmpty())
        return -1;
    int fd = open(path.string(), O_RDONLY, 0);
    if (fd == -1) {
        KLOG_ERROR(LOG_TAG, "Could not open '%s'\n", path.string());
        return -1;
    }

    ssize_t count = TEMP_FAILURE_RETRY(read(fd, buf, size));
    if (count > 0)
            cp = (char *)memrchr(buf, '\n', count);

    if (cp)
        *cp = '\0';
    else
        buf[0] = '\0';

    close(fd);
    return count;
}
Beispiel #2
0
/**
 * Described in header.
 */
char* path_dirname(const char *path)
{
	char *pos;

	pos = path ? strrchr(path, '/') : NULL;

	if (pos && !pos[1])
	{	/* if path ends with slashes we have to look beyond them */
		while (pos > path && *pos == '/')
		{	/* skip trailing slashes */
			pos--;
		}
		pos = memrchr(path, '/', pos - path + 1);
	}
	if (!pos)
	{
		return strdup(".");
	}
	while (pos > path && *pos == '/')
	{	/* skip superfluous slashes */
		pos--;
	}
	return strndup(path, pos - path + 1);
}
Beispiel #3
0
static void handleBufferedMsg(char *msg, uint32_t len, PS_DataBuffer_t *buffer,
			      Forwarder_Data_t *fwdata, Step_t *step,
			      uint32_t taskid, uint8_t type, uint32_t lrank)
{
    uint32_t nlLen;
    char *nl;

    nl = len ? memrchr(msg, '\n', len) : NULL;

    if (nl || !len || buffer->bufUsed + len > MAX_LINE_BUF_LENGTH) {
	if (buffer->bufUsed) {
	    writeLabelIOmsg(buffer->buf, buffer->bufUsed, taskid, type,
			fwdata, step, lrank);
	    buffer->bufUsed = 0;
	}
	nlLen = nl ? nl - msg +1: len;
	writeLabelIOmsg(msg, nlLen, taskid, type, fwdata, step, lrank);
	if (len - nlLen > 0) {
	    memToDataBuffer(msg + nlLen, len - nlLen, buffer);
	}
    } else {
	memToDataBuffer(msg, len, buffer);
    }
}
Beispiel #4
0
// try to remove the 'irrelevant' prefix of a multiboot path
// eg. "/username/blerg/x86_64/sbin/foo..." becomes "/x86_64/sbin/foo..."
static const char *remove_prefix(const char *path)
{
    static char *theprefix;
    static size_t theprefixlen;

    // don't know anything
    if (theprefix == NULL) {
        // walk forward until we see '/sbin/'
        char *sbin = strstr(path, "/sbin/");
        if (sbin == NULL || sbin == path) {
            return path; // give up
        }

        // walk backward one path element (the architecture)
        char *prevsep = memrchr(path, '/', sbin - path);
        if (prevsep == NULL) {
            return path; // give up
        }

        // store copy of prefix for future use
        theprefixlen = prevsep - path;
        theprefix = malloc(theprefixlen + 1);
        assert(theprefix != NULL);
        memcpy(theprefix, path, theprefixlen);
        theprefix[theprefixlen] = '\0';

        return prevsep;
    } else if (strncmp(theprefix, path, theprefixlen) == 0) {
        // check if stored prefix matches
        return &path[theprefixlen];
    } else { // no match?
        debug_printf("remove_prefix(): '%s' doesn't match stored prefix '%s'\n",
                     path, theprefix);
        return path;
    }
}
/* Read an entire line. Returns 0 on success or -1 and ERRNO on
   failure.  EOF is indictated by setting the integer at address
   R_EOF.  Note: BUF, R_NREAD and R_EOF contain a valid result even if
   an error is returned.  */
static int
readline (assuan_context_t ctx, char *buf, size_t buflen,
	  int *r_nread, int *r_eof)
{
  size_t nleft = buflen;
  char *p;

  *r_eof = 0;
  *r_nread = 0;
  while (nleft > 0)
    {
      ssize_t n = ctx->engine.readfnc (ctx, buf, nleft);

      if (n < 0)
        {
          if (errno == EINTR)
            continue;
          return -1; /* read error */
        }
      else if (!n)
        {
          *r_eof = 1;
          break; /* allow incomplete lines */
        }

      p = buf;
      nleft -= n;
      buf += n;
      *r_nread += n;

      p = memrchr (p, '\n', n);
      if (p)
        break; /* at least one full line available - that's enough for now */
    }
  return 0;
}
/* Read a line with buffering of partial lines.  Function returns an
   Assuan error.  */
gpg_error_t
_assuan_read_line (assuan_context_t ctx)
{
  gpg_error_t rc = 0;
  char *line = ctx->inbound.line;
  int nread, atticlen;
  char *endp = 0;

  if (ctx->inbound.eof)
    return _assuan_error (ctx, GPG_ERR_EOF);

  atticlen = ctx->inbound.attic.linelen;
  if (atticlen)
    {
      memcpy (line, ctx->inbound.attic.line, atticlen);
      ctx->inbound.attic.linelen = 0;

      endp = memchr (line, '\n', atticlen);
      if (endp)
	{
	  /* Found another line in the attic.  */
	  nread = atticlen;
	  atticlen = 0;
	}
      else
        {
	  /* There is pending data but not a full line.  */
          assert (atticlen < LINELENGTH);
          rc = readline (ctx, line + atticlen,
			 LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
        }
    }
  else
    /* No pending data.  */
    rc = readline (ctx, line, LINELENGTH,
                   &nread, &ctx->inbound.eof);
  if (rc)
    {
      int saved_errno = errno;
      char buf[100];

      snprintf (buf, sizeof buf, "error: %s", strerror (errno));
      _assuan_log_control_channel (ctx, 0, buf, NULL, 0, NULL, 0);

      if (saved_errno == EAGAIN)
        {
          /* We have to save a partial line.  Due to readline's
	     behaviour, we know that this is not a complete line yet
	     (no newline).  So we don't set PENDING to true.  */
          memcpy (ctx->inbound.attic.line, line, atticlen + nread);
          ctx->inbound.attic.pending = 0;
          ctx->inbound.attic.linelen = atticlen + nread;
        }

      gpg_err_set_errno (saved_errno);
      return _assuan_error (ctx, gpg_err_code_from_syserror ());
    }
  if (!nread)
    {
      assert (ctx->inbound.eof);
      _assuan_log_control_channel (ctx, 0, "eof", NULL, 0, NULL, 0);
      return _assuan_error (ctx, GPG_ERR_EOF);
    }

  ctx->inbound.attic.pending = 0;
  nread += atticlen;

  if (! endp)
    endp = memchr (line, '\n', nread);

  if (endp)
    {
      unsigned monitor_result;
      int n = endp - line + 1;

      if (n < nread)
	/* LINE contains more than one line.  We copy it to the attic
	   now as handlers are allowed to modify the passed
	   buffer.  */
	{
	  int len = nread - n;
	  memcpy (ctx->inbound.attic.line, endp + 1, len);
	  ctx->inbound.attic.pending = memrchr (endp + 1, '\n', len) ? 1 : 0;
	  ctx->inbound.attic.linelen = len;
	}

      if (endp != line && endp[-1] == '\r')
	endp --;
      *endp = 0;

      ctx->inbound.linelen = endp - line;

      monitor_result = 0;
      if (ctx->io_monitor)
	monitor_result = ctx->io_monitor (ctx, ctx->io_monitor_data, 0,
					  ctx->inbound.line,
					  ctx->inbound.linelen);
      if (monitor_result & ASSUAN_IO_MONITOR_IGNORE)
        ctx->inbound.linelen = 0;

      if ( !(monitor_result & ASSUAN_IO_MONITOR_NOLOG))
        _assuan_log_control_channel (ctx, 0, NULL,
                                     ctx->inbound.line, ctx->inbound.linelen,
                                     NULL, 0);
      return 0;
    }
  else
    {
      _assuan_log_control_channel (ctx, 0, "invalid line",
                                   NULL, 0, NULL, 0);
      *line = 0;
      ctx->inbound.linelen = 0;
      return _assuan_error (ctx, ctx->inbound.eof
			    ? GPG_ERR_ASS_INCOMPLETE_LINE
			    : GPG_ERR_ASS_LINE_TOO_LONG);
    }
}
Beispiel #7
0
bool url_parse(Url &output, const char *str, int length) {
  memset(&output, 0, sizeof(Url));

  char port_buf[6];
  const char *s, *e, *p, *pp, *ue;

  s = str;
  ue = s + length;

  /* parse scheme */
  if ((e = (const char *)memchr((const void *)s, ':', length)) && (e - s)) {
    /* validate scheme */
    p = s;
    while (p < e) {
      /* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */
      if (!isalpha(*p) && !isdigit(*p) &&
          *p != '+' && *p != '.' && *p != '-') {
        if (e + 1 < ue) {
          goto parse_port;
        } else {
          goto just_path;
        }
      }
      p++;
    }

    if (*(e + 1) == '\0') { /* only scheme is available */
      output.scheme = string_duplicate(s, (e - s));
      replace_controlchars(output.scheme, (e - s));
      goto end;
    }

    /*
     * certain schemas like mailto: and zlib: may not have any / after them
     * this check ensures we support those.
     */
    if (*(e+1) != '/') {
      /* check if the data we get is a port this allows us to
       * correctly parse things like a.com:80
       */
      p = e + 1;
      while (isdigit(*p)) {
        p++;
      }

      if ((*p == '\0' || *p == '/') && (p - e) < 7) {
        goto parse_port;
      }

      output.scheme = string_duplicate(s, (e-s));
      replace_controlchars(output.scheme, (e - s));

      length -= ++e - s;
      s = e;
      goto just_path;
    } else {
      output.scheme = string_duplicate(s, (e-s));
      replace_controlchars(output.scheme, (e - s));

      if (*(e+2) == '/') {
        s = e + 3;
        if (!strncasecmp("file", output.scheme, sizeof("file"))) {
          if (*(e + 3) == '/') {
            /* support windows drive letters as in:
               file:///c:/somedir/file.txt
            */
            if (*(e + 5) == ':') {
              s = e + 4;
            }
            goto nohost;
          }
        }
      } else {
        if (!strncasecmp("file", output.scheme, sizeof("file"))) {
          s = e + 1;
          goto nohost;
        } else {
          length -= ++e - s;
          s = e;
          goto just_path;
        }
      }
    }
  } else if (e) { /* no scheme, look for port */
    parse_port:
    p = e + 1;
    pp = p;

    while (pp-p < 6 && isdigit(*pp)) {
      pp++;
    }

    if (pp-p < 6 && (*pp == '/' || *pp == '\0')) {
      memcpy(port_buf, p, (pp-p));
      port_buf[pp-p] = '\0';
      output.port = atoi(port_buf);
    } else {
      goto just_path;
    }
  } else {
    just_path:
    ue = s + length;
    goto nohost;
  }

  e = ue;

  if (!(p = (const char *)memchr(s, '/', (ue - s)))) {
    if ((p = (const char *)memchr(s, '?', (ue - s)))) {
      e = p;
    } else if ((p = (const char *)memchr(s, '#', (ue - s)))) {
      e = p;
    }
  } else {
    e = p;
  }

  /* check for login and password */
  if ((p = (const char *)memrchr(s, '@', (e-s)))) {
    if ((pp = (const char *)memchr(s, ':', (p-s)))) {
      if ((pp-s) > 0) {
        output.user = string_duplicate(s, (pp-s));
        replace_controlchars(output.user, (pp - s));
      }

      pp++;
      if (p-pp > 0) {
        output.pass = string_duplicate(pp, (p-pp));
        replace_controlchars(output.pass, (p-pp));
      }
    } else {
      output.user = string_duplicate(s, (p-s));
      replace_controlchars(output.user, (p-s));
    }

    s = p + 1;
  }

  /* check for port */
  if (*s == '[' && *(e-1) == ']') {
    /* Short circuit portscan,
       we're dealing with an
       IPv6 embedded address */
    p = s;
  } else {
    /* memrchr is a GNU specific extension
       Emulate for wide compatability */
    for(p = e; *p != ':' && p >= s; p--);
  }

  if (p >= s && *p == ':') {
    if (!output.port) {
      p++;
      if (e-p > 5) { /* port cannot be longer then 5 characters */
        return false;
      } else if (e - p > 0) {
        memcpy(port_buf, p, (e-p));
        port_buf[e-p] = '\0';
        output.port = atoi(port_buf);
      }
      p--;
    }
  } else {
    p = e;
  }

  /* check if we have a valid host, if we don't reject the string as url */
  if ((p-s) < 1) {
    return false;
  }

  output.host = string_duplicate(s, (p-s));
  replace_controlchars(output.host, (p - s));

  if (e == ue) {
    return true;
  }

  s = e;

  nohost:

  if ((p = (const char *)memchr(s, '?', (ue - s)))) {
    pp = strchr(s, '#');

    if (pp && pp < p) {
      p = pp;
      pp = strchr(pp+2, '#');
    }

    if (p - s) {
      output.path = string_duplicate(s, (p-s));
      replace_controlchars(output.path, (p - s));
    }

    if (pp) {
      if (pp - ++p) {
        output.query = string_duplicate(p, (pp-p));
        replace_controlchars(output.query, (pp - p));
      }
      p = pp;
      goto label_parse;
    } else if (++p - ue) {
      output.query = string_duplicate(p, (ue-p));
      replace_controlchars(output.query, (ue - p));
    }
  } else if ((p = (const char *)memchr(s, '#', (ue - s)))) {
    if (p - s) {
      output.path = string_duplicate(s, (p-s));
      replace_controlchars(output.path, (p - s));
    }

    label_parse:
    p++;

    if (ue - p) {
      output.fragment = string_duplicate(p, (ue-p));
      replace_controlchars(output.fragment, (ue - p));
    }
  } else {
    output.path = string_duplicate(s, (ue-s));
    replace_controlchars(output.path, (ue - s));
  }
end:
  return true;
}
Beispiel #8
0
    bool ImportHelper::importJson (const string& collectionName, const string& fileName) {
      _collectionName = collectionName;
      _firstLine = "";
      _numberLines = 0;
      _numberOk = 0;
      _numberError = 0;
      _outputBuffer.clear();
      _errorMessage = "";
      _hasError = false;

      // read and convert
      int fd;
      int64_t totalLength;

      if (fileName == "-") {
        // we don't have a filesize
        totalLength = 0;
        fd = STDIN_FILENO;
      }
      else {
        // read filesize
        totalLength = TRI_SizeFile(fileName.c_str());
        fd = TRI_OPEN(fileName.c_str(), O_RDONLY);
      
        if (fd < 0) {
          _errorMessage = TRI_LAST_ERROR_STR;
          return false;
        }
      }

      char buffer[32768];
      bool isArray = false;
      bool checkedFront = false;

      // progress display control variables
      int64_t totalRead = 0;
      double nextProgress = ProgressStep;

      while (! _hasError) {
        ssize_t n = TRI_READ(fd, buffer, sizeof(buffer));

        if (n < 0) {
          _errorMessage = TRI_LAST_ERROR_STR;
          if (fd != STDIN_FILENO) {
            TRI_CLOSE(fd);
          }
          return false;
        }
        else if (n == 0) {
          // we're done
          break;
        }

        if (! checkedFront) {
          // detect the import file format (single lines with individual JSON objects
          // or a JSON array with all documents)
          const string firstChar = StringUtils::lTrim(string(buffer, n), "\r\n\t\f\b ").substr(0, 1);
          isArray = (firstChar == "[");
          checkedFront = true;
        }

        _outputBuffer.appendText(buffer, n);

        totalRead += (int64_t) n;
        reportProgress(totalLength, totalRead, nextProgress);

        if (_outputBuffer.length() > _maxUploadSize) {
          if (isArray) {
            if (fd != STDIN_FILENO) {
              TRI_CLOSE(fd);
            }
            _errorMessage = "import file is too big.";
            return false;
          }

          // send all data before last '\n'
          const char* first = _outputBuffer.c_str();
          char* pos = (char*) memrchr(first, '\n', _outputBuffer.length());

          if (pos != 0) {
            size_t len = pos - first + 1;
            sendJsonBuffer(first, len, isArray);
            _outputBuffer.erase_front(len);
          }
        }
      }

      if (_outputBuffer.length() > 0) {
        sendJsonBuffer(_outputBuffer.c_str(), _outputBuffer.length(), isArray);
      }

      _numberLines = _numberError + _numberOk;

      if (fd != STDIN_FILENO) {
        TRI_CLOSE(fd);
      }

      _outputBuffer.clear();
      return ! _hasError;
    }
Beispiel #9
0
    bool ImportHelper::importJson (const string& collectionName, const string& fileName) {
      _collectionName = collectionName;
      _firstLine = "";
      _numberLines = 0;
      _numberOk = 0;
      _numberError = 0;
      _outputBuffer.clear();
      _errorMessage = "";
      _hasError = false;

      // read and convert
      int fd;
      int64_t totalLength;

      if (fileName == "-") {
        // we don't have a filesize
        totalLength = 0;
        fd = STDIN_FILENO;
      }
      else {
        // read filesize
        totalLength = TRI_SizeFile(fileName.c_str());
        fd = TRI_OPEN(fileName.c_str(), O_RDONLY);

        if (fd < 0) {
          _errorMessage = TRI_LAST_ERROR_STR;
          return false;
        }
      }

      bool isArray = false;
      bool checkedFront = false;

      // progress display control variables
      int64_t totalRead = 0;
      double nextProgress = ProgressStep;

      static const int BUFFER_SIZE = 32768;

      while (! _hasError) {
        // reserve enough room to read more data
        if (_outputBuffer.reserve(BUFFER_SIZE) == TRI_ERROR_OUT_OF_MEMORY) {
          _errorMessage = TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY);

          if (fd != STDIN_FILENO) {
            TRI_CLOSE(fd);
          }
          return false;
        }

        // read directly into string buffer
        ssize_t n = TRI_READ(fd, _outputBuffer.end(), BUFFER_SIZE - 1);

        if (n < 0) {
          _errorMessage = TRI_LAST_ERROR_STR;
          if (fd != STDIN_FILENO) {
            TRI_CLOSE(fd);
          }
          return false;
        }
        else if (n == 0) {
          // we're done
          break;
        }

        // adjust size of the buffer by the size of the chunk we just read
        _outputBuffer.increaseLength(n);

        if (! checkedFront) {
          // detect the import file format (single lines with individual JSON objects
          // or a JSON array with all documents)
          char const* p = _outputBuffer.begin();
          char const* e = _outputBuffer.end();

          while (p < e &&
                 (*p == ' ' || *p == '\r' || *p == '\n' || *p == '\t' || *p == '\f' || *p == '\b')) {
            ++p;
          }

          isArray = (*p == '[');
          checkedFront = true;
        }

        totalRead += (int64_t) n;
        reportProgress(totalLength, totalRead, nextProgress);

        if (_outputBuffer.length() > _maxUploadSize) {
          if (isArray) {
            if (fd != STDIN_FILENO) {
              TRI_CLOSE(fd);
            }
            _errorMessage = "import file is too big. please increase the value of --batch-size (currently " + StringUtils::itoa(_maxUploadSize) + ")";
            return false;
          }

          // send all data before last '\n'
          char const* first = _outputBuffer.c_str();
          char* pos = (char*) memrchr(first, '\n', _outputBuffer.length());

          if (pos != 0) {
            size_t len = pos - first + 1;
            sendJsonBuffer(first, len, isArray);
            _outputBuffer.erase_front(len);
          }
        }
      }

      if (_outputBuffer.length() > 0) {
        sendJsonBuffer(_outputBuffer.c_str(), _outputBuffer.length(), isArray);
      }

      _numberLines = _numberError + _numberOk;

      if (fd != STDIN_FILENO) {
        TRI_CLOSE(fd);
      }

      _outputBuffer.clear();
      return ! _hasError;
    }
void UrlParser::parse() {
	// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

	const char *urlEnd = m_url + m_urlLen;
	const char *currentPos = m_url;

	// hier-part   = "//" authority path-abempty
	//             / path-absolute
	//             / path-rootless
	//             / path-empty

	const char *authorityPos = static_cast<const char*>( memmem( currentPos, urlEnd - currentPos, "//", 2 ) );
	if ( authorityPos != NULL ) {
		if ( authorityPos != currentPos ) {
			m_scheme = currentPos;
			m_schemeLen = authorityPos - currentPos - 1;
		}

		m_authority = authorityPos + 2;
		currentPos = m_authority;
	} else {
		m_authority = currentPos;
	}

	const char *pathPos = static_cast<const char*>( memchr( currentPos, '/', urlEnd - currentPos ) );
	if ( pathPos != NULL ) {
		m_authorityLen = pathPos - m_authority;
		currentPos = pathPos + 1;
	} else {
		m_authorityLen = urlEnd - m_authority;

		// nothing else to process
		return;
	}

	// @todo similar logic in Url.cpp ( merge this )

	// authority   = [ userinfo "@" ] host [ ":" port ]
	const char *userInfoPos = static_cast<const char *>( memchr( m_authority, '@', m_authorityLen ) );
	if ( userInfoPos != NULL ) {
		m_host = userInfoPos + 1;
		m_hostLen = m_authorityLen - ( userInfoPos - m_authority ) - 1;
	} else {
		m_host = m_authority;
		m_hostLen = m_authorityLen;
	}

	const char *portPos = static_cast<const char *>( memrchr( m_host, ':', m_hostLen ) );
	if ( portPos != NULL ) {
		m_hostLen -= ( m_hostLen - ( portPos - m_host ) );
	}

	// host        = IP-literal / IPv4address / reg-name

	/// @todo ALC we should remove the const cast once we fix all the const issue
	int32_t ip = atoip( m_host, m_hostLen );
	if ( ip ) {
		int32_t domainLen = 0;
		m_domain = getDomainOfIp ( const_cast<char *>( m_host ), m_hostLen , &domainLen );
		m_domainLen = domainLen;
	} else {
		const char *tldPos = ::getTLD( const_cast<char *>( m_host ), m_hostLen );
		if ( tldPos ) {
			size_t tldLen = m_host + m_hostLen - tldPos;
			if ( tldLen < m_hostLen ) {
				m_domain = static_cast<const char *>( memrchr( m_host, '.', m_hostLen - tldLen - 1 ) );
				if ( m_domain ) {
					m_domain += 1;
					m_domainLen = m_hostLen - ( m_domain - m_host );
				} else {
					m_domain = m_host;
					m_domainLen = m_hostLen;
				}
			}
		}
	}

	const char *queryPos = static_cast<const char*>( memchr( currentPos, '?', urlEnd - currentPos ) );
	if ( queryPos != NULL ) {
		currentPos = queryPos + 1;
	}

	const char *anchorPos = static_cast<const char*>( memrchr( currentPos, '#', urlEnd - currentPos ) );
//	if ( anchorPos != NULL ) {
//		currentPos = anchorPos + 1;
//	}

	const char *pathEnd = queryPos ? queryPos : (anchorPos ? anchorPos : urlEnd);
	m_pathEndChar = *( pathEnd - 1 );

	const char *queryEnd = anchorPos ? anchorPos : urlEnd;

	// path
	const char *prevPos = pathPos + 1;
	while ( prevPos && ( prevPos <= pathEnd ) ) {
		size_t len = pathEnd - prevPos;
		currentPos = strnpbrk( prevPos, len, "/;&" );
		if ( currentPos ) {
			len = currentPos - prevPos;
		}

		UrlComponent urlPart = UrlComponent( UrlComponent::TYPE_PATH, prevPos, len, *( prevPos - 1 ) );

		m_paths.push_back( urlPart );

		prevPos = currentPos ? currentPos + 1 : NULL;
	}

	// query
	if ( queryPos ) {
		prevPos = queryPos + 1;

		bool isPrevAmpersand = false;
		while ( prevPos && ( prevPos < queryEnd ) ) {
			size_t len = queryEnd - prevPos;
			currentPos = strnpbrk( prevPos, len, "&;" );
			if ( currentPos ) {
				len = currentPos - prevPos;
			}

			UrlComponent urlPart = UrlComponent( UrlComponent::TYPE_QUERY, prevPos, len, *( prevPos - 1 ) );
			std::string key = urlPart.getKey();

			// check previous urlPart
			if ( isPrevAmpersand ) {
				urlPart.setSeparator( '&' );
			}

			bool isAmpersand = ( !urlPart.hasValue() && urlPart.getKey() == "amp" );
			if ( !key.empty() && !isAmpersand ) {
				// we don't cater for case sensitive query parameter (eg: parm, Parm, PARM is assumed to be the same)
				auto it = m_queriesMap.find( key );
				if (it == m_queriesMap.end()) {
					m_queries.push_back( urlPart );
					m_queriesMap[key] = m_queries.size() - 1;
				} else {
					m_queries[it->second] = urlPart;
				}
			}

			prevPos = currentPos ? currentPos + 1 : NULL;
			isPrevAmpersand = isAmpersand;
		}
	}
}
Beispiel #11
0
int RenderCurses::outputWrapped(clc::Buffer *b, unsigned int strOffset, bool doBlit)
{
    int len = b->size();
    const unsigned char *start = (const unsigned char*)b->data();
    const unsigned char *p = start;

    ASSERT(strOffset <= len);
    len -= strOffset;
    p += strOffset;

    do {
        int w = m_width - m_x;

        // If at start of line, eat spaces
        if (m_x == 0) {
            while (*p != '\n' && isspace(*p)) {
                ++p;
                --len;
            }
        }

        // How many chars should go out on this line?
        const unsigned char *nl = 0;
        int n = w;
        if (w >= len) {
            n = len;
            nl = (const unsigned char *)memchr(p, '\n', n);
        } else {
            nl = (const unsigned char *)memchr(p, '\n', n);
            if (!nl) {
                // don't break words
                if (!isspace(*(p+n-1)) && !isspace(*(p+n))) {
                    unsigned char *space = (unsigned char*)memrchr(p, ' ', n);
                    if (space) {
                        nl = space;
                    }
                }
            }
        }
        if (nl)
            n = nl - p;

        if (doBlit) {
            mvwaddnstr(m_scr, m_y, m_x, (const char*)p, n);
        }
        p += n;
        len -= n;
        m_x += n;
        if (nl || m_x >= m_width-1) {
            m_x = 0;
            m_y++;
            if (nl) {
                p++;
                len--;
            }
            if (m_height > 0 && m_y + 1 >= m_height) {
                return p - start;
            }
        }
    } while (len > 0);
    return -1;
}
int
chdir_long (char *dir)
{
  int e = chdir (dir);
  if (e == 0 || errno != ENAMETOOLONG)
    return e;

  {
    size_t len = strlen (dir);
    char *dir_end = dir + len;
    struct cd_buf cdb;
    size_t n_leading_slash;

    cdb_init (&cdb);

    /* If DIR is the empty string, then the chdir above
       must have failed and set errno to ENOENT.  */
    assert (0 < len);
    assert (PATH_MAX <= len);

    /* Count leading slashes.  */
    n_leading_slash = strspn (dir, "/");

    /* Handle any leading slashes as well as any name that matches
       the regular expression, m!^//hostname[/]*! .  Handling this
       prefix separately usually results in a single additional
       cdb_advance_fd call, but it's worthwhile, since it makes the
       code in the following loop cleaner.  */
    if (n_leading_slash == 2)
      {
	int err;
	/* Find next slash.
	   We already know that dir[2] is neither a slash nor '\0'.  */
	char *slash = memchr (dir + 3, '/', dir_end - (dir + 3));
	if (slash == NULL)
	  {
	    errno = ENAMETOOLONG;
	    return -1;
	  }
	*slash = '\0';
	err = cdb_advance_fd (&cdb, dir);
	*slash = '/';
	if (err != 0)
	  goto Fail;
	dir = find_non_slash (slash + 1);
      }
    else if (n_leading_slash)
      {
	if (cdb_advance_fd (&cdb, "/") != 0)
	  goto Fail;
	dir += n_leading_slash;
      }

    assert (*dir != '/');
    assert (dir <= dir_end);

    while (PATH_MAX <= dir_end - dir)
      {
	int err;
	/* Find a slash that is PATH_MAX or fewer bytes away from dir.
	   I.e. see if there is a slash that will give us a name of
	   length PATH_MAX-1 or less.  */
	char *slash = memrchr (dir, '/', PATH_MAX);
	if (slash == NULL)
	  {
	    errno = ENAMETOOLONG;
	    return -1;
	  }

	*slash = '\0';
	assert (slash - dir < PATH_MAX);
	err = cdb_advance_fd (&cdb, dir);
	*slash = '/';
	if (err != 0)
	  goto Fail;

	dir = find_non_slash (slash + 1);
      }

    if (dir < dir_end)
      {
	if (cdb_advance_fd (&cdb, dir) != 0)
	  goto Fail;
      }

    if (cdb_fchdir (&cdb) != 0)
      goto Fail;

    cdb_free (&cdb);
    return 0;

   Fail:
    {
      int saved_errno = errno;
      cdb_free (&cdb);
      errno = saved_errno;
      return -1;
    }
  }
}
Beispiel #13
0
void search_buffer (int thread_id, const char* file_name, 
                    const char* query, int buf_num, 
                    struct iovec* buffer)
{

  fprintf(stderr,"search_buffer %d : %s %s %d \n"
          ,thread_id,file_name,query,buf_num);

  void* buf_base = buffer->iov_base;
  int   buf_len = buffer->iov_len;

  int   buf_end_pos = buf_len-1;
  int   buf_file_pos = buffer->iov_len*buf_num;
  
  void* match_idx = NULL;
  int offset = 0;
  int loop_count = 0;
  int lquery = strlen(query);

  while ( offset < buf_end_pos
          && (match_idx = memmem(buf_base+offset, /* haystack start */
                                 buf_len-offset,  /* haystack len   */
                                 query,
                                 lquery)) != NULL) {

    // Found a match
    int match_pos  =  (match_idx - buf_base );
    // offset right after match
    offset = match_pos+1;
    
    //find end of line
    int line_end_pos = buf_end_pos;
    void* line_end = memchr(match_idx,'\n',buf_len-match_pos);

    if(line_end != NULL)
      line_end_pos = line_end - buf_base -1;

    //find beginning of line
    int line_begin_pos = 0;
    void* line_begin = memrchr(buf_base,'\n',match_pos-1);

    if(line_begin!=NULL){ // no begining of line found
      line_begin_pos = line_begin - buf_base+1;
    }
    
    int line_length = line_end_pos - line_begin_pos + 1;

    int match_file_pos =  buf_file_pos + match_pos;

    if(line_length < 0) {
      fprintf(stderr, "search_buffer WARNING negative line length  buffer length %d match_pos %d \n", buf_len, match_pos);
    }

    fprintf(stderr,"MATCH : [T %d][loop %d][buf %d]search_buffers line offset %d [%p %p] [ %d -  %d] length %d\n"
            ,thread_id
            ,loop_count
            ,buf_num
            ,offset,line_begin, line_end,
            line_begin_pos, line_end_pos, line_length);
    

    char match_string[line_length+1];
    memcpy(&match_string, buf_base+line_begin_pos, line_length);
    match_string[line_length]='\0';   

    //fprintf(stderr,"[T:%d] match: [%d]%s: %d: [%s]  \n", thread_id,buf_num,file_name,match_file_pos,match_string);
    //TODO seeing duplicates in results
    fprintf(stdout,"%s:%d:%s\n",file_name,match_file_pos,match_string);

    loop_count++;

  }
}
Beispiel #14
0
void 
do_tunnel(int fd, char *buf, int offset, int len, AtomPtr url)
{
    TunnelPtr tunnel;
    int port;
    char *p, *q;

    tunnel = makeTunnel(fd, buf, offset, len);
    if(tunnel == NULL) {
        do_log(L_ERROR, "Couldn't allocate tunnel.\n");
        releaseAtom(url);
        dispose_chunk(buf);
        CLOSE(fd);
        return;
    }

    if(proxyOffline) {
        do_log(L_INFO, "Attemted CONNECT when disconnected.\n");
        releaseAtom(url);
        tunnelError(tunnel, 502,
                    internAtom("Cannot CONNECT when disconnected."));
        return;
    }

    p = memrchr(url->string, ':', url->length);
    q = NULL;
    if(p)
        port = strtol(p + 1, &q, 10);
    if(!p || q != url->string + url->length) {
        do_log(L_ERROR, "Couldn't parse CONNECT.\n");
        releaseAtom(url);
        tunnelError(tunnel, 400, internAtom("Couldn't parse CONNECT"));
        return;
    }
    tunnel->hostname = internAtomLowerN(url->string, p - url->string);
    if(tunnel->hostname == NULL) {
        releaseAtom(url);
        tunnelError(tunnel, 501, internAtom("Couldn't allocate hostname"));
        return;
    }

    if(!intListMember(port, tunnelAllowedPorts)) {
        releaseAtom(url);
        tunnelError(tunnel, 403, internAtom("Forbidden port"));
        return;
    }
    tunnel->port = port;
    
    if (tunnelIsMatched(url->string, url->length, 
			tunnel->hostname->string, tunnel->hostname->length)) {
        releaseAtom(url);
        tunnelError(tunnel, 404, internAtom("Forbidden tunnel"));
	logTunnel(tunnel,1);
        return;
    }
    
    logTunnel(tunnel,0);
    
    releaseAtom(url);

    if(socksParentProxy)
        do_socks_connect(parentHost ?
                         parentHost->string : tunnel->hostname->string,
                         parentHost ? parentPort : tunnel->port,
                         tunnelSocksHandler, tunnel);
    else
        do_gethostbyname(parentHost ?
                         parentHost->string : tunnel->hostname->string, 0,
                         tunnelDnsHandler, tunnel);
}
Beispiel #15
0
static int
do_test (void)
{
  int size = sysconf (_SC_PAGESIZE);
  int nchars = size / sizeof (CHAR);
  CHAR *adr;
  CHAR *dest;
  int result = 0;

  adr = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
		       MAP_PRIVATE | MAP_ANON, -1, 0);
  dest = (CHAR *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
			MAP_PRIVATE | MAP_ANON, -1, 0);
  if (adr == MAP_FAILED || dest == MAP_FAILED)
    {
      if (errno == ENOSYS)
	puts ("No test, mmap not available.");
      else
	{
	  printf ("mmap failed: %m");
	  result = 1;
	}
    }
  else
    {
      int inner, middle, outer;

      mprotect (adr, size, PROT_NONE);
      mprotect (adr + 2 * nchars, size, PROT_NONE);
      adr += nchars;

      mprotect (dest, size, PROT_NONE);
      mprotect (dest + 2 * nchars, size, PROT_NONE);
      dest += nchars;

      MEMSET (adr, L('T'), nchars);

      /* strlen/wcslen test */
      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
	    {
	      adr[inner] = L('\0');

	      if (STRLEN (&adr[outer]) != (size_t) (inner - outer))
		{
		  printf ("%s flunked for outer = %d, inner = %d\n",
			  STRINGIFY (STRLEN), outer, inner);
		  result = 1;
		}

	      adr[inner] = L('T');
	    }
	}

      /* strnlen/wcsnlen test */
      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
	    {
	      adr[inner] = L('\0');

	      if (STRNLEN (&adr[outer], inner - outer + 1)
		  != (size_t) (inner - outer))
		{
		  printf ("%s flunked for outer = %d, inner = %d\n",
			  STRINGIFY (STRNLEN), outer, inner);
		  result = 1;
		}

	      adr[inner] = L('T');
	    }
	}
      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (inner = MAX (outer, nchars - 64); inner <= nchars; ++inner)
	    {
	      if (STRNLEN (&adr[outer], inner - outer)
		  != (size_t) (inner - outer))
		{
		  printf ("%s flunked bounded for outer = %d, inner = %d\n",
			  STRINGIFY (STRNLEN), outer, inner);
		  result = 1;
		}
	    }
	}

      /* strchr/wcschr test */
      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
	    {
	      for (inner = middle; inner < nchars; ++inner)
		{
		  adr[middle] = L('V');
		  adr[inner] = L('\0');

		  CHAR *cp = STRCHR (&adr[outer], L('V'));

		  if ((inner == middle && cp != NULL)
		      || (inner != middle
			  && (cp - &adr[outer]) != middle - outer))
		    {
		      printf ("%s flunked for outer = %d, middle = %d, "
			      "inner = %d\n",
			      STRINGIFY (STRCHR), outer, middle, inner);
		      result = 1;
		    }

		  adr[inner] = L('T');
		  adr[middle] = L('T');
		}
	    }
	}

      /* Special test.  */
      adr[nchars - 1] = L('\0');
      if (STRCHR (&adr[nchars - 1], L('\n')) != NULL)
	{
	  printf ("%s flunked test of empty string at end of page\n",
		  STRINGIFY (STRCHR));
	  result = 1;
	}

      /* strrchr/wcsrchr test */
      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
	    {
	      for (inner = middle; inner < nchars; ++inner)
		{
		  adr[middle] = L('V');
		  adr[inner] = L('\0');

		  CHAR *cp = STRRCHR (&adr[outer], L('V'));

		  if ((inner == middle && cp != NULL)
		      || (inner != middle
			  && (cp - &adr[outer]) != middle - outer))
		    {
		      printf ("%s flunked for outer = %d, middle = %d, "
			      "inner = %d\n",
			      STRINGIFY (STRRCHR), outer, middle, inner);
		      result = 1;
		    }

		  adr[inner] = L('T');
		  adr[middle] = L('T');
		}
	    }
	}

      /* memchr test */
      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
	    {
	      adr[middle] = L('V');

	      CHAR *cp = MEMCHR (&adr[outer], L('V'), 3 * size);

	      if (cp - &adr[outer] != middle - outer)
		{
		  printf ("%s flunked for outer = %d, middle = %d\n",
			  STRINGIFY (MEMCHR), outer, middle);
		  result = 1;
		}

	      adr[middle] = L('T');
	    }
	}
      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
	{
	  CHAR *cp = MEMCHR (&adr[outer], L('V'), nchars - outer);

	  if (cp != NULL)
	    {
	      printf ("%s flunked for outer = %d\n",
		      STRINGIFY (MEMCHR), outer);
	      result = 1;
	    }
	}

      /* These functions only exist for single-byte characters.  */
#ifndef WCSTEST
      /* rawmemchr test */
      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
	    {
	      adr[middle] = L('V');

	      CHAR *cp = rawmemchr (&adr[outer], L('V'));

	      if (cp - &adr[outer] != middle - outer)
		{
		  printf ("%s flunked for outer = %d, middle = %d\n",
			  STRINGIFY (rawmemchr), outer, middle);
		  result = 1;
		}

	      adr[middle] = L('T');
	    }
	}

      /* memrchr test */
      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
	    {
	      adr[middle] = L('V');

	      CHAR *cp = memrchr (&adr[outer], L('V'), nchars - outer);

	      if (cp - &adr[outer] != middle - outer)
		{
		  printf ("%s flunked for outer = %d, middle = %d\n",
			  STRINGIFY (memrchr), outer, middle);
		  result = 1;
		}

	      adr[middle] = L('T');
	    }
	}
      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
	{
	  CHAR *cp = memrchr (&adr[outer], L('V'), nchars - outer);

	  if (cp != NULL)
	    {
	      printf ("%s flunked for outer = %d\n",
		      STRINGIFY (memrchr), outer);
	      result = 1;
	    }
	}
#endif

      /* strcpy/wcscpy test */
      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
	    {
	      adr[inner] = L('\0');

	      if (STRCPY (dest, &adr[outer]) != dest
		  || STRLEN (dest) != (size_t) (inner - outer))
		{
		  printf ("%s flunked for outer = %d, inner = %d\n",
			  STRINGIFY (STRCPY), outer, inner);
		  result = 1;
		}

	      adr[inner] = L('T');
	    }
	}

      /* strcmp/wcscmp tests */
      for (outer = 1; outer < 32; ++outer)
	for (middle = 0; middle < 16; ++middle)
	  {
	    MEMSET (adr + middle, L('T'), 256);
	    adr[256] = L('\0');
	    MEMSET (dest + nchars - outer, L('T'), outer - 1);
	    dest[nchars - 1] = L('\0');

	    if (STRCMP (adr + middle, dest + nchars - outer) <= 0)
	      {
		printf ("%s 1 flunked for outer = %d, middle = %d\n",
			STRINGIFY (STRCMP), outer, middle);
		result = 1;
	      }

	    if (STRCMP (dest + nchars - outer, adr + middle) >= 0)
	      {
		printf ("%s 2 flunked for outer = %d, middle = %d\n",
			STRINGIFY (STRCMP), outer, middle);
		result = 1;
	      }
	  }

      /* strncmp/wcsncmp tests */
      for (outer = 1; outer < 32; ++outer)
	for (middle = 0; middle < 16; ++middle)
	  {
	    MEMSET (adr + middle, L('T'), 256);
	    adr[256] = L('\0');
	    MEMSET (dest + nchars - outer, L('T'), outer - 1);
	    dest[nchars - 1] = L('U');

	    for (inner = 0; inner < outer; ++inner)
	      {
		if (STRNCMP (adr + middle, dest + nchars - outer, inner) != 0)
		  {
		    printf ("%s 1 flunked for outer = %d, middle = %d, "
			    "inner = %d\n",
			    STRINGIFY (STRNCMP), outer, middle, inner);
		    result = 1;
		  }

		if (STRNCMP (dest + nchars - outer, adr + middle, inner) != 0)
		  {
		    printf ("%s 2 flunked for outer = %d, middle = %d, "
			    "inner = %d\n",
			    STRINGIFY (STRNCMP), outer, middle, inner);
		    result = 1;
		  }
	      }

	    if (STRNCMP (adr + middle, dest + nchars - outer, outer) >= 0)
	      {
		printf ("%s 1 flunked for outer = %d, middle = %d, full\n",
			STRINGIFY (STRNCMP), outer, middle);
		result = 1;
	      }

	    if (STRNCMP (dest + nchars - outer, adr + middle, outer) <= 0)
	      {
		printf ("%s 2 flunked for outer = %d, middle = %d, full\n",
			STRINGIFY (STRNCMP), outer, middle);
		result = 1;
	      }
	  }

      /* strncpy/wcsncpy tests */
      adr[nchars - 1] = L('T');
      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
	{
	  size_t len;

	  for (len = 0; len < nchars - outer; ++len)
	    {
	      if (STRNCPY (dest, &adr[outer], len) != dest
		  || MEMCMP (dest, &adr[outer], len) != 0)
		{
		  printf ("outer %s flunked for outer = %d, len = %Zd\n",
			  STRINGIFY (STRNCPY), outer, len);
		  result = 1;
		}
	    }
	}
      adr[nchars - 1] = L('\0');

      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
	    {
	      size_t len;

	      adr[inner] = L('\0');

	      for (len = 0; len < nchars - outer + 64; ++len)
		{
		  if (STRNCPY (dest, &adr[outer], len) != dest
		      || MEMCMP (dest, &adr[outer],
				 MIN (inner - outer, len)) != 0
		      || (inner - outer < len
			  && STRLEN (dest) != (inner - outer)))
		    {
		      printf ("%s flunked for outer = %d, inner = %d, "
			      "len = %Zd\n",
			      STRINGIFY (STRNCPY), outer, inner, len);
		      result = 1;
		    }
		  if (STRNCPY (dest + 1, &adr[outer], len) != dest + 1
		      || MEMCMP (dest + 1, &adr[outer],
				 MIN (inner - outer, len)) != 0
		      || (inner - outer < len
			  && STRLEN (dest + 1) != (inner - outer)))
		    {
		      printf ("%s+1 flunked for outer = %d, inner = %d, "
			      "len = %Zd\n",
			      STRINGIFY (STRNCPY), outer, inner, len);
		      result = 1;
		    }
		}

	      adr[inner] = L('T');
	    }
	}

      /* stpcpy/wcpcpy test */
      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (inner = MAX (outer, nchars - 64); inner < nchars; ++inner)
	    {
	      adr[inner] = L('\0');

	      if ((STPCPY (dest, &adr[outer]) - dest) != inner - outer)
		{
		  printf ("%s flunked for outer = %d, inner = %d\n",
			  STRINGIFY (STPCPY), outer, inner);
		  result = 1;
		}

	      adr[inner] = L('T');
	    }
	}

      /* stpncpy/wcpncpy test */
      adr[nchars - 1] = L('T');
      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
	{
	  size_t len;

	  for (len = 0; len < nchars - outer; ++len)
	    {
	      if (STPNCPY (dest, &adr[outer], len) != dest + len
		  || MEMCMP (dest, &adr[outer], len) != 0)
		{
		  printf ("outer %s flunked for outer = %d, len = %Zd\n",
			  STRINGIFY (STPNCPY), outer, len);
		  result = 1;
		}
	    }
	}
      adr[nchars - 1] = L('\0');

      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	{
	  for (middle = MAX (outer, nchars - 64); middle < nchars; ++middle)
	    {
	      adr[middle] = L('\0');

	      for (inner = 0; inner < nchars - outer; ++ inner)
		{
		  if ((STPNCPY (dest, &adr[outer], inner) - dest)
		      != MIN (inner, middle - outer))
		    {
		      printf ("%s flunked for outer = %d, middle = %d, "
			      "inner = %d\n",
			      STRINGIFY (STPNCPY), outer, middle, inner);
		      result = 1;
		    }
		}

	      adr[middle] = L('T');
	    }
	}

      /* memcpy/wmemcpy test */
      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
	for (inner = 0; inner < nchars - outer; ++inner)
	  if (MEMCPY (dest, &adr[outer], inner) !=  dest)
	    {
	      printf ("%s flunked for outer = %d, inner = %d\n",
		      STRINGIFY (MEMCPY), outer, inner);
	      result = 1;
	    }

      /* mempcpy/wmempcpy test */
      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
	for (inner = 0; inner < nchars - outer; ++inner)
	  if (MEMPCPY (dest, &adr[outer], inner) !=  dest + inner)
	    {
	      printf ("%s flunked for outer = %d, inner = %d\n",
		      STRINGIFY (MEMPCPY), outer, inner);
	      result = 1;
	    }

      /* This function only exists for single-byte characters.  */
#ifndef WCSTEST
      /* memccpy test */
      memset (adr, '\0', nchars);
      for (outer = nchars; outer >= MAX (0, nchars - 128); --outer)
	for (inner = 0; inner < nchars - outer; ++inner)
	  if (memccpy (dest, &adr[outer], L('\1'), inner) != NULL)
	    {
	      printf ("memccpy flunked full copy for outer = %d, inner = %d\n",
		      outer, inner);
	      result = 1;
	    }
      for (outer = nchars - 1; outer >= MAX (0, nchars - 128); --outer)
	for (middle = 0; middle < nchars - outer; ++middle)
	  {
	    memset (dest, L('\2'), middle + 1);
	    for (inner = 0; inner < middle; ++inner)
	      {
		adr[outer + inner] = L('\1');

		if (memccpy (dest, &adr[outer], '\1', middle + 128)
		    !=  dest + inner + 1)
		  {
		    printf ("\
memccpy flunked partial copy for outer = %d, middle = %d, inner = %d\n",
			    outer, middle, inner);
		    result = 1;
		  }
		else if (dest[inner + 1] != L('\2'))
		  {
		    printf ("\
memccpy copied too much for outer = %d, middle = %d, inner = %d\n",
			    outer, middle, inner);
		    result = 1;
		  }
		adr[outer + inner] = L('\0');
	      }
Beispiel #16
0
/* function: searchstr
 * Suche Teilstring substr im Gesamtstring data von vorn nach hinten.
 * Search substring substr in whole string data.
 * If substr is not found 0 is returned. If substr is contained more than
 * once the occurrence with the lowest address is reported.
 *
 * Used algorithmus:
 * Simplified Boyer-Moore without Bad-Character-Heuristic.
 * Like KMP but comparing starts from end of substr (substr[substrsize-1]).
 *
 * Worst case:
 * O(size)
 *
 * Special case (data == 0 || substrsize == 0):
 * The value 0 is returned if length of substr or data is 0.
 *
 */
const uint8_t* searchstr(size_t size, const uint8_t data[size], uint8_t substrsize, const uint8_t substr[substrsize])
{
   // nr of positions substr is to shift right
   // array is indexed by nr of matched positions starting from end
   uint8_t shift[substrsize];
   const uint8_t* pos;

   if (substrsize < 2) {
      return substrsize ? memchr(data, substr[0], size) : 0;
   }

   if (substrsize > size) {
      return 0;
   }

   {
      pos = memrchr(substr, substr[substrsize-1], substrsize-1);
      int lastoff = (pos ? 1 + (int) (pos - substr) : 0);

      shift[0] = 1;
      shift[1] = (uint8_t) (substrsize - lastoff);

      // copied from rsearchstr (KMP index helper array)
      uint8_t sidx[substrsize];
      sidx[substrsize-1] = substrsize;    // 0 length match
      for (int i = substrsize-1, i2 = substrsize; i; ) {
         while (i2 < substrsize && substr[i] != substr[i2]) {
            i2 = sidx[i2];
         }
         sidx[--i] = (uint8_t) (--i2);
      }

      for (int nrmatched = 2; nrmatched < substrsize; ++nrmatched) {
         if (lastoff >= nrmatched) {
            int dpos = lastoff-nrmatched+1;
            int spos = substrsize-nrmatched+1;
            while (dpos > 0) {
               --dpos;
               --spos;
               if (substr[spos] != substr[dpos]) {
                  spos = sidx[spos];
                  while (spos < substrsize && substr[spos] != substr[dpos]) {
                     spos = sidx[spos];
                  }
               }
               if (nrmatched == substrsize-spos) break;
            }
            lastoff = (spos < substrsize ? dpos+(substrsize-spos) : 0);
         }
         shift[nrmatched] = (uint8_t) (substrsize - lastoff);
      }
   }

   const int substrsize1 = substrsize-1;

   int eoff = 0;
   int skip = 0;

   const uint8_t* const
   endpos = data + size - substrsize1;
   pos = data;

   do {
      int off = substrsize1;
      while (substr[off] == pos[off]) {
         if (off == eoff) {
            if (off <= skip) {
               return pos;
            }
            off -= skip; // make worst case O(size) instead O(size*substrlen)
            eoff = 0;
         }
         --off;
      }
      int nrmatched = substrsize1 - off;
      int pincr = shift[nrmatched];
      skip = nrmatched;
      pos += pincr;
      eoff = substrsize - pincr;
   } while (pos < endpos);

   return 0;
}
Beispiel #17
0
/**
 * this the parse_url() implements in php-src.
 * more information see:http://www.php.net
 */
url_t *_url_parse(char const *str, int length){
	char port_buf[6];
	url_t *ret = m_new(url_t, 1);
	char const *s, *e, *p, *pp, *ue;

	s = str;
	ue = s + length;

	/* parse scheme */
	if ((e = memchr(s, ':', length)) && (e - s)) {
		/* validate scheme */
		p = s;
		while (p < e) {
			/* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */
			if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') {
				if (e + 1 < ue) {
					goto parse_port;
				} else {
					goto just_path;
				}
			}
			p++;
		}

		if (*(e + 1) == '\0') { /* only scheme is available */
			ret->scheme = strndup(s, (e - s));
			replace_controlchars(ret->scheme, (e - s));
			goto end;
		}

		/*
		 * certain schemas like mailto: and zlib: may not have any / after them
		 * this check ensures we support those.
		 */
		if (*(e+1) != '/') {
			/* check if the data we get is a port this allows us to
			 * correctly parse things like a.com:80
			 */
			p = e + 1;
			while (isdigit(*p)) {
				p++;
			}

			if ((*p == '\0' || *p == '/') && (p - e) < 7) {
				goto parse_port;
			}

			ret->scheme = strndup(s, (e-s));
			replace_controlchars(ret->scheme, (e - s));

			length -= ++e - s;
			s = e;
			goto just_path;
		} else {
			ret->scheme = strndup(s, (e-s));
			replace_controlchars(ret->scheme, (e - s));

			if (*(e+2) == '/') {
				s = e + 3;
				if (!strncasecmp("file", ret->scheme, sizeof("file"))) {
					if (*(e + 3) == '/') {
						/* support windows drive letters as in:
						   file:///c:/somedir/file.txt
						*/
						if (*(e + 5) == ':') {
							s = e + 4;
						}
						goto nohost;
					}
				}
			} else {
				if (!strncasecmp("file", ret->scheme, sizeof("file"))) {
					s = e + 1;
					goto nohost;
				} else {
					length -= ++e - s;
					s = e;
					goto just_path;
				}
			}
		}
	} else if (e) { /* no scheme; starts with colon: look for port */
		parse_port:
		p = e + 1;
		pp = p;

		while (pp-p < 6 && isdigit(*pp)) {
			pp++;
		}

		if (pp - p > 0 && pp - p < 6 && (*pp == '/' || *pp == '\0')) {
			long port;
			memcpy(port_buf, p, (pp - p));
			port_buf[pp - p] = '\0';
			port = strtol(port_buf, NULL, 10);
			if (port > 0 && port <= 65535) {
				ret->port = (unsigned short) port;
			} else {
				free(ret->scheme);
				free(ret);
				return NULL;
			}
		} else if (p == pp && *pp == '\0') {
			free(ret->scheme);
			free(ret);
			return NULL;
		} else {
			goto just_path;
		}
	} else {
		just_path:
		ue = s + length;
		goto nohost;
	}

	e = ue;

	if (!(p = memchr(s, '/', (ue - s)))) {
		char *query, *fragment;

		query = memchr(s, '?', (ue - s));
		fragment = memchr(s, '#', (ue - s));

		if (query && fragment) {
			if (query > fragment) {
				p = e = fragment;
			} else {
				p = e = query;
			}
		} else if (query) {
			p = e = query;
		} else if (fragment) {
			p = e = fragment;
		}
	} else {
		e = p;
	}

	/* check for login and password */
	if ((p = memrchr(s, '@', (e-s)))) {
		if ((pp = memchr(s, ':', (p-s)))) {
			if ((pp-s) > 0) {
				ret->user = strndup(s, (pp-s));
				replace_controlchars(ret->user, (pp - s));
			}

			pp++;
			if (p-pp > 0) {
				ret->pass = strndup(pp, (p-pp));
				replace_controlchars(ret->pass, (p-pp));
			}
		} else {
			ret->user = strndup(s, (p-s));
			replace_controlchars(ret->user, (p-s));
		}

		s = p + 1;
	}

	/* check for port */
	if (*s == '[' && *(e-1) == ']') {
		/* Short circuit portscan,
		   we're dealing with an
		   IPv6 embedded address */
		p = s;
	} else {
		/* memrchr is a GNU specific extension
		   Emulate for wide compatability */
		for(p = e; *p != ':' && p >= s; p--);
	}

	if (p >= s && *p == ':') {
		if (!ret->port) {
			p++;
			if (e-p > 5) { /* port cannot be longer then 5 characters */
				free(ret->scheme);
				free(ret->user);
				free(ret->pass);
				free(ret);
				return NULL;
			} else if (e - p > 0) {
				long port;
				memcpy(port_buf, p, (e - p));
				port_buf[e - p] = '\0';
				port = strtol(port_buf, NULL, 10);
				if (port > 0 && port <= 65535) {
					ret->port = (unsigned short)port;
				} else {
					free(ret->scheme);
					free(ret->user);
					free(ret->pass);
					free(ret);
					return NULL;
				}
			}
			p--;
		}
	} else {
		p = e;
	}

	/* check if we have a valid host, if we don't reject the string as url */
	if ((p-s) < 1) {
		free(ret->scheme);
		free(ret->user);
		free(ret->pass);
		free(ret);
		return NULL;
	}

	ret->host = strndup(s, (p-s));
	replace_controlchars(ret->host, (p - s));

	if (e == ue) {
		return ret;
	}

	s = e;

	nohost:

	if ((p = memchr(s, '?', (ue - s)))) {
		pp = strchr(s, '#');

		if (pp && pp < p) {
			if (pp - s) {
				ret->path = strndup(s, (pp-s));
				replace_controlchars(ret->path, (pp - s));
			}
			p = pp;
			goto label_parse;
		}

		if (p - s) {
			ret->path = strndup(s, (p-s));
			replace_controlchars(ret->path, (p - s));
		}

		if (pp) {
			if (pp - ++p) {
				ret->query = strndup(p, (pp-p));
				replace_controlchars(ret->query, (pp - p));
			}
			p = pp;
			goto label_parse;
		} else if (++p - ue) {
			ret->query = strndup(p, (ue-p));
			replace_controlchars(ret->query, (ue - p));
		}
	} else if ((p = memchr(s, '#', (ue - s)))) {
		if (p - s) {
			ret->path = strndup(s, (p-s));
			replace_controlchars(ret->path, (p - s));
		}

		label_parse:
		p++;

		if (ue - p) {
			ret->fragment = strndup(p, (ue-p));
			replace_controlchars(ret->fragment, (ue - p));
		}
	} else {
		ret->path = strndup(s, (ue-s));
		replace_controlchars(ret->path, (ue - s));
	}
end:
	return ret;
}
Beispiel #18
0
const void* memrchr(const void* ptr, int ch, std::size_t count) {
    return (const void*)memrchr((void*)ptr, ch, count);
}
static gboolean
convert_var_to_tmpfiles_d_recurse (GOutputStream *tmpfiles_out,
                                   int            dfd,
                                   GString       *prefix,
                                   GCancellable  *cancellable,
                                   GError       **error)
{
    gboolean ret = FALSE;
    g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
    gsize bytes_written;

    if (!glnx_dirfd_iterator_init_at (dfd, prefix->str + 1, TRUE, &dfd_iter, error))
        goto out;

    while (TRUE)
    {
        struct dirent *dent = NULL;
        GString *tmpfiles_d_buf;
        gs_free char *tmpfiles_d_line = NULL;
        char filetype_c;
        gs_free char *relpath = NULL;

        if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
            goto out;

        if (!dent)
            break;

        switch (dent->d_type)
        {
        case DT_DIR:
            filetype_c = 'd';
            break;
        case DT_LNK:
            filetype_c = 'L';
            break;
        default:
            g_print ("Ignoring non-directory/non-symlink '%s'\n",
                     dent->d_name);
            continue;
        }

        tmpfiles_d_buf = g_string_new ("");
        g_string_append_c (tmpfiles_d_buf, filetype_c);
        g_string_append_c (tmpfiles_d_buf, ' ');
        g_string_append (tmpfiles_d_buf, prefix->str);
        g_string_append_c (tmpfiles_d_buf, '/');
        g_string_append (tmpfiles_d_buf, dent->d_name);

        if (filetype_c == 'd')
        {
            struct stat stbuf;

            if (TEMP_FAILURE_RETRY (fstatat (dfd_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW)) != 0)
            {
                glnx_set_error_from_errno (error);
                goto out;
            }

            g_string_append_printf (tmpfiles_d_buf, " 0%02o", stbuf.st_mode & ~S_IFMT);
            g_string_append_printf (tmpfiles_d_buf, " %d %d - -", stbuf.st_uid, stbuf.st_gid);

            /* Push prefix */
            g_string_append_c (prefix, '/');
            g_string_append (prefix, dent->d_name);

            if (!convert_var_to_tmpfiles_d_recurse (tmpfiles_out, dfd, prefix,
                                                    cancellable, error))
                goto out;

            /* Pop prefix */
            {
                char *r = memrchr (prefix->str, '/', prefix->len);
                g_assert (r != NULL);
                g_string_truncate (prefix, r - prefix->str);
            }
        }
        else
        {
            g_autofree char *link = glnx_readlinkat_malloc (dfd_iter.fd, dent->d_name, cancellable, error);
            if (!link)
                goto out;
            g_string_append (tmpfiles_d_buf, " - - - - ");
            g_string_append (tmpfiles_d_buf, link);
        }

        g_string_append_c (tmpfiles_d_buf, '\n');

        tmpfiles_d_line = g_string_free (tmpfiles_d_buf, FALSE);

        if (!g_output_stream_write_all (tmpfiles_out, tmpfiles_d_line,
                                        strlen (tmpfiles_d_line), &bytes_written,
                                        cancellable, error))
            goto out;
    }

    ret = TRUE;
out:
    return ret;
}
Beispiel #20
0
static int m3u_format_parser(struct list_mgt *mgt,ByteIOContext *s)
{
    unsigned  char line[1024];
    int ret;
    unsigned char *p;
    int getnum=0;
    struct list_item tmpitem;
    char prefix[1024]="";
    char prefixex[1024]="";
    int prefix_len=0,prefixex_len=0;
    double start_time=mgt->full_time;
    char *oprefix=mgt->location!=NULL?mgt->location:mgt->filename;
    if(NULL!=mgt->prefix) {
        av_free(mgt->prefix);
        mgt->prefix = NULL;
    }
    if(oprefix) {
        mgt->prefix = strdup(oprefix);

        char *tail,*tailex,*extoptions;
        extoptions=strchr(oprefix,'?');/*ext options is start with ? ,we don't need in nested*/
        if(is_NET_URL(oprefix)) {
            tail=strchr(oprefix+10,'/');/*skip Http:// and shttp:,and to first '/'*/
            if(!extoptions)// no ?
                tailex=strrchr(oprefix+10,'/');/*skip Http:// and shttp:,start to  last '/'*/
            else
                tailex=memrchr(oprefix+10,'/',extoptions-oprefix-10);/*skip Http:// and shttp:,start to  last '/',between http-->? */
        } else {
            tail=strchr(oprefix,'/'); /*first '/'*/
            if(!extoptions)//no ?
                tailex=strrchr(oprefix,'/'); /*to last '/' */
            else
                tailex=memrchr(oprefix+10,'/',extoptions-oprefix-10);/*skip Http:// and shttp:,start to  last '/',between http-->? */
        }

        if(tail!=NULL) {
            prefix_len=tail-oprefix+1;/*left '/'..*/
            memcpy(prefix,oprefix,prefix_len);
            prefix[prefix_len]='\0';
        }

        if(tailex!=NULL) {
            prefixex_len=tailex-oprefix+1;/*left '/'..*/
            memcpy(prefixex,oprefix,prefixex_len);
            prefixex[prefixex_len]='\0';
        }
    }
    memset(&tmpitem,0,sizeof(tmpitem));
    tmpitem.seq=-1;
    av_log(NULL, AV_LOG_INFO, "m3u_format_parser get prefix=%s\n",prefix);
    av_log(NULL, AV_LOG_INFO, "m3u_format_parser get prefixex=%s\n",prefixex);
#if 0
    if(mgt->n_variants>0) {
        free_variant_list(mgt);
    }
#endif
    while(m3u_format_get_line(s,line,1024)>=0)
    {
        if (url_interrupt_cb()) {
            return -1;
        }
        tmpitem.ktype = KEY_NONE;
        ret = m3u_parser_line(mgt,line,&tmpitem);
        if(ret>0)
        {
            struct list_item*item;
            int need_prefix=0;
            int size_file=tmpitem.file?(strlen(tmpitem.file)+32):4;
            tmpitem.start_time=start_time;

            if(tmpitem.file &&
                    (is_NET_URL(prefix)) && /*net protocal*/
                    !(is_NET_URL(tmpitem.file)))/*if item is not net protocal*/
            {   /*if m3u is http,item is not http,add prefix*/
                need_prefix=1;
                size_file+=prefixex_len;
            }
            item=av_malloc(sizeof(struct list_item)+size_file);
            if(!item)
                return AVERROR(ENOMEM);
            memcpy(item,&tmpitem,sizeof(tmpitem));
            item->file=NULL;
            if(tmpitem.file)
            {
                item->file=&item[1];
                if(need_prefix) {
                    if(tmpitem.file[0]=='/') { /*has '/',not need the dir */
                        strcpy(item->file,prefix);
                        strcpy(item->file+prefix_len,tmpitem.file+1);/*don't copy two '/',we have left before*/
                    } else { /*no '/', some I save the full path frefix*/
                        if(!strncmp(prefixex,"shttps://",9)) {
                            strcpy(item->file,"http");
                            strcpy(item->file+4,prefixex+6);
                            strcpy(item->file+4+prefixex_len -6,tmpitem.file);
                        } else {
                            strcpy(item->file,prefixex);
                            strcpy(item->file+prefixex_len,tmpitem.file);
                        }

                    }
                }
                else {
                    strcpy(item->file,tmpitem.file);
                }
            }

            if(mgt->flags&KEY_FLAG&&NULL!= mgt->key_tmp&&mgt->key_tmp->is_have_key_file>0) {
                item->key_ctx = av_mallocz(sizeof(struct AES128KeyContext));
                if(!item->key_ctx) {
                    ret = AVERROR(ENOMEM);
                    break;
                }
                memcpy(item->key_ctx->key,mgt->key_tmp->key,sizeof(item->key_ctx->key));
                if(mgt->has_iv>0) {
                    memcpy(item->key_ctx->iv,mgt->key_tmp->iv,sizeof(item->key_ctx->iv));
                } else { //from applehttp.c
                    av_log(NULL,AV_LOG_INFO,"Current item seq number:%d\n",item->seq);
                    AV_WB32(item->key_ctx->iv + 12, item->seq);
                }


                item->ktype = mgt->key_tmp->key_type;

            }
            if(mgt->next_seq>=0 && item->seq<0) {
                item->seq=mgt->next_seq;
                mgt->next_seq++;
            }

            if(!(tmpitem.flags&INVALID_ITEM_FLAG)) {

                ret =list_test_and_add_item(mgt,item);
                if(ret==0) {
                    getnum++;
                    start_time+=item->duration;
                } else {
                    av_free(item);
                    mgt->next_seq--;
                }

            }

            if((item->flags &ENDLIST_FLAG) && (item->flags < (1<<12)))
            {
                mgt->have_list_end=1;
                break;
            }
            memset(&tmpitem,0,sizeof(tmpitem));
            tmpitem.seq=-1;
        }
        else if(ret <0) {
            if(ret ==-(TRICK_LOGIC_BASE+0)&&(mgt->flags&KEY_FLAG)&&NULL!= mgt->key_tmp&&0==mgt->key_tmp->is_have_key_file) { //get key from server
                URLContext *uc;
                if (ffurl_open(&uc, mgt->key_tmp->key_from, AVIO_FLAG_READ) == 0) {
                    if (ffurl_read_complete(uc, mgt->key_tmp->key, sizeof(mgt->key_tmp->key))
                            != sizeof(mgt->key_tmp->key)) {
                        av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
                               mgt->key_tmp->key_from);

                    }
                    av_log(NULL,AV_LOG_INFO,"Just get aes key file from server\n");
                    mgt->key_tmp->is_have_key_file = 1;

                    ffurl_close(uc);
                } else {
                    av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
                           mgt->key_tmp->key_from);
                }
                memset(&tmpitem,0,sizeof(tmpitem));
                continue;
            }

            if(ret ==-(TRICK_LOGIC_BASE+1)||ret ==-(TRICK_LOGIC_BASE+2)) {
                memset(&tmpitem,0,sizeof(tmpitem));
                continue;
            }
            break;
        }
        else {
            if(tmpitem.flags&ALLOW_CACHE_FLAG)
                mgt->flags|=ALLOW_CACHE_FLAG;
            if(tmpitem.flags&INVALID_ITEM_FLAG) {
                av_log(NULL,AV_LOG_INFO,"just a trick,drop this item,seq number:%d\n",tmpitem.seq);
                continue;
            }
        }

    }
    if(mgt->key_tmp) {
        av_free(mgt->key_tmp);
        mgt->key_tmp = NULL;
    }

    mgt->file_size=AVERROR_STREAM_SIZE_NOTVALID;
    mgt->full_time=start_time;
    mgt->last_load_time = av_gettime();
    av_log(NULL, AV_LOG_INFO, "m3u_format_parser end num =%d,fulltime=%.4lf\n",getnum,start_time);
    return getnum;
}
Beispiel #21
0
void bsodFatal(const char *component)
{
	/* show no more than one bsod while shutting down/crashing */
	if (bsodhandled)
		return;
	bsodhandled = true;

	if (!component)
		component = "Enigma2";

	/* Retrieve current ringbuffer state */
	const char* logp1;
	unsigned int logs1;
	const char* logp2;
	unsigned int logs2;
	retrieveLogBuffer(&logp1, &logs1, &logp2, &logs2);

	FILE *f;
	std::string crashlog_name;
	std::ostringstream os;
	time_t t = time(0);
	struct tm tm;
	char tm_str[32];
	localtime_r(&t, &tm);
	strftime(tm_str, sizeof(tm_str), "%Y-%m-%d_%H-%M-%S", &tm);
	os << getConfigString("config.crash.debug_path", "/home/root/logs/");
	os << "enigma2_crash_";
	os << tm_str;
	os << ".log";
	crashlog_name = os.str();
	f = fopen(crashlog_name.c_str(), "wb");

	if (f == NULL)
	{
		/* No hardisk. If there is a crash log in /home/root, leave it
		 * alone because we may be in a crash loop and writing this file
		 * all night long may damage the flash. Also, usually the first
		 * crash log is the most interesting one. */
		crashlog_name = "/home/root/logs/enigma2_crash.log";
		if ((access(crashlog_name.c_str(), F_OK) == 0) ||
		    ((f = fopen(crashlog_name.c_str(), "wb")) == NULL))
		{
			/* Re-write the same file in /tmp/ because it's expected to
			 * be in RAM. So the first crash log will end up in /home
			 * and the last in /tmp */
			crashlog_name = "/tmp/enigma2_crash.log";
			f = fopen(crashlog_name.c_str(), "wb");
		}
	}

	if (f)
	{
		time_t t = time(0);
		struct tm tm;
		char tm_str[32];

		localtime_r(&t, &tm);
		strftime(tm_str, sizeof(tm_str), "%a %b %_d %T %Y", &tm);

		fprintf(f,
					"OpenBh Enigma2 Crashlog\n\n"
					"Crashdate = %s\n\n"
					"%s\n"
					"Compiled = %s\n"
					"Skin = %s\n"
					"Component = %s\n\n"
					"Kernel CMDline = %s\n"
					"Nim Sockets = %s\n",
					tm_str,
					stringFromFile("/etc/image-version").c_str(),
					__DATE__,
					getConfigString("config.skin.primary_skin", "Default Skin").c_str(),
					component,
					stringFromFile("/proc/cmdline").c_str(),
					stringFromFile("/proc/bus/nim_sockets").c_str()
				);

		/* dump the log ringbuffer */
		fprintf(f, "\n\n");
		if (logp1)
			fwrite(logp1, 1, logs1, f);
		if (logp2)
			fwrite(logp2, 1, logs2, f);

		fclose(f);
	}

	ePtr<gMainDC> my_dc;
	gMainDC::getInstance(my_dc);

	gPainter p(my_dc);
	p.resetOffset();
	p.resetClip(eRect(ePoint(0, 0), my_dc->size()));
	p.setBackgroundColor(gRGB(0x010000));
	p.setForegroundColor(gRGB(0xFFFFFF));

	int hd =  my_dc->size().width() == 1920;
	ePtr<gFont> font = new gFont("Regular", hd ? 30 : 20);
	p.setFont(font);
	p.clear();

	eRect usable_area = eRect(hd ? 30 : 100, hd ? 30 : 70, my_dc->size().width() - (hd ? 60 : 150), hd ? 150 : 100);

	os.str("");
	os.clear();
	os << "We are really sorry. Your receiver encountered "
		"a software problem, and needs to be restarted.\n"
		"Please upload the crash log " << crashlog_name << " to www.vuplus-community.net\n"
		"Your STB will restart in 10 seconds!\n"
		"Component: " << component;

	p.renderText(usable_area, os.str().c_str(), gPainter::RT_WRAP|gPainter::RT_HALIGN_LEFT);

	std::string logtail;
	int lines = 20;
	
	if (logp2)
	{
		unsigned int size = logs2;
		while (size) {
			const char* r = (const char*)memrchr(logp2, '\n', size);
			if (r) {
				size = r - logp2;
				--lines;
				if (!lines) {
					logtail = std::string(r, logs2 - size);
					break;
				} 
			}
			else {
				logtail = std::string(logp2, logs2);
				break;
			}
		}
	}

	if (lines && logp1)
	{
		unsigned int size = logs1;
		while (size) {
			const char* r = (const char*)memrchr(logp1, '\n', size);
			if (r) {
				--lines;
				size = r - logp1;
				if (!lines) {
					logtail += std::string(r, logs1 - size);
					break;
				} 
			}
			else {
				logtail += std::string(logp1, logs1);
				break;
			}
		}
	}

	if (!logtail.empty())
	{
		font = new gFont("Regular", hd ? 21 : 14);
		p.setFont(font);
		usable_area = eRect(hd ? 30 : 100, hd ? 180 : 170, my_dc->size().width() - (hd ? 60 : 180), my_dc->size().height() - (hd ? 30 : 20));
		p.renderText(usable_area, logtail, gPainter::RT_HALIGN_LEFT);
	}
	sleep(10);

	/*
	 * When 'component' is NULL, we are called because of a python exception.
	 * In that case, we'd prefer to to a clean shutdown of the C++ objects,
	 * and this should be safe, because the crash did not occur in the
	 * C++ part.
	 * However, when we got here for some other reason, a segfault probably,
	 * we prefer to stop immediately instead of performing a clean shutdown.
	 * We'd risk destroying things with every additional instruction we're
	 * executing here.
	 */
	if (component) raise(SIGKILL);
}
Beispiel #22
0
void
email_login_pop(Email *e, Ecore_Con_Event_Server_Data *ev)
{
    char *buf;
    size_t size;

    switch (e->state)
    {
    case EMAIL_STATE_SSL:
        if (!email_op_ok(ev->data, ev->size))
        {
            ERR("Could not create secure connection!");
            ecore_con_server_del(ev->server);
            return;
        }
        ecore_con_ssl_server_upgrade(e->svr, ECORE_CON_USE_MIXED);
        ecore_con_ssl_server_verify_basic(e->svr);
        e->flags = ECORE_CON_USE_MIXED;
        return;
    case EMAIL_STATE_INIT:
        if (!email_op_ok(ev->data, ev->size))
        {
            ERR("Not a POP3 server!");
            ecore_con_server_del(ev->server);
            return;
        }
        if (ev->size > 20)
        {
            const unsigned char *end;

            end = memrchr(ev->data + 3, '>', ev->size - 3);
            if (end)
            {
                const unsigned char *start;

                start = memrchr(ev->data + 3, '<', end - (unsigned char*)ev->data);
                if (start)
                {
                    e->features.pop_features.apop = EINA_TRUE;
                    e->features.pop_features.apop_str = eina_binbuf_new();
                    eina_binbuf_append_length(e->features.pop_features.apop_str, start, end - start + 1);
                }
            }
        }
        if (e->secure && (!e->flags))
        {
            email_write(e, "STLS\r\n", sizeof("STLS\r\n") - 1);
            e->state++;
            return;
        }
        e->state = EMAIL_STATE_USER;
        ev = NULL;
    case EMAIL_STATE_USER:
        if (!ev)
        {
            unsigned char digest[16];
            char md5buf[33];

            if (!e->features.pop_features.apop)
            {
                INF("Beginning AUTH PLAIN");
                size = sizeof(char) * (sizeof("USER ") - 1 + sizeof("\r\n") - 1 + strlen(e->username)) + 1;
                buf = alloca(size);
                snprintf(buf, size, "USER %s\r\n", e->username);
                email_write(e, buf, size - 1);
                return;
            }
            INF("Beginning AUTH APOP");
            e->state++;
            eina_binbuf_append_length(e->features.pop_features.apop_str, (unsigned char*)e->password, strlen(e->password));

            md5_buffer((char*)eina_binbuf_string_get(e->features.pop_features.apop_str), eina_binbuf_length_get(e->features.pop_features.apop_str), digest);
            email_md5_digest_to_str(digest, md5buf);
            size = sizeof(char) * (sizeof("APOP ") - 1 + sizeof("\r\n") - 1 + strlen(e->username)) + sizeof(md5buf);
            buf = alloca(size);
            snprintf(buf, size, "APOP %s %s\r\n", e->username, md5buf);
            email_write(e, buf, size - 1);
            return;
        }
        if (!email_op_ok(ev->data, ev->size))
        {
            ERR("Username invalid!");
            ecore_con_server_del(e->svr);
            return;
        }
        size = sizeof(char) * (sizeof("PASS ") - 1 + sizeof("\r\n") - 1 + strlen(e->password)) + 1;
        buf = alloca(size);
        snprintf(buf, size, "PASS %s\r\n", e->password);
        DBG("Sending password");
        ecore_con_server_send(e->svr, buf, size - 1);
        e->state++;
        return;
    case EMAIL_STATE_PASS:
        if (!email_op_ok(ev->data, ev->size))
        {
            ERR("Credentials invalid!");
            ecore_con_server_del(e->svr);
            return;
        }
        INF("Logged in successfully!");
        e->state++;
        ecore_event_add(EMAIL_EVENT_CONNECTED, e, (Ecore_End_Cb)email_fake_free, NULL);
    default:
        break;
    }
}
Beispiel #23
0
int main(int argc, char **argv) {
	//argument variables
	const char *exe = NULL;
	int perclimit = 0;
	int exe_ok = 0;
	int pid_ok = 0;
	int limit_ok = 0;
	pid_t pid = 0;
	int include_children = 0;

	//get program name
	char *p = (char*)memrchr(argv[0], (unsigned int)'/', strlen(argv[0]));
	program_name = p==NULL ? argv[0] : (p+1);
	//get current pid
	cpulimit_pid = getpid();
	//get cpu count
	NCPU = get_ncpu();

	//parse arguments
	int next_option;
    int option_index = 0;
	//A string listing valid short options letters
	const char* short_options = "+p:e:l:vzih";
	//An array describing valid long options
	const struct option long_options[] = {
		{ "pid",        required_argument, NULL, 'p' },
		{ "exe",        required_argument, NULL, 'e' },
		{ "limit",      required_argument, NULL, 'l' },
		{ "verbose",    no_argument,       NULL, 'v' },
		{ "lazy",       no_argument,       NULL, 'z' },
		{ "include-children", no_argument,  NULL, 'i' },
		{ "help",       no_argument,       NULL, 'h' },
		{ 0,            0,                 0,     0  }
	};

	do {
		next_option = getopt_long(argc, argv, short_options,long_options, &option_index);
		switch(next_option) {
			case 'p':
				pid = atoi(optarg);
				pid_ok = 1;
				break;
			case 'e':
				exe = optarg;
				exe_ok = 1;
				break;
			case 'l':
				perclimit = atoi(optarg);
				limit_ok = 1;
				break;
			case 'v':
				verbose = 1;
				break;
			case 'z':
				lazy = 1;
				break;
			case 'i':
				include_children = 1;
				break;
			case 'h':
				print_usage(stdout, 1);
				break;
			case '?':
				print_usage(stderr, 1);
				break;
			case -1:
				break;
			default:
				abort();
		}
	} while(next_option != -1);

	if (pid_ok && (pid <= 1 || pid >= get_pid_max())) {
		fprintf(stderr,"Error: Invalid value for argument PID\n");
		print_usage(stderr, 1);
		exit(1);
	}
	if (pid != 0) {
		lazy = 1;
	}

	if (!limit_ok) {
		fprintf(stderr,"Error: You must specify a cpu limit percentage\n");
		print_usage(stderr, 1);
		exit(1);
	}
	double limit = perclimit / 100.0;
	if (limit<0 || limit >NCPU) {
		fprintf(stderr,"Error: limit must be in the range 0-%d00\n", NCPU);
		print_usage(stderr, 1);
		exit(1);
	}

	int command_mode = optind < argc;
	if (exe_ok + pid_ok + command_mode == 0) {
		fprintf(stderr,"Error: You must specify one target process, either by name, pid, or command line\n");
		print_usage(stderr, 1);
		exit(1);
	}

	if (exe_ok + pid_ok + command_mode > 1) {
		fprintf(stderr,"Error: You must specify exactly one target process, either by name, pid, or command line\n");
		print_usage(stderr, 1);
		exit(1);
	}

	//all arguments are ok!
	signal(SIGINT, quit);
	signal(SIGTERM, quit);

	//print the number of available cpu
	if (verbose) printf("%d cpu detected\n", NCPU);

	if (command_mode) {
		int i;
		//executable file
		const char *cmd = argv[optind];
		//command line arguments
		char **cmd_args = (char**)malloc((argc-optind + 1) * sizeof(char*));
		if (cmd_args==NULL) exit(2);
		for (i=0; i<argc-optind; i++) {
			cmd_args[i] = argv[i+optind];
		}
		cmd_args[i] = NULL;

		if (verbose) {
			printf("Running command: '%s", cmd);
			for (i=1; i<argc-optind; i++) {
				printf(" %s", cmd_args[i]);
			}
			printf("'\n");
		}

		int child = fork();
		if (child < 0) {
			exit(EXIT_FAILURE);
		}
		else if (child == 0) {
			//target process code
			int ret = execvp(cmd, cmd_args);
			//if we are here there was an error, show it
			perror("Error");
			exit(ret);
		}
		else {
			//parent code
			free(cmd_args);
			int limiter = fork();
			if (limiter < 0) {
				exit(EXIT_FAILURE);
			}
			else if (limiter > 0) {
				//parent
				int status_process;
				int status_limiter;
				waitpid(child, &status_process, 0);
				waitpid(limiter, &status_limiter, 0);
				if (WIFEXITED(status_process)) {
					if (verbose) printf("Process %d terminated with exit status %d\n", child, (int)WEXITSTATUS(status_process));
					exit(WEXITSTATUS(status_process));
				}
				printf("Process %d terminated abnormally\n", child);
				exit(status_process);
			}
			else {
				//limiter code
				if (verbose) printf("Limiting process %d\n",child);
				limit_process(child, limit, include_children);
				exit(0);
			}
		}
	}

	while(1) {
		//look for the target process..or wait for it
		pid_t ret = 0;
		if (pid_ok) {
			//search by pid
			ret = find_process_by_pid(pid);
			if (ret == 0) {
				printf("No process found\n");
			}
			else if (ret < 0) {
				printf("Process found but you aren't allowed to control it\n");
			}
		}
		else {
			//search by file or path name
			ret = find_process_by_name(exe);
			if (ret == 0) {
				printf("No process found\n");
			}
			else if (ret < 0) {
				printf("Process found but you aren't allowed to control it\n");
			}
			else {
				pid = ret;
			}
		}
		if (ret > 0) {
			if (ret == cpulimit_pid) {
				printf("Target process %d is cpulimit itself! Aborting because it makes no sense\n", ret);
				exit(1);
			}
			printf("Process %d found\n", pid);
			//control
			limit_process(pid, limit, include_children);
		}
		if (lazy) break;
		sleep(2);
	};

	exit(0);
}
Beispiel #24
0
static rc_t ShowConfig(const KConfig* cfg, Params* prm) {
    rc_t rc = 0;
    bool hasAny = false;
    bool hasQuery = false;
    bool xml = true;
    assert(cfg && prm);
    xml = prm->xml;
    while (rc == 0) {
        KNamelist* names = NULL;
        const KConfigNode* node = NULL;
        uint32_t count = 0;
        uint32_t i = 0;
        int indent = 0;
        const char* root = NULL;
        const char* nodeName = NULL;
        size_t nodeNameL = 1;
        rc = ParamsGetNextParam(prm, &root);
        if (rc == 0) {
            if (root == NULL) {
                if (hasQuery)
                {   break; }
                else
                {   root = "/"; }
            }
            else { hasQuery = true; }
            assert(root);
        }
        if (rc == 0) {
            int64_t len = strlen(root);
            assert(len > 0);
            while (len > 0) {
                if (root[len - 1] == '/')
                {   --len; }
                else { break; }
            }
            assert(len >= 0);
            if (len == 0) {
                root += strlen(root) - 1;
                nodeName = root;
            }
            else {
                char *c = memrchr(root, '/', len);
                if (c != NULL) {
                    nodeName = c + 1;
                }
                else {
                    nodeName = root;
                }
            }
            assert(nodeName && nodeName[0]);
            nodeNameL = strlen(nodeName);
            while (nodeNameL > 1 && nodeName[nodeNameL - 1] == '/')
            {   --nodeNameL; }
        }

        if (rc == 0) {
            rc = KConfigOpenNodeRead(cfg, &node, root);
            DISP_RC(rc, root);
        }
        if (rc == 0) {
            rc = KConfigNodeListChild(node, &names);
        }
        if (rc == 0) {
            rc = KNamelistCount(names, &count);
        }
        if (rc == 0 && count == 0) {
            char buf[512] = "";
            size_t num_read = 0;
            rc = KConfigNodeReadData(node, buf, sizeof buf, &num_read);
            if (rc == 0 && num_read > 0) {
                if (prm->showMultiple)
                {   OUTMSG(("<!-- Configuration node %s -->\n", root)); }
                if (xml) {
                    VDB_CONGIG_OUTMSG(("<%.*s>", nodeNameL, nodeName));
                    VDB_CONGIG_OUTMSG(("%.*s", (int)num_read, buf));
                    VDB_CONGIG_OUTMSG(("</%.*s>\n", nodeNameL, nodeName));
                }
                else {
                    OUTMSG(("%.*s = \"%.*s\"\n",
                        nodeNameL, nodeName, (int)num_read, buf));
                }
                hasAny = true;
            }
        }
        else {
            if (rc == 0) {
                if (nodeName[0] != '/') {
                    if (prm->showMultiple)
                    {   OUTMSG(("<!-- Configuration node %s -->\n", root)); }
                    VDB_CONGIG_OUTMSG(("<%.*s>\n", nodeNameL, nodeName));
                } else {
                    if (prm->showMultiple)
                    {   OUTMSG(("<!-- Current configuration -->\n")); }
                    VDB_CONGIG_OUTMSG(("<Config>\n"));
                }
                hasAny = true;
                ++indent;
            }
            for (i = 0; i < count && rc == 0; ++i) {
                const char* name = NULL;
                if (rc == 0)
                {   rc = KNamelistGet(names, i, &name); }
                if (rc == 0) {
                    char* fullname = NULL;
                    if (strcmp(root, "/") == 0) {
                        fullname = malloc(strlen(name) + 2);
                        if (fullname == NULL) {
                            rc = RC(rcExe,
                                rcStorage, rcAllocating, rcMemory, rcExhausted);
                        }
                        sprintf(fullname, "/%s", name);
                    }
                    else {
                        fullname = strdup(root);
                        if (fullname == NULL) {
                            rc = RC(rcExe,
                                rcStorage, rcAllocating, rcMemory, rcExhausted);
                        }
                    }
                    if (rc == 0) {
                        rc = KConfigNodePrintChildNames
                            (xml, node, name, indent, fullname);
                        hasAny = true;
                    }
                    free(fullname);
                    fullname = NULL;
                }
            }
            if (rc == 0) {
                if (nodeName[0] != '/') {
                    VDB_CONGIG_OUTMSG(("</%.*s>\n", nodeNameL, nodeName));
                }
                else {
                    VDB_CONGIG_OUTMSG(("</Config>\n"));
                }
            }
        }

        RELEASE(KConfigNode, node);
        RELEASE(KNamelist, names);

        if (rc == 0) {
            if (hasAny) {
                OUTMSG(("\n"));
            }
            else if (nodeNameL > 0 && nodeName != NULL) {
                VDB_CONGIG_OUTMSG(("<%.*s/>\n", nodeNameL, nodeName));
            }
        }

        if (!hasQuery)
        {   break; }
    }

    return rc;
}
Beispiel #25
0
/* parses name as a given word number (1-based) in a str of size len
 * looks for name(#barcode)?([\/.]\d)?
 * returns score of found parts
 * score == 0 word not found
 */ 
static
uint8_t parse_spot_name(const SRALoaderFile* file, FileReadData* spot, const char* str, size_t len, uint8_t word_number)
{
    uint8_t w, score = 0;
    const char* name, *name_end;

    name = name_end = str;
    /* set name_end to end of word_number-th word */
    for(w = 1; w <= word_number || name_end == NULL; w++ ) {
        /* skip consecutive spaces */
        while( *name_end == ' ' && name_end != &str[len] ) {
            name_end++;
        }
        name = name_end;
        name_end = memchr(name, ' ', len - (name_end - str));
        if( name_end == NULL ) {
            if( w == word_number ) {
                name_end = &str[len];
            }
            break;
        }
    }
    if( name != name_end && name_end != NULL ) {
        char* x;
        rc_t rc;

        /* init only name portion */
        FileReadData_init(spot, true);
        --name_end; /* goto last char */
        if( isdigit(name_end[0])&& (name_end[-1] == '\\' || name_end[-1] == '/' )) {
            score++;
            spot->read.read_id = name_end[0] - '0';
            name_end -= 2;
        } else if( isdigit(*name_end) && name_end[-1] == '.' ) {
            int q = 0;
            if( memrchr(name, '#', name_end - name) != NULL ) {
                /* have barode -> this is read id */
                q = 4;
            } else {
                /* may a read id, check to see if 4 coords follow */
                const char* end = name_end - 1;
                while( --end >= name ) {
                    if( strchr(":|_", *end) != NULL ) {
                        q++;
                    } else if( !isdigit(*end) ) {
                        break;
                    }
                }
            }
            if( q == 4 ) {
                score++;
                spot->read.read_id = name_end[0] - '0';
                name_end -= 2;
            }
        }
        if( (x = memrchr(name, '#', name_end - name)) != NULL ) {
            score++;
            if( (rc = pstring_assign(&spot->barcode, x + 1, name_end - x)) != 0 ) {
                SRALoaderFile_LOG(file, klogErr, rc, "barcode $(b)", "b=%.*s", name_end - x, x + 1);
                return 0;
            }
            if( pstring_strcmp(&spot->barcode, "0") == 0 ) {
                pstring_clear(&spot->barcode);
            } else if( spot->barcode.len >= 4 &&
                       (strncmp(spot->barcode.data, "0/1_", 4) == 0 || strncmp(spot->barcode.data, "0/2_", 4) == 0) ) {
                spot->read.read_id = spot->barcode.data[2] - '0';
                pstring_assign(&spot->barcode, &spot->barcode.data[4], spot->barcode.len - 4);
            }
            name_end = --x;
        }
        score++;
        if( (rc = pstring_assign(&spot->name, name, name_end - name + 1)) != 0 ) {
            SRALoaderFile_LOG(file, klogErr, rc, "spot name $(n)", "n=%.*s", name_end - name + 1, name);
            return 0;
        }
        /* search for _R\d\D in name and use it as read id, remove from name or spot won't assemble */
        x = spot->name.data;
        while( (x = strrchr(x, 'R')) != NULL ) {
            if( x != spot->name.data && *(x - 1) == '_' && isdigit(*(x + 1)) && !isalnum(*(x + 2)) ) {
                score++;
		if(spot->read.read_id == -1){
			spot->read.read_id = *(x + 1) - '0';
		}
                strcpy(x - 1, x + 2);
                spot->name.len -= 4;
                break;
            }
            x++;
        }
        /* find last '=' and use only whatever is to the left of it */
        if( (x = memrchr(spot->name.data, '=', spot->name.len)) != NULL ) {
            rc = pstring_assign(&spot->name, spot->name.data, (x - spot->name.data) );
        }
    }
    return score;
}
int
_assuan_read_line (assuan_context_t ctx)
{
  char *line = ctx->inbound.line;
  int nread, atticlen;
  int rc;
  char *endp = 0;

  if (ctx->inbound.eof)
    return -1;

  atticlen = ctx->inbound.attic.linelen;
  if (atticlen)
    {
      memcpy (line, ctx->inbound.attic.line, atticlen);
      ctx->inbound.attic.linelen = 0;

      endp = memchr (line, '\n', atticlen);
      if (endp)
	/* Found another line in the attic.  */
	{
	  rc = 0;
	  nread = atticlen;
	  atticlen = 0;
	}
      else
	/* There is pending data but not a full line.  */
        {
          assert (atticlen < LINELENGTH);
          rc = readaline (ctx, line + atticlen,
			 LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
        }
    }
  else
    /* No pending data.  */
    rc = readaline (ctx, line, LINELENGTH,
                   &nread, &ctx->inbound.eof);
  if (rc)
    {
      if (ctx->log_fp)
	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Error: %s]\n",
		 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx, strerror (errno));
      return ASSUAN_Read_Error;
    }
  if (!nread)
    {
      assert (ctx->inbound.eof);
      if (ctx->log_fp)
	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [EOF]\n",
		 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx);
      return -1;
    }

  ctx->inbound.attic.pending = 0;
  nread += atticlen;

  if (! endp)
    endp = memchr (line, '\n', nread);

  if (endp)
    {
      int n = endp - line + 1;
      if (n < nread)
	/* LINE contains more than one line.  We copy it to the attic
	   now as handlers are allowed to modify the passed
	   buffer.  */
	{
	  int len = nread - n;
	  memcpy (ctx->inbound.attic.line, endp + 1, len);
	  ctx->inbound.attic.pending = memrchr (endp + 1, '\n', len) ? 1 : 0;
	  ctx->inbound.attic.linelen = len;
	}

      if (endp != line && endp[-1] == '\r')
	endp --;
      *endp = 0;

      ctx->inbound.linelen = endp - line;
      if (ctx->log_fp)
	{
	  fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- ",
		   assuan_get_assuan_log_prefix (),
                   (unsigned int)getpid (), (void *)ctx);
	  if (ctx->confidential)
	    fputs ("[Confidential data not shown]", ctx->log_fp);
	  else
	    _assuan_log_print_buffer (ctx->log_fp,
				      ctx->inbound.line,
				      ctx->inbound.linelen);
	  putc ('\n', ctx->log_fp);
	}
      return 0;
    }
  else
    {
      if (ctx->log_fp)
	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Invalid line]\n",
		 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx);
      *line = 0;
      ctx->inbound.linelen = 0;
      return ctx->inbound.eof ? ASSUAN_Line_Not_Terminated
	: ASSUAN_Line_Too_Long;
    }
}
Beispiel #27
0
struct Cookie *
Curl_cookie_add(struct SessionHandle *data,
                /* The 'data' pointer here may be NULL at times, and thus
                   must only be used very carefully for things that can deal
                   with data being NULL. Such as infof() and similar */

                struct CookieInfo *c,
                bool httpheader, /* TRUE if HTTP header-style line */
                char *lineptr,   /* first character of the line */
                const char *domain, /* default domain */
                const char *path)   /* full path used when this cookie is set,
                                       used to get default path for the cookie
                                       unless set */
{
  struct Cookie *clist;
  char name[MAX_NAME];
  struct Cookie *co;
  struct Cookie *lastc=NULL;
  time_t now = time(NULL);
  bool replace_old = FALSE;
  bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */

#ifdef CURL_DISABLE_VERBOSE_STRINGS
  (void)data;
#endif

  /* First, alloc and init a new struct for it */
  co = calloc(1, sizeof(struct Cookie));
  if(!co)
    return NULL; /* bail out if we're this low on memory */

  if(httpheader) {
    /* This line was read off a HTTP-header */
    const char *ptr;
    const char *semiptr;
    char *what;

    what = malloc(MAX_COOKIE_LINE);
    if(!what) {
      free(co);
      return NULL;
    }

    semiptr=strchr(lineptr, ';'); /* first, find a semicolon */

    while(*lineptr && ISBLANK(*lineptr))
      lineptr++;

    ptr = lineptr;
    do {
      /* we have a <what>=<this> pair or a stand-alone word here */
      name[0]=what[0]=0; /* init the buffers */
      if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n =]=%"
                     MAX_COOKIE_LINE_TXT "[^;\r\n]",
                     name, what)) {
        /* Use strstore() below to properly deal with received cookie
           headers that have the same string property set more than once,
           and then we use the last one. */
        const char *whatptr;
        bool done = FALSE;
        bool sep;
        size_t len=strlen(what);
        const char *endofn = &ptr[ strlen(name) ];

        /* skip trailing spaces in name */
        while(*endofn && ISBLANK(*endofn))
          endofn++;

        /* name ends with a '=' ? */
        sep = (*endofn == '=')?TRUE:FALSE;

        /* Strip off trailing whitespace from the 'what' */
        while(len && ISBLANK(what[len-1])) {
          what[len-1]=0;
          len--;
        }

        /* Skip leading whitespace from the 'what' */
        whatptr=what;
        while(*whatptr && ISBLANK(*whatptr))
          whatptr++;

        if(!len) {
          /* this was a "<name>=" with no content, and we must allow
             'secure' and 'httponly' specified this weirdly */
          done = TRUE;
          if(Curl_raw_equal("secure", name))
            co->secure = TRUE;
          else if(Curl_raw_equal("httponly", name))
            co->httponly = TRUE;
          else if(sep)
            /* there was a '=' so we're not done parsing this field */
            done = FALSE;
        }
        if(done)
          ;
        else if(Curl_raw_equal("path", name)) {
          strstore(&co->path, whatptr);
          if(!co->path) {
            badcookie = TRUE; /* out of memory bad */
            break;
          }
          co->spath = sanitize_cookie_path(co->path);
          if(!co->spath) {
            badcookie = TRUE; /* out of memory bad */
            break;
          }
        }
        else if(Curl_raw_equal("domain", name)) {
          /* Now, we make sure that our host is within the given domain,
             or the given domain is not valid and thus cannot be set. */

          if('.' == whatptr[0])
            whatptr++; /* ignore preceding dot */

          if(!domain || tailmatch(whatptr, domain)) {
            const char *tailptr=whatptr;
            if(tailptr[0] == '.')
              tailptr++;
            strstore(&co->domain, tailptr); /* don't prefix w/dots
                                               internally */
            if(!co->domain) {
              badcookie = TRUE;
              break;
            }
            co->tailmatch=TRUE; /* we always do that if the domain name was
                                   given */
          }
          else {
            /* we did not get a tailmatch and then the attempted set domain
               is not a domain to which the current host belongs. Mark as
               bad. */
            badcookie=TRUE;
            infof(data, "skipped cookie with bad tailmatch domain: %s\n",
                  whatptr);
          }
        }
        else if(Curl_raw_equal("version", name)) {
          strstore(&co->version, whatptr);
          if(!co->version) {
            badcookie = TRUE;
            break;
          }
        }
        else if(Curl_raw_equal("max-age", name)) {
          /* Defined in RFC2109:

             Optional.  The Max-Age attribute defines the lifetime of the
             cookie, in seconds.  The delta-seconds value is a decimal non-
             negative integer.  After delta-seconds seconds elapse, the
             client should discard the cookie.  A value of zero means the
             cookie should be discarded immediately.

          */
          strstore(&co->maxage, whatptr);
          if(!co->maxage) {
            badcookie = TRUE;
            break;
          }
          co->expires =
            strtol((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0],NULL,10)
            + (long)now;
        }
        else if(Curl_raw_equal("expires", name)) {
          strstore(&co->expirestr, whatptr);
          if(!co->expirestr) {
            badcookie = TRUE;
            break;
          }
          /* Note that if the date couldn't get parsed for whatever reason,
             the cookie will be treated as a session cookie */
          co->expires = curl_getdate(what, &now);

          /* Session cookies have expires set to 0 so if we get that back
             from the date parser let's add a second to make it a
             non-session cookie */
          if(co->expires == 0)
            co->expires = 1;
          else if(co->expires < 0)
            co->expires = 0;
        }
        else if(!co->name) {
          co->name = strdup(name);
          co->value = strdup(whatptr);
          if(!co->name || !co->value) {
            badcookie = TRUE;
            break;
          }
        }
        /*
          else this is the second (or more) name we don't know
          about! */
      }
      else {
        /* this is an "illegal" <what>=<this> pair */
      }

      if(!semiptr || !*semiptr) {
        /* we already know there are no more cookies */
        semiptr = NULL;
        continue;
      }

      ptr=semiptr+1;
      while(*ptr && ISBLANK(*ptr))
        ptr++;
      semiptr=strchr(ptr, ';'); /* now, find the next semicolon */

      if(!semiptr && *ptr)
        /* There are no more semicolons, but there's a final name=value pair
           coming up */
        semiptr=strchr(ptr, '\0');
    } while(semiptr);

    if(!badcookie && !co->domain) {
      if(domain) {
        /* no domain was given in the header line, set the default */
        co->domain=strdup(domain);
        if(!co->domain)
          badcookie = TRUE;
      }
    }

    if(!badcookie && !co->path && path) {
      /* No path was given in the header line, set the default.
         Note that the passed-in path to this function MAY have a '?' and
         following part that MUST not be stored as part of the path. */
      char *queryp = strchr(path, '?');

      /* queryp is where the interesting part of the path ends, so now we
         want to the find the last */
      char *endslash;
      if(!queryp)
        endslash = strrchr(path, '/');
      else
        endslash = memrchr(path, '/', (size_t)(queryp - path));
      if(endslash) {
        size_t pathlen = (size_t)(endslash-path+1); /* include ending slash */
        co->path=malloc(pathlen+1); /* one extra for the zero byte */
        if(co->path) {
          memcpy(co->path, path, pathlen);
          co->path[pathlen]=0; /* zero terminate */
          co->spath = sanitize_cookie_path(co->path);
          if(!co->spath)
            badcookie = TRUE; /* out of memory bad */
        }
        else
          badcookie = TRUE;
      }
    }

    free(what);

    if(badcookie || !co->name) {
      /* we didn't get a cookie name or a bad one,
         this is an illegal line, bail out */
      freecookie(co);
      return NULL;
    }

  }
  else {
    /* This line is NOT a HTTP header style line, we do offer support for
       reading the odd netscape cookies-file format here */
    char *ptr;
    char *firstptr;
    char *tok_buf=NULL;
    int fields;

    /* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies
       marked with httpOnly after the domain name are not accessible
       from javascripts, but since curl does not operate at javascript
       level, we include them anyway. In Firefox's cookie files, these
       lines are preceded with #HttpOnly_ and then everything is
       as usual, so we skip 10 characters of the line..
    */
    if(strncmp(lineptr, "#HttpOnly_", 10) == 0) {
      lineptr += 10;
      co->httponly = TRUE;
    }

    if(lineptr[0]=='#') {
      /* don't even try the comments */
      free(co);
      return NULL;
    }
    /* strip off the possible end-of-line characters */
    ptr=strchr(lineptr, '\r');
    if(ptr)
      *ptr=0; /* clear it */
    ptr=strchr(lineptr, '\n');
    if(ptr)
      *ptr=0; /* clear it */

    firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */

    /* Now loop through the fields and init the struct we already have
       allocated */
    for(ptr=firstptr, fields=0; ptr && !badcookie;
        ptr=strtok_r(NULL, "\t", &tok_buf), fields++) {
      switch(fields) {
      case 0:
        if(ptr[0]=='.') /* skip preceding dots */
          ptr++;
        co->domain = strdup(ptr);
        if(!co->domain)
          badcookie = TRUE;
        break;
      case 1:
        /* This field got its explanation on the 23rd of May 2001 by
           Andrés García:

           flag: A TRUE/FALSE value indicating if all machines within a given
           domain can access the variable. This value is set automatically by
           the browser, depending on the value you set for the domain.

           As far as I can see, it is set to true when the cookie says
           .domain.com and to false when the domain is complete www.domain.com
        */
        co->tailmatch = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
        break;
      case 2:
        /* It turns out, that sometimes the file format allows the path
           field to remain not filled in, we try to detect this and work
           around it! Andrés García made us aware of this... */
        if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
          /* only if the path doesn't look like a boolean option! */
          co->path = strdup(ptr);
          if(!co->path)
            badcookie = TRUE;
          else {
            co->spath = sanitize_cookie_path(co->path);
            if(!co->spath) {
              badcookie = TRUE; /* out of memory bad */
            }
          }
          break;
        }
        /* this doesn't look like a path, make one up! */
        co->path = strdup("/");
        if(!co->path)
          badcookie = TRUE;
        co->spath = strdup("/");
        if(!co->spath)
          badcookie = TRUE;
        fields++; /* add a field and fall down to secure */
        /* FALLTHROUGH */
      case 3:
        co->secure = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
        break;
      case 4:
        co->expires = curlx_strtoofft(ptr, NULL, 10);
        break;
      case 5:
        co->name = strdup(ptr);
        if(!co->name)
          badcookie = TRUE;
        break;
      case 6:
        co->value = strdup(ptr);
        if(!co->value)
          badcookie = TRUE;
        break;
      }
    }
    if(6 == fields) {
      /* we got a cookie with blank contents, fix it */
      co->value = strdup("");
      if(!co->value)
        badcookie = TRUE;
      else
        fields++;
    }

    if(!badcookie && (7 != fields))
      /* we did not find the sufficient number of fields */
      badcookie = TRUE;

    if(badcookie) {
      freecookie(co);
      return NULL;
    }

  }

  if(!c->running &&    /* read from a file */
     c->newsession &&  /* clean session cookies */
     !co->expires) {   /* this is a session cookie since it doesn't expire! */
    freecookie(co);
    return NULL;
  }

  co->livecookie = c->running;

  /* now, we have parsed the incoming line, we must now check if this
     superceeds an already existing cookie, which it may if the previous have
     the same domain and path as this */

  clist = c->cookies;
  replace_old = FALSE;
  while(clist) {
    if(Curl_raw_equal(clist->name, co->name)) {
      /* the names are identical */

      if(clist->domain && co->domain) {
        if(Curl_raw_equal(clist->domain, co->domain))
          /* The domains are identical */
          replace_old=TRUE;
      }
      else if(!clist->domain && !co->domain)
        replace_old = TRUE;

      if(replace_old) {
        /* the domains were identical */

        if(clist->spath && co->spath) {
          if(Curl_raw_equal(clist->spath, co->spath)) {
            replace_old = TRUE;
          }
          else
            replace_old = FALSE;
        }
        else if(!clist->spath && !co->spath)
          replace_old = TRUE;
        else
          replace_old = FALSE;

      }

      if(replace_old && !co->livecookie && clist->livecookie) {
        /* Both cookies matched fine, except that the already present
           cookie is "live", which means it was set from a header, while
           the new one isn't "live" and thus only read from a file. We let
           live cookies stay alive */

        /* Free the newcomer and get out of here! */
        freecookie(co);
        return NULL;
      }

      if(replace_old) {
        co->next = clist->next; /* get the next-pointer first */

        /* then free all the old pointers */
        free(clist->name);
        if(clist->value)
          free(clist->value);
        if(clist->domain)
          free(clist->domain);
        if(clist->path)
          free(clist->path);
        if(clist->spath)
          free(clist->spath);
        if(clist->expirestr)
          free(clist->expirestr);

        if(clist->version)
          free(clist->version);
        if(clist->maxage)
          free(clist->maxage);

        *clist = *co;  /* then store all the new data */

        free(co);   /* free the newly alloced memory */
        co = clist; /* point to the previous struct instead */

        /* We have replaced a cookie, now skip the rest of the list but
           make sure the 'lastc' pointer is properly set */
        do {
          lastc = clist;
          clist = clist->next;
        } while(clist);
        break;
      }
    }
    lastc = clist;
    clist = clist->next;
  }

  if(c->running)
    /* Only show this when NOT reading the cookies from a file */
    infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, "
          "expire %" FORMAT_OFF_T "\n",
          replace_old?"Replaced":"Added", co->name, co->value,
          co->domain, co->path, co->expires);

  if(!replace_old) {
    /* then make the last item point on this new one */
    if(lastc)
      lastc->next = co;
    else
      c->cookies = co;
    c->numcookies++; /* one more cookie in the jar */
  }

  return co;
}
bool http_connection::process_request(unsigned fd)
{
	char* data = _M_in.data();
	data[_M_uri + _M_urilen] = 0;

	// Parse URL.
	_M_url.reset();
	url_parser::parse_result parse_result = _M_url.parse(data + _M_uri, _M_urilen, _M_path);
	if (parse_result == url_parser::ERROR_NO_MEMORY) {
		logger::instance().log(logger::LOG_INFO, "[http_connection::process_request] (fd %d) No memory, URL (%.*s).", fd, _M_urilen, data + _M_uri);

		_M_error = http_error::INTERNAL_SERVER_ERROR;
		return true;
	} else if (parse_result == url_parser::PARSE_ERROR) {
		if (_M_path.count() > 0) {
			logger::instance().log(logger::LOG_INFO, "[http_connection::process_request] (fd %d) URL parse error (%.*s).", fd, _M_path.count(), _M_path.data());
		} else {
			logger::instance().log(logger::LOG_INFO, "[http_connection::process_request] (fd %d) URL parse error (%.*s).", fd, _M_urilen, data + _M_uri);
		}

		_M_error = http_error::BAD_REQUEST;
		return true;
	} else if (parse_result == url_parser::FORBIDDEN) {
		logger::instance().log(logger::LOG_INFO, "[http_connection::process_request] (fd %d) Forbidden URL (%.*s).", fd, _M_path.count(), _M_path.data());

		_M_error = http_error::FORBIDDEN;
		return true;
	}

	// If an absolute URL has been received...
	unsigned short hostlen;
	const char* host = _M_url.get_host(hostlen);
	if (host) {
		if ((_M_major_number == 1) && (_M_minor_number == 1)) {
			// Ignore Host header (if present).
			const char* value;
			unsigned short valuelen;
			if (!_M_headers.get_value_known_header(http_headers::HOST_HEADER, value, &valuelen)) {
				_M_error = http_error::BAD_REQUEST;
				return true;
			}
		}

		if (!_M_host.append_nul_terminated_string(host, hostlen)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}

		_M_port = _M_url.get_port();

#if PROXY
		_M_http_rule.handler = rulelist::HTTP_HANDLER;
		_M_rule = &_M_http_rule;
		return process_non_local_handler(fd);
#endif // PROXY

		if (_M_url.get_port() != static_cast<http_server*>(_M_server)->_M_port) {
			not_found();
			return true;
		}

		_M_vhost = static_cast<http_server*>(_M_server)->_M_vhosts.get_host(host, hostlen);
	} else {
		if (_M_headers.get_value_known_header(http_headers::HOST_HEADER, host, &hostlen)) {
			// If the host includes port number...
			unsigned port;

			const char* semicolon = (const char*) memrchr(host, ':', hostlen);
			if (semicolon) {
				if (number::parse_unsigned(semicolon + 1, (host + hostlen) - (semicolon + 1), port, 1, 65535) != number::PARSE_SUCCEEDED) {
					_M_error = http_error::BAD_REQUEST;
					return true;
				}

				hostlen = semicolon - host;
			} else {
				port = url_parser::HTTP_DEFAULT_PORT;
			}

			if (port != static_cast<http_server*>(_M_server)->_M_port) {
				not_found();
				return true;
			}

			_M_vhost = static_cast<http_server*>(_M_server)->_M_vhosts.get_host(host, hostlen);
		} else {
			if ((_M_major_number == 1) && (_M_minor_number == 1)) {
				_M_error = http_error::BAD_REQUEST;
				return true;
			}

			_M_vhost = static_cast<http_server*>(_M_server)->_M_vhosts.get_default_host();
		}
	}

	if (!_M_vhost) {
		not_found();
		return true;
	}

	unsigned short pathlen;
	const char* urlpath = _M_url.get_path(pathlen);

	unsigned short extensionlen;
	const char* extension = _M_url.get_extension(extensionlen);

	_M_rule = _M_vhost->rules->find(_M_method, urlpath, pathlen, extension, extensionlen);

	if (_M_rule->handler != rulelist::LOCAL_HANDLER) {
		if (_M_rule->handler == rulelist::FCGI_HANDLER) {
			size_t len = _M_vhost->rootlen + pathlen;
			if (len > PATH_MAX) {
				_M_error = http_error::REQUEST_URI_TOO_LONG;
				return true;
			}

			// Save decoded path.
			if (!_M_decoded_path.append(urlpath, pathlen)) {
				_M_error = http_error::INTERNAL_SERVER_ERROR;
				return true;
			}

			unsigned short query_string_len;
			const char* query_string = _M_url.get_query(query_string_len);
			if (query_string_len > 1) {
				// Save query string.
				if (!_M_query_string.append(query_string + 1, query_string_len - 1)) {
					_M_error = http_error::INTERNAL_SERVER_ERROR;
					return true;
				}
			}
		}

		return process_non_local_handler(fd);
	}

	// Local handler.

	if ((_M_method != http_method::GET) && (_M_method != http_method::HEAD)) {
		_M_error = http_error::NOT_IMPLEMENTED;
		return true;
	}

	char path[PATH_MAX + 1];
	size_t len = _M_vhost->rootlen + pathlen;
	if (len >= sizeof(path)) {
		_M_error = http_error::REQUEST_URI_TOO_LONG;
		return true;
	}

	memcpy(path, _M_vhost->root, _M_vhost->rootlen);
	memcpy(path + _M_vhost->rootlen, urlpath, pathlen);
	path[len] = 0;

	struct stat buf;
	if (stat(path, &buf) < 0) {
		not_found();
		return true;
	}

	bool dirlisting;
	bool index_file;

	// If the URI points to a directory...
	if (S_ISDIR(buf.st_mode)) {
		// If the directory name doesn't end with '/'...
		if (path[len - 1] != '/') {
			moved_permanently();
			return true;
		}

		// Search index file.
		if (static_cast<http_server*>(_M_server)->_M_index_file_finder.search(path, len, &buf)) {
			// File.
			dirlisting = false;
			index_file = true;
		} else {
			// If we don't have directory listing...
			if (!_M_vhost->have_dirlisting) {
				not_found();
				return true;
			} else {
				// Build directory listing.
				if (!_M_vhost->dir_listing->build(urlpath, pathlen, _M_body)) {
					logger::instance().log(logger::LOG_WARNING, "[http_connection::process_request] (fd %d) Couldn't build directory listing for (%s).", fd, path);

					_M_error = http_error::INTERNAL_SERVER_ERROR;
					return true;
				}

				_M_bodyp = &_M_body;

				dirlisting = true;
				index_file = false;
			}
		}
	} else if ((S_ISREG(buf.st_mode)) || (S_ISLNK(buf.st_mode))) {
		// File.
		dirlisting = false;
		index_file = false;
	} else {
		not_found();
		return true;
	}

	if (!dirlisting) {
		const char* value;
		unsigned short valuelen;
		if (_M_headers.get_value_known_header(http_headers::IF_MODIFIED_SINCE_HEADER, value, &valuelen)) {
			time_t t;
			if ((t = date_parser::parse(value, valuelen, &_M_last_modified)) != (time_t) -1) {
				if (t == buf.st_mtime) {
					not_modified();
					return true;
				} else if (t > buf.st_mtime) {
					gmtime_r(&buf.st_mtime, &_M_last_modified);
					not_modified();

					return true;
				}
			}
		}

		if (_M_method == http_method::GET) {
			if ((_M_headers.get_value_known_header(http_headers::RANGE_HEADER, value, &valuelen)) && (valuelen > 6) && (strncasecmp(value, "bytes=", 6) == 0)) {
				if (!range_parser::parse(value + 6, valuelen - 6, buf.st_size, _M_ranges)) {
					requested_range_not_satisfiable();
					return true;
				}
			}

			if ((_M_fd = file_wrapper::open(path, O_RDONLY)) < 0) {
				logger::instance().log(logger::LOG_WARNING, "[http_connection::process_request] (fd %d) Couldn't open file (%s).", fd, path);

				_M_error = http_error::INTERNAL_SERVER_ERROR;
				return true;
			}
		}
	}

	http_headers* headers = &(static_cast<http_server*>(_M_server)->_M_headers);
	headers->reset();

	if (!headers->add_known_header(http_headers::DATE_HEADER, &now::_M_tm)) {
		_M_error = http_error::INTERNAL_SERVER_ERROR;
		return true;
	}

	if (keep_alive()) {
		if (!headers->add_known_header(http_headers::CONNECTION_HEADER, "Keep-Alive", 10, false)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}
	} else {
		if (!headers->add_known_header(http_headers::CONNECTION_HEADER, "close", 5, false)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}
	}

	if (!headers->add_known_header(http_headers::SERVER_HEADER, WEBSERVER_NAME, sizeof(WEBSERVER_NAME) - 1, false)) {
		_M_error = http_error::INTERNAL_SERVER_ERROR;
		return true;
	}

	unsigned short status_code;

	// Directory listing?
	if (dirlisting) {
		char num[32];
		int numlen = snprintf(num, sizeof(num), "%lu", _M_body.count());
		if (!headers->add_known_header(http_headers::CONTENT_LENGTH_HEADER, num, numlen, false)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}

		if (!headers->add_known_header(http_headers::CONTENT_TYPE_HEADER, "text/html; charset=UTF-8", 24, false)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}

		status_code = 200;
	} else {
		if (!headers->add_known_header(http_headers::ACCEPT_RANGES_HEADER, "bytes", 5, false)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}

		if (index_file) {
			const char* end = path + len;
			const char* ptr = end;
			extension = NULL;
			while ((ptr > path) && (*(ptr - 1) != '/')) {
				if (*(ptr - 1) == '.') {
					extension = ptr;
					extensionlen = end - extension;
					break;
				}

				ptr--;
			}
		}

		if ((extension) && (extensionlen > 0)) {
			_M_type = static_cast<http_server*>(_M_server)->_M_mime_types.get_mime_type(extension, extensionlen, _M_typelen);
		} else {
			_M_type = mime_types::DEFAULT_MIME_TYPE;
			_M_typelen = mime_types::DEFAULT_MIME_TYPE_LEN;
		}

		_M_filesize = compute_content_length(buf.st_size);

		char num[32];
		int numlen = snprintf(num, sizeof(num), "%lld", _M_filesize);
		if (!headers->add_known_header(http_headers::CONTENT_LENGTH_HEADER, num, numlen, false)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}

		const range_list::range* range;
		char content_range[128];

		switch (_M_ranges.count()) {
			case 0:
				if (!headers->add_known_header(http_headers::CONTENT_TYPE_HEADER, _M_type, _M_typelen, false)) {
					_M_error = http_error::INTERNAL_SERVER_ERROR;
					return true;
				}

				status_code = 200;

				break;
			case 1:
				if (!headers->add_known_header(http_headers::CONTENT_TYPE_HEADER, _M_type, _M_typelen, false)) {
					_M_error = http_error::INTERNAL_SERVER_ERROR;
					return true;
				}

				range = _M_ranges.get(0);

				len = snprintf(content_range, sizeof(content_range), "bytes %lld-%lld/%lld", range->from, range->to, buf.st_size);
				if (!headers->add_known_header(http_headers::CONTENT_RANGE_HEADER, content_range, len, false)) {
					_M_error = http_error::INTERNAL_SERVER_ERROR;
					return true;
				}

				status_code = 206;

				break;
			default:
				_M_boundary = ++(static_cast<http_server*>(_M_server)->_M_boundary);
				if (!headers->add_content_type_multipart(_M_boundary)) {
					_M_error = http_error::INTERNAL_SERVER_ERROR;
					return true;
				}

				status_code = 206;
		}

		// Add 'Last-Modified' header.

		struct tm timestamp;
		gmtime_r(&buf.st_mtime, &timestamp);

		if (!headers->add_known_header(http_headers::LAST_MODIFIED_HEADER, &timestamp)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}
	}

	_M_out.reset();

	if (status_code == 200) {
		if (!_M_out.append("HTTP/1.1 200 OK\r\n", 17)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}
	} else {
		if (!_M_out.append("HTTP/1.1 206 Partial Content\r\n", 30)) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}
	}

	if (!headers->serialize(_M_out)) {
		_M_error = http_error::INTERNAL_SERVER_ERROR;
		return true;
	}

	_M_response_header_size = _M_out.count();

	// If multipart...
	if (_M_ranges.count() >= 2) {
		if (!build_part_header()) {
			_M_error = http_error::INTERNAL_SERVER_ERROR;
			return true;
		}
	}

	_M_error = http_error::OK;

	if (_M_method == http_method::HEAD) {
		_M_filesize = 0;

		_M_state = SENDING_HEADERS_STATE;
	} else {
		if (dirlisting) {
			_M_filesize = _M_body.count();

			_M_state = SENDING_TWO_BUFFERS_STATE;
		} else {
			socket_wrapper::cork(fd);

			_M_state = SENDING_HEADERS_STATE;
		}
	}

	return true;
}
bool http_server::load_rules(const xmlconf& conf, const general_conf& general_conf, const char* host, rulelist* rules)
{
	for (unsigned i = 0; ; i++) {
		char name[64];
		snprintf(name, sizeof(name), "rule-%u", i);

		const char* value;
		size_t len;
		if (!conf.get_value(value, len, "config", "hosts", host, "request_handling", name, "handler", NULL)) {
			return true;
		}

		unsigned char handler;

		if (len == 4) {
			if (strncasecmp(value, "http", 4) == 0) {
				handler = rulelist::HTTP_HANDLER;
			} else {
				return false;
			}
		} else if (len == 5) {
			if (strncasecmp(value, "local", 5) == 0) {
				handler = rulelist::LOCAL_HANDLER;
			} else {
				return false;
			}
		} else if (len == 7) {
			if (strncasecmp(value, "fastcgi", 7) == 0) {
				handler = rulelist::FCGI_HANDLER;
			} else {
				return false;
			}
		} else {
			return false;
		}

		if (!conf.get_value(value, len, "config", "hosts", host, "request_handling", name, "criterion", NULL)) {
			return false;
		}

		unsigned char criterion;

		if (len == 4) {
			if (strncasecmp(value, "path", 4) == 0) {
				criterion = rulelist::BY_PATH;
			} else {
				return false;
			}
		} else if (len == 6) {
			if (strncasecmp(value, "method", 6) == 0) {
				criterion = rulelist::BY_METHOD;
			} else {
				return false;
			}
		} else if (len == 14) {
			if (strncasecmp(value, "file_extension", 14) == 0) {
				criterion = rulelist::BY_EXTENSION;
			} else {
				return false;
			}
		} else {
			return false;
		}

		rulelist::rule* rule;
		if ((rule = new (std::nothrow) rulelist::rule) == NULL) {
			return false;
		}

		unsigned j;

		if (criterion == rulelist::BY_PATH) {
			for (j = 0; conf.get_child(j, value, len, "config", "hosts", host, "request_handling", name, "values", NULL); j++) {
				if (!rule->paths.add(value, len)) {
					delete rule;
					return false;
				}
			}
		} else if (criterion == rulelist::BY_EXTENSION) {
			for (j = 0; conf.get_child(j, value, len, "config", "hosts", host, "request_handling", name, "values", NULL); j++) {
				if (!rule->extensions.add(value, len)) {
					delete rule;
					return false;
				}
			}
		} else {
			for (j = 0; conf.get_child(j, value, len, "config", "hosts", host, "request_handling", name, "values", NULL); j++) {
				unsigned char method;
				if ((method = http_method::get_method(value, len)) == http_method::UNKNOWN) {
					delete rule;
					return false;
				}

				rule->add(method);
			}
		}

		if (j == 0) {
			delete rule;
			return false;
		}

		rule->backends.set_retry_interval(general_conf.backend_retry_interval);

		if (handler != rulelist::LOCAL_HANDLER) {
			for (j = 0; conf.get_child(j, value, len, "config", "hosts", host, "request_handling", name, "backends", NULL); j++) {
				unsigned port;

				const char* semicolon = (const char*) memrchr(value, ':', len);
				if (semicolon) {
					if (number::parse_unsigned(semicolon + 1, (value + len) - (semicolon + 1), port, 1, 65535) != number::PARSE_SUCCEEDED) {
						delete rule;
						return false;
					}

					len = semicolon - value;
				} else {
					if (handler != rulelist::HTTP_HANDLER) {
						delete rule;
						return false;
					}

					port = url_parser::HTTP_DEFAULT_PORT;
				}

				if (len > url_parser::HOST_MAX_LEN) {
					delete rule;
					return false;
				}

				if (!rule->backends.add(value, len, port)) {
					delete rule;
					return false;
				}
			}

			if (j == 0) {
				delete rule;
				return false;
			}
		}

		rule->handler = handler;
		rule->criterion = criterion;

		if (!rules->add(rule)) {
			delete rule;
			return false;
		}
	}

	return true;
}
Beispiel #30
0
  assert(sockaddr != NULL);
  assert(addrport != NULL);
  assert((atype == TWDIP_v4) || (atype == TWDIP_v6) || (atype == TWDIP_any));
  
  memcpy(ipaddr,addrport,len + 1);

  /*--------------------------------------------------------------------
  ; We search backwards through the string, instead of forwards, because
  ; IPv6 addresses has embedded colons (but are embedded in brackets, with
  ; the port outside the brackets.  It will look like:
  ;
  ;	[fc00::1]:2222
  ;
  ;-----------------------------------------------------------------------*/  
  
  tport = memrchr(ipaddr,':',len);
  
  if (tport != NULL)
    *tport++ = '\0';
  else
    return EINVAL; /* when we get an IANA port, we can specify it here */

  /*--------------------------------------------------------------------
  ; if the first character of the addrport is a bracket, this is an IPv6
  ; address.  Using a hack, if the two characters previous to the port text
  ; is NOT a closing bracket, we return an error, otherwise, we NUL out the
  ; closing bracket, and skip the addrport pointer past the opening bracket,
  ; thus leaving us with a straight IPv6 address.
  ;-------------------------------------------------------------------------*/

  if (ipaddr[0] == '[')