예제 #1
0
파일: aiod.C 프로젝트: bougyman/sfs
static void
sigio_handler (int sig)
{
  int saved_errno = errno;
  static timeval ztv = { 0, 0 };

  sigio_received = 1;
  flock (shmfd, LOCK_UN);
  while (fdwait (rwfd, selread, &ztv) > 0) {
    /* Note that rwfd is a unix domain socket, not a pipe.  Since unix
     * domain sockets are not specified by POSIX, writes of less than
     * PIPE_BUF bytes could conceivably not be atomic on some systems,
     * and a true select for writing might not even guarantee PIPE_BUF
     * bytes of buffer space.
     *
     * We thereforedo a "fullread" here.  We know the client is trying
     * to write sizeof (msg) bytes to us, so we don't need to worry
     * about blocking. */
    aiomsg_t msg;
    ssize_t n = fullread (rwfd, &msg, sizeof (msg));
    if (n != sizeof (msg)) {
      if (n < 0)
	fatal ("read: %m\n");
      exit (0);
    }
    srv->getmsg (msg);
  }
  errno = saved_errno;
}
예제 #2
0
파일: sockfilt.c 프로젝트: AndyUI/curl
static bool read_stdin(void *buffer, size_t nbytes)
{
  ssize_t nread = fullread(fileno(stdin), buffer, nbytes);
  if(nread != (ssize_t)nbytes) {
    logmsg("exiting...");
    return FALSE;
  }
  return TRUE;
}
예제 #3
0
// Copy ordinary file
static FXbool copyfile (const FXString & oldfile, const FXString & newfile, thread_elem * te)
{
    unsigned char buffer[4096];
    struct stat status;
    long nread, nwritten;
    int src, dst;
    FXbool ok = FALSE;
    if ((src = open (oldfile.text (), O_RDONLY)) >= 0)
    {
	if (::stat (oldfile.text (), &status) == 0)
	{


	    te->act_file_name = oldfile.text ();
	    te->act_file_size = 1;
	    te->file_size = status.st_size;



	    if ((dst = open (newfile.text (), O_WRONLY | O_CREAT | O_TRUNC, status.st_mode)) >= 0)
	    {
		while (1)
		{
		    nread = fullread (src, buffer, sizeof (buffer));
		    if (nread < 0)
			goto err;
		    if (nread == 0)
			break;




		    if (te->cancel == true)
		    {
			fxmessage ("CANCEL CANCEL CANCEL CANCEL !!!\n\n\n\n\n");
			close (dst);
			close (src);
			return FALSE;
		    }

		    te->act_file_size += nread;
		    te->act_total_size += nread;



		    nwritten = fullwrite (dst, buffer, nread);
		    if (nwritten < 0)
			goto err;
		}
		ok = TRUE;
	      err:close (dst);
	    }
	}
	close (src);
    }
    return ok;
}
	void streamtools_object::test<25>()
	{
		std::string str = "First Line.\nSecond Line\n";
		std::istringstream is(str);
		char buf[255] = {0};
		
		fullread(is, buf, 255);
		ensure_memory_matches("fullread: read with newlines", (void*) buf,  str.size()-1, (void*) str.c_str(), str.size()-1);

		is.clear();
		is.str(str = "First Line.\nSecond Line\n");
		memset(buf, 0, 255);
		
		char expected_string[] = "First Line.\nSecond";
		int len = sizeof(expected_string)-1;
		fullread(is, buf, len);
		ensure_memory_matches("fullread: read with newlines", (void*) buf, len, (void*) &expected_string, len);
	}
예제 #5
0
파일: aiod.C 프로젝트: maxtaco/sfslite
static bool
read_fd (int fd, fd_set *set, aiomsg_t *msg)
{
  bool ret = false;
  if (FD_ISSET (fd, set)) {
    size_t msz = sizeof (*msg);
    size_t n = fullread (fd, msg, msz);
    if (n == msz) {
      ret = true;
    } else if (n < 0) {
      warn ("error in reading from fd=%d: %m\n", fd);
    } else if (n == 0) {
      exit (0);
    }
  }
  return ret;
}
예제 #6
0
bool LLSDBinaryParser::parseString(
	std::istream& istr,
	std::string& value) const
{
	// *FIX: This is memory inefficient.
	U32 value_nbo = 0;
	read(istr, (char*)&value_nbo, sizeof(U32));		 /*Flawfinder: ignore*/
	S32 size = (S32)ntohl(value_nbo);
	if(mCheckLimits && (size > mMaxBytesLeft)) return false;
	std::vector<char> buf;
	if(size)
	{
		buf.resize(size);
		account(fullread(istr, &buf[0], size));
		value.assign(buf.begin(), buf.end());
	}
	return true;
}
예제 #7
0
파일: httpauth.c 프로젝트: StAlphonsos/kcgi
enum kcgi_err
kworker_auth_parent(int fd, struct khttpauth *auth)
{
	enum kcgi_err	 ke;

	if (fullread(fd, &auth->type, sizeof(enum kauth), 0, &ke) < 0)
		return(ke);

	switch (auth->type) {
	case (KAUTH_DIGEST):
		if (fullread(fd, &auth->authorised, sizeof(int), 0, &ke) < 0)
			return(ke);
		if ( ! auth->authorised)
			break;
		if (fullread(fd, &auth->d.digest.alg, sizeof(enum khttpalg), 0, &ke) < 0)
			return(ke);
		if (fullread(fd, &auth->d.digest.qop, sizeof(enum khttpqop), 0, &ke) < 0)
			return(ke);
		if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.user)))
			return(ke);
		if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.uri)))
			return(ke);
		if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.realm)))
			return(ke);
		if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.nonce)))
			return(ke);
		if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.cnonce)))
			return(ke);
		if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.response)))
			return(ke);
		if (fullread(fd, &auth->d.digest.count, sizeof(size_t), 0, &ke) < 0)
			return(ke);
		if (KCGI_OK != (ke = fullreadword(fd, &auth->d.digest.opaque)))
			return(ke);
		break;
	case (KAUTH_BASIC):
		if (fullread(fd, &auth->authorised, sizeof(int), 0, &ke) < 0)
			return(ke);
		if ( ! auth->authorised)
			break;
		if (KCGI_OK != (ke = fullreadword(fd, &auth->d.basic.response)))
			return(ke);
		break;
	default:
		break;
	}

	return(KCGI_OK);
}
예제 #8
0
int deserialize_string_raw(
	std::istream& istr,
	std::string& value,
	S32 max_bytes)
{
	int count = 0;
	const S32 BUF_LEN = 20;
	char buf[BUF_LEN];		/* Flawfinder: ignore */
	istr.get(buf, BUF_LEN - 1, ')');
	count += istr.gcount();
	char c = istr.get();
	c = istr.get();
	count += 2;
	if(((c == '"') || (c == '\'')) && (buf[0] == '('))
	{
		// We probably have a valid raw string. determine
		// the size, and read it.
		// *FIX: This is memory inefficient.
		S32 len = strtol(buf + 1, NULL, 0);
		if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE;
		std::vector<char> buf;
		if(len)
		{
			buf.resize(len);
			count += fullread(istr, (char *)&buf[0], len);
			value.assign(buf.begin(), buf.end());
		}
		c = istr.get();
		++count;
		if(!((c == '"') || (c == '\'')))
		{
			return LLSDParser::PARSE_FAILURE;
		}
	}
	else
	{
		return LLSDParser::PARSE_FAILURE;
	}
	return count;
}
예제 #9
0
// virtual
S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
{
/**
 * Undefined: '!'<br>
 * Boolean: 't' for true 'f' for false<br>
 * Integer: 'i' + 4 bytes network byte order<br>
 * Real: 'r' + 8 bytes IEEE double<br>
 * UUID: 'u' + 16 byte unsigned integer<br>
 * String: 's' + 4 byte integer size + string<br>
 *  strings also secretly support the notation format
 * Date: 'd' + 8 byte IEEE double for seconds since epoch<br>
 * URI: 'l' + 4 byte integer size + string uri<br>
 * Binary: 'b' + 4 byte integer size + binary data<br>
 * Array: '[' + 4 byte integer size  + all values + ']'<br>
 * Map: '{' + 4 byte integer size  every(key + value) + '}'<br>
 *  map keys are serialized as s + 4 byte integer size + string or in the
 *  notation format.
 */
	char c;
	c = get(istr);
	if(!istr.good())
	{
		return 0;
	}
	S32 parse_count = 1;
	switch(c)
	{
	case '{':
	{
		S32 child_count = parseMap(istr, data);
		if((child_count == PARSE_FAILURE) || data.isUndefined())
		{
			parse_count = PARSE_FAILURE;
		}
		else
		{
			parse_count += child_count;
		}
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary map." << llendl;
			parse_count = PARSE_FAILURE;
		}
		break;
	}

	case '[':
	{
		S32 child_count = parseArray(istr, data);
		if((child_count == PARSE_FAILURE) || data.isUndefined())
		{
			parse_count = PARSE_FAILURE;
		}
		else
		{
			parse_count += child_count;
		}
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary array." << llendl;
			parse_count = PARSE_FAILURE;
		}
		break;
	}

	case '!':
		data.clear();
		break;

	case '0':
		data = false;
		break;

	case '1':
		data = true;
		break;

	case 'i':
	{
		U32 value_nbo = 0;
		read(istr, (char*)&value_nbo, sizeof(U32));	 /*Flawfinder: ignore*/
		data = (S32)ntohl(value_nbo);
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary integer." << llendl;
		}
		break;
	}

	case 'r':
	{
		F64 real_nbo = 0.0;
		read(istr, (char*)&real_nbo, sizeof(F64));	 /*Flawfinder: ignore*/
		data = ll_ntohd(real_nbo);
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary real." << llendl;
		}
		break;
	}

	case 'u':
	{
		LLUUID id;
		read(istr, (char*)(&id.mData), UUID_BYTES);	 /*Flawfinder: ignore*/
		data = id;
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary uuid." << llendl;
		}
		break;
	}

	case '\'':
	case '"':
	{
		std::string value;
		int cnt = deserialize_string_delim(istr, value, c);
		if(PARSE_FAILURE == cnt)
		{
			parse_count = PARSE_FAILURE;
		}
		else
		{
			data = value;
			account(cnt);
		}
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary (notation-style) string."
				<< llendl;
			parse_count = PARSE_FAILURE;
		}
		break;
	}

	case 's':
	{
		std::string value;
		if(parseString(istr, value))
		{
			data = value;
		}
		else
		{
			parse_count = PARSE_FAILURE;
		}
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary string." << llendl;
			parse_count = PARSE_FAILURE;
		}
		break;
	}

	case 'l':
	{
		std::string value;
		if(parseString(istr, value))
		{
			data = LLURI(value);
		}
		else
		{
			parse_count = PARSE_FAILURE;
		}
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary link." << llendl;
			parse_count = PARSE_FAILURE;
		}
		break;
	}

	case 'd':
	{
		F64 real = 0.0;
		read(istr, (char*)&real, sizeof(F64));	 /*Flawfinder: ignore*/
		data = LLDate(real);
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary date." << llendl;
			parse_count = PARSE_FAILURE;
		}
		break;
	}

	case 'b':
	{
		// We probably have a valid raw binary stream. determine
		// the size, and read it.
		U32 size_nbo = 0;
		read(istr, (char*)&size_nbo, sizeof(U32));	/*Flawfinder: ignore*/
		S32 size = (S32)ntohl(size_nbo);
		if(mCheckLimits && (size > mMaxBytesLeft))
		{
			parse_count = PARSE_FAILURE;
		}
		else
		{
			std::vector<U8> value;
			if(size > 0)
			{
				value.resize(size);
				account(fullread(istr, (char*)&value[0], size));
			}
			data = value;
		}
		if(istr.fail())
		{
			llinfos << "STREAM FAILURE reading binary." << llendl;
			parse_count = PARSE_FAILURE;
		}
		break;
	}

	default:
		parse_count = PARSE_FAILURE;
		llinfos << "Unrecognized character while parsing: int(" << (int)c
			<< ")" << llendl;
		break;
	}
	if(PARSE_FAILURE == parse_count)
	{
		data.clear();
	}
	return parse_count;
}
예제 #10
0
bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
{
	// binary: b##"ff3120ab1"
	// or: b(len)"..."

	// I want to manually control those values here to make sure the
	// parser doesn't break when someone changes a constant somewhere
	// else.
	const U32 BINARY_BUFFER_SIZE = 256;
	const U32 STREAM_GET_COUNT = 255;

	// need to read the base out.
	char buf[BINARY_BUFFER_SIZE];		/* Flawfinder: ignore */
	get(istr, buf, STREAM_GET_COUNT, '"');
	char c = get(istr);
	if(c != '"') return false;
	if(0 == strncmp("b(", buf, 2))
	{
		// We probably have a valid raw binary stream. determine
		// the size, and read it.
		S32 len = strtol(buf + 2, NULL, 0);
		if(mCheckLimits && (len > mMaxBytesLeft)) return false;
		std::vector<U8> value;
		if(len)
		{
			value.resize(len);
			account(fullread(istr, (char *)&value[0], len));
		}
		c = get(istr); // strip off the trailing double-quote
		data = value;
	}
	else if(0 == strncmp("b64", buf, 3))
	{
		// *FIX: A bit inefficient, but works for now. To make the
		// format better, I would need to add a hint into the
		// serialization format that indicated how long it was.
		std::stringstream coded_stream;
		get(istr, *(coded_stream.rdbuf()), '\"');
		c = get(istr);
		std::string encoded(coded_stream.str());
		S32 len = apr_base64_decode_len(encoded.c_str());
		std::vector<U8> value;
		if(len)
		{
			value.resize(len);
			len = apr_base64_decode_binary(&value[0], encoded.c_str());
			value.resize(len);
		}
		data = value;
	}
	else if(0 == strncmp("b16", buf, 3))
	{
		// yay, base 16. We pop the next character which is either a
		// double quote or base 16 data. If it's a double quote, we're
		// done parsing. If it's not, put the data back, and read the
		// stream until the next double quote.
		char* read;	 /*Flawfinder: ignore*/
		U8 byte;
		U8 byte_buffer[BINARY_BUFFER_SIZE];
		U8* write;
		std::vector<U8> value;
		c = get(istr);
		while(c != '"')
		{
			putback(istr, c);
			read = buf;
			write = byte_buffer;
			get(istr, buf, STREAM_GET_COUNT, '"');
			c = get(istr);
			while(*read != '\0')	 /*Flawfinder: ignore*/
			{
				byte = hex_as_nybble(*read++);
				byte = byte << 4;
				byte |= hex_as_nybble(*read++);
				*write++ = byte;
			}
			// copy the data out of the byte buffer
			value.insert(value.end(), byte_buffer, write);
		}
		data = value;
	}
	else
	{
		return false;
	}
	return true;
}
예제 #11
0
파일: parent.c 프로젝트: hmatyschok/MeshBSD
/*
 * Read a single kpair from the child.
 * This returns 0 if there are no more pairs to read and -1 if any
 * errors occur (the parent should also exit with server failure).
 * Otherwise, it returns 1 and the pair is zeroed and filled in.
 */
static int
input(enum input *type, struct kpair *kp, 
	int fd, enum kcgi_err *ke, int eofok)
{
	size_t		 sz;
	int		 rc;
	ptrdiff_t	 diff;

	memset(kp, 0, sizeof(struct kpair));

	/* This will return EOF for the last one. */
	rc = fullread(fd, type, sizeof(enum input), 1, ke);
	if (0 == rc) {
		if (eofok) 
			return(0);
		XWARNX("unexpected eof from child");
		*ke = KCGI_FORM;
		return(-1);
	} else if (rc < 0)
		return(-1);

	if (*type == IN__MAX)
		return(0);

	if (*type > IN__MAX) {
		XWARNX("unknown input type %d", *type);
		*ke = KCGI_FORM;
		return(-1);
	}

	/* TODO: check additive overflow. */
	if (fullread(fd, &sz, sizeof(size_t), 0, ke) < 0)
		return(-1);
	if (NULL == (kp->key = XCALLOC(sz + 1, 1))) {
		*ke = KCGI_ENOMEM;
		return(-1);
	}
	if (fullread(fd, kp->key, sz, 0, ke) < 0)
		return(-1);

	/* TODO: check additive overflow. */
	if (fullread(fd, &kp->valsz, sizeof(size_t), 0, ke) < 0)
		return(-1);
	if (NULL == (kp->val = XCALLOC(kp->valsz + 1, 1))) {
		*ke = KCGI_ENOMEM;
		return(-1);
	}
	if (fullread(fd, kp->val, kp->valsz, 0, ke) < 0)
		return(-1);

	if (fullread(fd, &kp->state, sizeof(enum kpairstate), 0, ke) < 0)
		return(-1);
	if (fullread(fd, &kp->type, sizeof(enum kpairtype), 0, ke) < 0)
		return(-1);
	if (fullread(fd, &kp->keypos, sizeof(size_t), 0, ke) < 0)
		return(-1);

	if (KPAIR_VALID == kp->state)
		switch (kp->type) {
		case (KPAIR_DOUBLE):
			if (fullread(fd, &kp->parsed.d, sizeof(double), 0, ke) < 0)
				return(-1);
			break;
		case (KPAIR_INTEGER):
			if (fullread(fd, &kp->parsed.i, sizeof(int64_t), 0, ke) < 0)
				return(-1);
			break;
		case (KPAIR_STRING):
			if (fullread(fd, &diff, sizeof(ptrdiff_t), 0, ke) < 0)
				return(-1);
			if (diff > (ssize_t)kp->valsz) {
				*ke = KCGI_FORM;
				return(-1);
			}
			kp->parsed.s = kp->val + diff;
			break;
		default:
			break;
		}

	/* TODO: check additive overflow. */
	if (fullread(fd, &sz, sizeof(size_t), 0, ke) < 0)
		return(-1);
	if (NULL == (kp->file = XCALLOC(sz + 1, 1))) {
		*ke = KCGI_ENOMEM;
		return(-1);
	}
	if (fullread(fd, kp->file, sz, 0, ke) < 0)
		return(-1);

	/* TODO: check additive overflow. */
	if (fullread(fd, &sz, sizeof(size_t), 0, ke) < 0)
		return(-1);
	if (NULL == (kp->ctype = XCALLOC(sz + 1, 1))) {
		*ke = KCGI_ENOMEM;
		return(-1);
	}
	if (fullread(fd, kp->ctype, sz, 0, ke) < 0)
		return(-1);
	if (fullread(fd, &kp->ctypepos, sizeof(size_t), 0, ke) < 0)
		return(-1);

	/* TODO: check additive overflow. */
	if (fullread(fd, &sz, sizeof(size_t), 0, ke) < 0)
		return(-1);
	if (NULL == (kp->xcode = XCALLOC(sz + 1, 1)))  {
		*ke = KCGI_ENOMEM;
		return(-1);
	}
	if (fullread(fd, kp->xcode, sz, 0, ke) < 0) 
		return(-1);

	return(1);
}
예제 #12
0
파일: parent.c 프로젝트: hmatyschok/MeshBSD
/*
 * This is the parent kcgi process.
 * It spins on input from the child until all fields have been received.
 * These fields are sent from the child's output() function.
 * Each input field consists of the data and its validation state.
 * We build up the kpair arrays here with this data, then assign the
 * kpairs into named buckets.
 */
enum kcgi_err
kworker_parent(int fd, struct kreq *r, int eofok)
{
	struct kpair	 kp;
	struct kpair	*kpp;
	enum krequ	 requ;
	enum input	 type;
	int		 rc;
	enum kcgi_err	 ke;
	size_t		 i, dgsz;

	/* Pointers freed at "out" label. */
	memset(&kp, 0, sizeof(struct kpair));

	/*
	 * First read all of our parsed parameters.
	 * Each parsed parameter is handled a little differently.
	 * This list will end with META__MAX.
	 */
	if (fullread(fd, &r->reqsz, sizeof(size_t), 0, &ke) < 0) {
		XWARNX("failed to read request header size");
		goto out;
	}
	r->reqs = XCALLOC(r->reqsz, sizeof(struct khead));
	if (NULL == r->reqs) {
		ke = KCGI_ENOMEM;
		goto out;
	}
	for (i = 0; i < r->reqsz; i++) {
		if (fullread(fd, &requ, sizeof(enum krequ), 0, &ke) < 0) {
			XWARNX("failed to read request identifier");
			goto out;
		}
		if (KCGI_OK != (ke = fullreadword(fd, &r->reqs[i].key))) {
			XWARNX("failed to read request key");
			goto out;
		}
		if (KCGI_OK != (ke = fullreadword(fd, &r->reqs[i].val))) {
			XWARNX("failed to read request value");
			goto out;
		}
		if (requ != KREQU__MAX)
			r->reqmap[requ] = &r->reqs[i];
	}

	if (fullread(fd, &r->method, sizeof(enum kmethod), 0, &ke) < 0) {
		XWARNX("failed to read request method");
		goto out;
	} else if (fullread(fd, &r->auth, sizeof(enum kauth), 0, &ke) < 0) {
		XWARNX("failed to read authorisation type");
		goto out;
	} else if (KCGI_OK != (ke = kworker_auth_parent(fd, &r->rawauth))) {
		XWARNX("failed to read raw authorisation");
		goto out;
	} else if (fullread(fd, &r->scheme, sizeof(enum kscheme), 0, &ke) < 0) {
		XWARNX("failed to read scheme");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->remote))) {
		XWARNX("failed to read remote");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->fullpath))) {
		XWARNX("failed to read fullpath");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->suffix))) {
		XWARNX("failed to read suffix");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->pagename))) {
		XWARNX("failed to read page part");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->path))) {
		XWARNX("failed to read path part");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->pname))) {
		XWARNX("failed to read script name");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->host))) {
		XWARNX("failed to read host name");
		goto out;
	} else if (fullread(fd, &r->port, sizeof(uint16_t), 0, &ke) < 0) {
		XWARNX("failed to read port");
		goto out;
	} else if (fullread(fd, &dgsz, sizeof(size_t), 0, &ke) < 0) {
		XWARNX("failed to read digest length");
		goto out;
	} else if (MD5_DIGEST_LENGTH == dgsz) {
		/* This is a binary value. */
		if (NULL == (r->rawauth.digest = XMALLOC(dgsz)))
			goto out;
		if (fullread(fd, r->rawauth.digest, dgsz, 0, &ke) < 0) {
			XWARNX("failed to read digest");
			goto out;
		}
	}

	while ((rc = input(&type, &kp, fd, &ke, eofok)) > 0) {
		assert(type < IN__MAX);
		/*
		 * We have a parsed field from the child process.
		 * Begin by expanding the number of parsed fields
		 * depending on whether we have a cookie or form input.
		 * Then copy the new data.
		 */
		kpp = IN_COOKIE == type ?
			kpair_expand(&r->cookies, &r->cookiesz) :
			kpair_expand(&r->fields, &r->fieldsz);

		if (NULL == kpp) {
			rc = -1;
			ke = KCGI_ENOMEM;
			break;
		}

		*kpp = kp;
	}

	if (rc < 0)
		goto out;

	/*
	 * Now that the field and cookie arrays are fixed and not going
	 * to be reallocated any more, we run through both arrays and
	 * assign the named fields into buckets.
	 */
	for (i = 0; i < r->fieldsz; i++) {
		kpp = &r->fields[i];
		if (kpp->keypos == r->keysz)
			continue;
		if (KPAIR_INVALID != kpp->state) {
			kpp->next = r->fieldmap[kpp->keypos];
			r->fieldmap[kpp->keypos] = kpp;
		} else {
			kpp->next = r->fieldnmap[kpp->keypos];
			r->fieldnmap[kpp->keypos] = kpp;
		}
	}
	for (i = 0; i < r->cookiesz; i++) {
		kpp = &r->cookies[i];
		if (kpp->keypos == r->keysz)
			continue;
		if (KPAIR_INVALID != kpp->state) {
			kpp->next = r->cookiemap[kpp->keypos];
			r->cookiemap[kpp->keypos] = kpp;
		} else {
			kpp->next = r->cookienmap[kpp->keypos];
			r->cookienmap[kpp->keypos] = kpp;
		}
	}

	ke = KCGI_OK;
	/*
	 * Usually, "kp" would be zeroed after its memory is copied into
	 * one of the form-input arrays.
	 * However, in the case of error, these may still have
	 * allocations, so free them now.
	 */
out:
	free(kp.key);
	free(kp.val);
	free(kp.file);
	free(kp.ctype);
	free(kp.xcode);
	return(ke);
}
예제 #13
0
static void* daemon_main(void *param)
{
	struct daemon_thread	*dt;
	struct dazuko_request	request;
	char reqdesc[64];
	long long ptr_num;
	struct xp_daemon_id	xp_id;

	dt = (struct daemon_thread *)param;

	while (1)
	{
		if (fullread(dt->fd, &request, sizeof(request)) != 0)
			break;

		request.buffer = NULL;
		request.reply_buffer = NULL;

		if (request.buffer_size > 0)
		{
			request.buffer = (char *)malloc(request.buffer_size);
			if (request.buffer == NULL)
				break;

			if (fullread(dt->fd, request.buffer, request.buffer_size) != 0)
				break;
		}

		if (request.reply_buffer_size > 0)
		{
			request.reply_buffer = (char *)malloc(request.reply_buffer_size);
			if (request.reply_buffer == NULL)
				break;

			if (fullread(dt->fd, request.reply_buffer, request.reply_buffer_size) != 0)
				break;
		}

		/* we now have the full request from the daemon */

		xp_id.id = dt->fd;

		memset(reqdesc, 0, sizeof(reqdesc));
		snprintf(reqdesc, sizeof(reqdesc), "%p", &request);
		ptr_num = strtoll(reqdesc, NULL, 16);
		snprintf(reqdesc, sizeof(reqdesc), "\nRA=%lld", (long long)ptr_num);
		if (dazuko_handle_user_request(reqdesc, &xp_id) != 0)
			break;

		/* we now have the request response */

		if (fullwrite(dt->fd, &request, sizeof(request)) != 0)
			break;

		if (request.buffer_size > 0)
		{
			if (fullwrite(dt->fd, request.buffer, request.buffer_size) != 0)
				break;
		}

		if (request.reply_buffer_size > 0)
		{
			if (fullwrite(dt->fd, request.reply_buffer, request.reply_buffer_size) != 0)
				break;
		}

		if (request.buffer != NULL)
			free(request.buffer);

		if (request.reply_buffer != NULL)
			free(request.reply_buffer);
	}

	close(dt->fd);

	return NULL;
}