コード例 #1
0
ファイル: sock.c プロジェクト: vonnyfly/http_server_for_wince
int	socketGets(int sid, char_t **buf)
{
    socket_t	*sp;
    ringq_t		*lq;
    char		c;
    int			rc, len;

    a_assert(buf);
    *buf = NULL;

    if ((sp = socketPtr(sid)) == NULL) {
        return -1;
    }
    lq = &sp->lineBuf;

    while (1) {

        if ((rc = socketRead(sid, &c, 1)) < 0) {
            return rc;
        }

        if (rc == 0) {
            /*
             *			If there is a partial line and we are at EOF, pretend we saw a '\n'
             */
            if (ringqLen(lq) > 0 && (sp->flags & SOCKET_EOF)) {
                c = '\n';
            } else {
                return -1;
            }
        }
        /*
         * 		Validate length of request.  Ignore long strings without newlines to
         * 		safeguard against long URL attacks.
         */
        if (ringqLen(lq) > E_MAX_REQUEST) {
            c = '\n';
        }
        /*
         *		If a newline is seen, return the data excluding the new line to the
         *		caller. If carriage return is seen, just eat it.
         */
        if (c == '\n') {
            len = ringqLen(lq);
            if (len > 0) {
                *buf = ballocAscToUni((char *)lq->servp, len);
            } else {
                *buf = NULL;
            }
            ringqFlush(lq);
            return len;

        } else if (c == '\r') {
            continue;
        }
        ringqPutcA(lq, c);
    }
    return 0;
}
コード例 #2
0
ファイル: ringq.c プロジェクト: BackupGGCode/faceaip
void ringqClose(ringq_t *rq)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (rq == NULL) {
		return;
	}

	ringqFlush(rq);
	bfree(B_L, (char*) rq->buf);
	rq->buf = NULL;
}
コード例 #3
0
ファイル: sock.c プロジェクト: sd-eblana/bawx
int socketFlush(int sid)
{
	socket_t	*sp;
	ringq_t		*rq;
	int			len, bytesWritten, errCode;

	if ((sp = socketPtr(sid)) == NULL) {
		return -1;
	}
	rq = &sp->outBuf;

/*
 *	Set the background flushing flag which socketEventProc will check to
 *	continue the flush.
 */
	if (! (sp->flags & SOCKET_BLOCK)) {
		sp->flags |= SOCKET_FLUSHING;
	}

/*
 *	Break from loop if not blocking after initiating output. If we are blocking
 *	we wait for a write event.
 */
	while (ringqLen(rq) > 0) {
		len = ringqGetBlkMax(&sp->outBuf);
		bytesWritten = socketDoOutput(sp, (char*) rq->servp, len, &errCode);
		if (bytesWritten < 0) {
			if (errCode == EINTR) {
				continue;
			} else if (errCode == EWOULDBLOCK || errCode == EAGAIN) {
#if (defined (WIN) || defined (CE))
				if (sp->flags & SOCKET_BLOCK) {
					int		errCode;
					if (! socketWaitForEvent(sp,  FD_WRITE | SOCKET_WRITABLE,
						&errCode)) {
						return -1;
					}
					continue;
				} 
#endif
/*
 *				Ensure we get a FD_WRITE message when the socket can absorb
 *				more data (non-blocking only.) Store the user's mask if we
 *				haven't done it already.
 */
				if (sp->saveMask < 0 ) {
					sp->saveMask = sp->handlerMask;
					socketRegisterInterest(sp, 
					sp->handlerMask | SOCKET_WRITABLE);
				}
				return 0;
			}
			return -1;
		}
		ringqGetBlkAdj(rq, bytesWritten);
	}
/*
 *	If the buffer is empty, reset the ringq pointers to point to the start
 *	of the buffer. This is essential to ensure that datagrams get written
 *	in one single I/O operation.
 */
	if (ringqLen(rq) == 0) {
		ringqFlush(rq);
	}
/*
 *	Restore the users mask if it was saved by the non-blocking code above.
 *	Note: saveMask = -1 if empty. socketRegisterInterest will set handlerMask
 */
	if (sp->saveMask >= 0) {
		socketRegisterInterest(sp, sp->saveMask);
		sp->saveMask = -1;
	}
	sp->flags &= ~SOCKET_FLUSHING;
	return 0;
}
コード例 #4
0
ファイル: sock.c プロジェクト: sd-eblana/bawx
int	socketRead(int sid, char *buf, int bufsize)
{
	socket_t	*sp;
	ringq_t		*rq;
	int			len, room, errCode, bytesRead;

	a_assert(buf);
	a_assert(bufsize > 0);

	if ((sp = socketPtr(sid)) == NULL) {
		return -1;
	}

	if (sp->flags & SOCKET_EOF) {
		return 0;
	}

	rq = &sp->inBuf;
	for (bytesRead = 0; bufsize > 0; ) {
		len = min(ringqLen(rq), bufsize);
		if (len <= 0) {
/*
 *			if blocking mode and already have data, exit now or it may block
 *			forever.
 */
			if ((sp->flags & SOCKET_BLOCK) &&
				(bytesRead > 0)) {
				break;
			}
/*
 *			This flush is critical for readers of datagram packets. If the
 *			buffer is not big enough to read the whole datagram in one hit,
 *			the recvfrom call will fail. 
 */
			ringqFlush(rq);
			room = ringqPutBlkMax(rq);
			len = socketGetInput(sid, (char *) rq->endp, room, &errCode);
			if (len < 0) {
				if (errCode == EWOULDBLOCK) {
					if ((sp->flags & SOCKET_BLOCK) &&
						(bytesRead ==  0)) {
						continue;
					}
					if (bytesRead >= 0) {
						return bytesRead;
					}
				}
				return -1;

			} else if (len == 0) {
/*
 *				If bytesRead is 0, this is EOF since socketRead should never
 *				be called unless there is data yet to be read.  Set the flag.  
 *				Then pass back the number of bytes read.
 */
				if (bytesRead == 0) {
					sp->flags |= SOCKET_EOF;
				}
				return bytesRead;
			}
			ringqPutBlkAdj(rq, len);
			len = min(len, bufsize);
		}
		memcpy(&buf[bytesRead], rq->servp, len);
		ringqGetBlkAdj(rq, len);
		bufsize -= len;
		bytesRead += len;
	}
	return bytesRead;
}
コード例 #5
0
static int getLexicalToken(ej_t* ep, int state)
{
    ringq_t		*inq, *tokq;
    ejinput_t*	ip;
    int			done, tid, c, quote, style;

    a_assert(ep);
    ip = ep->input;
    a_assert(ip);

    inq = &ip->script;
    tokq = &ip->tokbuf;

    ep->tid = -1;
    tid = -1;
    ep->token = T("");

    ringqFlush(tokq);

    if (ip->putBackTokenId > 0) {
        ringqPutStr(tokq, ip->putBackToken);
        tid = ip->putBackTokenId;
        ip->putBackTokenId = 0;
        ep->token = (char_t*) tokq->servp;
        return tid;
    }

    if ((c = inputGetc(ep)) < 0) {
        return TOK_EOF;
    }

    for (done = 0; !done; ) {
        switch (c) {
        case -1:
            return TOK_EOF;

        case ' ':
        case '\t':
        case '\r':
            do {
                if ((c = inputGetc(ep)) < 0)
                    break;
            } while (c == ' ' || c == '\t' || c == '\r');
            break;

        case '\n':
            return TOK_NEWLINE;

        case '(':
            tokenAddChar(ep, c);
            return TOK_LPAREN;

        case ')':
            tokenAddChar(ep, c);
            return TOK_RPAREN;

        case '{':
            tokenAddChar(ep, c);
            return TOK_LBRACE;

        case '}':
            tokenAddChar(ep, c);
            return TOK_RBRACE;

        case '+':
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c != '+' ) {
                inputPutback(ep, c);
                tokenAddChar(ep, EXPR_PLUS);
                return TOK_EXPR;
            }
            tokenAddChar(ep, EXPR_INC);
            return TOK_INC_DEC;

        case '-':
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c != '-' ) {
                inputPutback(ep, c);
                tokenAddChar(ep, EXPR_MINUS);
                return TOK_EXPR;
            }
            tokenAddChar(ep, EXPR_DEC);
            return TOK_INC_DEC;

        case '*':
            tokenAddChar(ep, EXPR_MUL);
            return TOK_EXPR;

        case '%':
            tokenAddChar(ep, EXPR_MOD);
            return TOK_EXPR;

        case '/':
            /*
             *			Handle the division operator and comments
             */
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c != '*' && c != '/') {
                inputPutback(ep, c);
                tokenAddChar(ep, EXPR_DIV);
                return TOK_EXPR;
            }
            style = c;
            /*
             *			Eat comments. Both C and C++ comment styles are supported.
             */
            while (1) {
                if ((c = inputGetc(ep)) < 0) {
                    ejError(ep, T("Syntax Error"));
                    return TOK_ERR;
                }
                if (c == '\n' && style == '/') {
                    break;
                } else if (c == '*') {
                    c = inputGetc(ep);
                    if (style == '/') {
                        if (c == '\n') {
                            break;
                        }
                    } else {
                        if (c == '/') {
                            break;
                        }
                    }
                }
            }
            /*
             *			Continue looking for a token, so get the next character
             */
            if ((c = inputGetc(ep)) < 0) {
                return TOK_EOF;
            }
            break;

        case '<':									/* < and <= */
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c == '<') {
                tokenAddChar(ep, EXPR_LSHIFT);
                return TOK_EXPR;
            } else if (c == '=') {
                tokenAddChar(ep, EXPR_LESSEQ);
                return TOK_EXPR;
            }
            tokenAddChar(ep, EXPR_LESS);
            inputPutback(ep, c);
            return TOK_EXPR;

        case '>':									/* > and >= */
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c == '>') {
                tokenAddChar(ep, EXPR_RSHIFT);
                return TOK_EXPR;
            } else if (c == '=') {
                tokenAddChar(ep, EXPR_GREATEREQ);
                return TOK_EXPR;
            }
            tokenAddChar(ep, EXPR_GREATER);
            inputPutback(ep, c);
            return TOK_EXPR;

        case '=':									/* "==" */
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c == '=') {
                tokenAddChar(ep, EXPR_EQ);
                return TOK_EXPR;
            }
            inputPutback(ep, c);
            return TOK_ASSIGNMENT;

        case '!':									/* "!=" or "!"*/
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            if (c == '=') {
                tokenAddChar(ep, EXPR_NOTEQ);
                return TOK_EXPR;
            }
            inputPutback(ep, c);
            tokenAddChar(ep, EXPR_BOOL_COMP);
            return TOK_EXPR;

        case ';':
            tokenAddChar(ep, c);
            return TOK_SEMI;

        case ',':
            tokenAddChar(ep, c);
            return TOK_COMMA;

        case '|':									/* "||" */
            if ((c = inputGetc(ep)) < 0 || c != '|') {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            tokenAddChar(ep, COND_OR);
            return TOK_LOGICAL;

        case '&':									/* "&&" */
            if ((c = inputGetc(ep)) < 0 || c != '&') {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }
            tokenAddChar(ep, COND_AND);
            return TOK_LOGICAL;

        case '\"':									/* String quote */
        case '\'':
            quote = c;
            if ((c = inputGetc(ep)) < 0) {
                ejError(ep, T("Syntax Error"));
                return TOK_ERR;
            }

            while (c != quote) {
                /*
                 *				check for escape sequence characters
                 */
                if (c == '\\') {
                    c = inputGetc(ep);

                    if (gisdigit(c)) {
                        /*
                         *						octal support, \101 maps to 65 = 'A'. put first char
                         *						back so converter will work properly.
                         */
                        inputPutback(ep, c);
                        c = charConvert(ep, OCTAL, 3);

                    } else {
                        switch (c) {
                        case 'n':
                            c = '\n';
                            break;
                        case 'b':
                            c = '\b';
                            break;
                        case 'f':
                            c = '\f';
                            break;
                        case 'r':
                            c = '\r';
                            break;
                        case 't':
                            c = '\t';
                            break;
                        case 'x':
                            /*
                             *							hex support, \x41 maps to 65 = 'A'
                             */
                            c = charConvert(ep, HEX, 2);
                            break;
                        case 'u':
                            /*
                             *							unicode support, \x0401 maps to 65 = 'A'
                             */
                            c = charConvert(ep, HEX, 2);
                            c = c*16 + charConvert(ep, HEX, 2);

                            break;
                        case '\'':
                        case '\"':
                        case '\\':
                            break;
                        default:
                            ejError(ep, T("Invalid Escape Sequence"));
                            return TOK_ERR;
                        }
                    }
                    if (tokenAddChar(ep, c) < 0) {
                        return TOK_ERR;
                    }
                } else {
                    if (tokenAddChar(ep, c) < 0) {
                        return TOK_ERR;
                    }
                }
                if ((c = inputGetc(ep)) < 0) {
                    ejError(ep, T("Unmatched Quote"));
                    return TOK_ERR;
                }
            }
            return TOK_LITERAL;

        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            do {
                if (tokenAddChar(ep, c) < 0) {
                    return TOK_ERR;
                }
                if ((c = inputGetc(ep)) < 0)
                    break;
            } while (gisdigit(c));
            inputPutback(ep, c);
            return TOK_LITERAL;

        default:
            /*
             *			Identifiers or a function names
             */
            while (1) {
                if (c == '\\') {
                    /*
                     *					just ignore any \ characters.
                     */
                } else if (tokenAddChar(ep, c) < 0) {
                    break;
                }
                if ((c = inputGetc(ep)) < 0) {
                    break;
                }
                if (!gisalnum(c) && c != '$' && c != '_' &&
                    c != '\\') {
                    break;
                }
            }
            if (! gisalpha(*tokq->servp) && *tokq->servp != '$' &&
                *tokq->servp != '_') {
                ejError(ep, T("Invalid identifier %s"), tokq->servp);
                return TOK_ERR;
            }
            /*
             *			Check for reserved words (only "if", "else", "var", "for"
             *			and "return" at the moment)
             */
            if (state == STATE_STMT) {
                if (gstrcmp(ep->token, T("if")) == 0) {
                    return TOK_IF;
                } else if (gstrcmp(ep->token, T("else")) == 0) {
                    return TOK_ELSE;
                } else if (gstrcmp(ep->token, T("var")) == 0) {
                    return TOK_VAR;
                } else if (gstrcmp(ep->token, T("for")) == 0) {
                    return TOK_FOR;
                } else if (gstrcmp(ep->token, T("return")) == 0) {
                    if ((c == ';') || (c == '(')) {
                        inputPutback(ep, c);
                    }
                    return TOK_RETURN;
                }
            }

            /*
             * 			Skip white space after token to find out whether this is
             * 			a function or not.
             */
            while (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
                if ((c = inputGetc(ep)) < 0)
                    break;
            }

            tid = (c == '(') ? TOK_FUNCTION : TOK_ID;
            done++;
        }
    }

    /*
     *	Putback the last extra character for next time
     */
    inputPutback(ep, c);
    return tid;
}