Exemple #1
0
static int scan_identifier(void) {
	struct buffer buf;
	
	/* for the first char, no numbers are allowed */
	if(isalpha(*src) || *src == '_') {
		buffer_init(&buf);
		buffer_add_char(&buf, *src);
	}
	else
		return 0;
	++yylloc.last_column;
	++src;
	
	while(IDENTIFIER_CHAR(*src)) {
		buffer_add_char(&buf, *src);
		++yylloc.last_column;
		++src;
	}
	buffer_add_char(&buf, 0);
	
	yylval.identifier = buf.data;
#ifdef DEBUG
	printf("yylex returns identifier %s\n", yylval.identifier);
#endif
	
	return IDENTIFIER;
}
Exemple #2
0
Fichier : lex.c Projet : zayac/pipo
/* Internal function to read until the end of identifier, checking
   if it is a keyword.  */
static inline void
lexer_read_id (struct lexer *lex, struct token *tok,
               char **buf, size_t *size, char c)
{
  char *index = *buf;
  size_t search;

  do 
    {
      buffer_add_char (buf, &index, size, c);
      c = lexer_getch (lex);
    }
  while (isalnum (c) || c == '_');
  lexer_ungetch (lex, c);
  buffer_add_char (buf, &index, size, 0);

  search = kw_bsearch (*buf, keywords, keywords_length);
  if (search != keywords_length)
    {
      if (*buf)
        free (*buf);
      *size = 0;
      *buf = NULL;
      tval_tok_init (tok, tok_keyword, (enum token_kind)(search + tv_function));
      return;
    }
  tok->tok_class = tok_id;
  return;
}
Exemple #3
0
static int scan_string(void) {
	char new_char;
	struct buffer buf;
	
	if(*src != '"')
		return 0;
	
	buffer_init(&buf);
	++yylloc.last_column;
	++src;
	
	while(*src != '"') {
		if(*src == 0) {
			string_does_not_end:
			location_error(yylloc, "String does not end");
		}
		
		if(*src == '\\') {
			++yylloc.last_column;
			++src;
			if(*src == 0)
				goto string_does_not_end;
			if(*src == '\n') { /* backslash newline means ignore newline */
				++yylloc.last_line;
				yylloc.last_column = 1;
				++src;
				continue;
			}
			
			new_char = slash_char(*src);
		}
		else
			new_char = *src;
		
		buffer_add_char(&buf, new_char);
		if(*src == '\n') {
			++yylloc.last_line;
			yylloc.last_column = 1;
		}
		else
			++yylloc.last_column;
		++src;
	}
	
	buffer_add_char(&buf, 0);
	yylval.string = buf.data;
	
#ifdef DEBUG
	printf("yylex returns \"%s\"\n", yylval.string);
#endif
	
	++yylloc.last_column;
	++src; /* now src points to the char after the " */
	return STRING;
}
/**
	@brief Add a message to an output buffer.
	@param outbuf Pointer to the output buffer.
	@param msg Pointer to the message to be added, in the form of a JSON string.

	Since the output buffer is in the form of a JSON array, prepend a left bracket to the
	first message, and a comma to subsequent ones.

	Used only by servers to respond to clients.
*/
static inline void append_msg( growing_buffer* outbuf, const char* msg ) {
	if( outbuf && msg ) {
		char prefix = buffer_length( outbuf ) > 0 ? ',' : '[';
		buffer_add_char( outbuf, prefix );
		buffer_add( outbuf, msg );
	}
}
Exemple #5
0
void net_connect(net *n, buffer *b, int c)
{
  b->size = 0;
  buffer_add_string(b, "s=");
  buffer_add_string(b, n->session);
  buffer_add_char(b, 0);
  net_post(n, c, b,
           "https://webchat.freenode.net/dynamic/test/e/s",
           b->data);
}
Exemple #6
0
void buffer_add_cchar(buffer *b, int c)
{
  char t[32];
  if (isunreserved(c))
    buffer_add_char(b, c);
  else {
    sprintf(t, "%%%02X", (unsigned char)c);
    buffer_add_string(b, t);
  }
}
Exemple #7
0
Fichier : lex.c Projet : zayac/pipo
/* Function to read a hex number */
static inline void
lexer_read_octal_number (struct lexer *lex, struct token *tok, char **buf,
		       size_t * size, char c)
{
  char *index = *buf;

  assert (c == '0', "a character must be '0'");
  buffer_add_char (buf, &index, size, c);
  do
    {
      buffer_add_char (buf, &index, size, c);
      c = lexer_getch (lex);
    }
  while (c >= '0' && c < '8');

  lexer_ungetch (lex, c);
  buffer_add_char (buf, &index, size, 0);
  tok->tok_class = tok_octnum;
  tok->uses_buf = true;
}
Exemple #8
0
Fichier : lex.c Projet : zayac/pipo
/* Internal function to read until the end of comment.  */
static inline enum token_class
lexer_read_comments (struct lexer *lex, char **buf, size_t * size)
{
  char *index = *buf;

  while (true)
    {
      char c = lexer_getch (lex);

      if (c == EOF)
	break;

      if (c == '\n')
	break;

      buffer_add_char (buf, &index, size, c);
    }

  buffer_add_char (buf, &index, size, '\0');
  return tok_comments;
}
Exemple #9
0
Fichier : lex.c Projet : zayac/pipo
/* Function to read a hex number */
static inline void
lexer_read_hex_number (struct lexer *lex, struct token *tok, char **buf,
		       size_t * size, char c)
{
  char *index = *buf;

  assert (c == '0', "a character must be '0', '%c' found", c);
  buffer_add_char (buf, &index, size, c);
  c = lexer_getch (lex);
  assert (c == 'x' || c == 'X', "a character must be 'x' or 'X', '%c' found", c);
  do
    {
      buffer_add_char (buf, &index, size, c);
      c = lexer_getch (lex);
    }
  while (isxdigit (c));

  lexer_ungetch (lex, c);
  buffer_add_char (buf, &index, size, 0);
  tok->tok_class = tok_hexnum;
  tok->uses_buf = true;
}
Exemple #10
0
void buffer_add_cstring(buffer *b, const char *c)
{
  char t[32];
  while (*c) {
    if (isunreserved(*c))
      buffer_add_char(b, *c);
    else {
      sprintf(t, "%%%02X", (unsigned char)*c);
      buffer_add_string(b, t);
    }
    c++;
  }
}
Exemple #11
0
static char* _escape_xml (const char* text) {
	growing_buffer* b = buffer_init(256);
	int len = strlen(text);
	int i;
	for (i = 0; i < len; i++) {
		if (text[i] == '&')
			buffer_add(b,"&amp;");
		else if (text[i] == '<')
			buffer_add(b,"&lt;");
		else if (text[i] == '>')
			buffer_add(b,"&gt;");
		else
			buffer_add_char(b,text[i]);
	}
	return buffer_release(b);
}
/**
	@brief Send any response messages that have accumulated in the output buffer.
	@param ses Pointer to the current application session.
	@param outbuf Pointer to the output buffer.
	@return Zero if successful, or -1 if not.

	Used only by servers to respond to clients.
*/
static int flush_responses( osrfAppSession* ses, growing_buffer* outbuf ) {

	// Collect any inbound traffic on the socket(s).  This doesn't accomplish anything for the
	// immediate task at hand, but it may help to keep TCP from getting clogged in some cases.
	osrf_app_session_queue_wait( ses, 0, NULL );

	int rc = 0;
	if( buffer_length( outbuf ) > 0 ) {    // If there's anything to send...
		buffer_add_char( outbuf, ']' );    // Close the JSON array
		if( osrfSendTransportPayload( ses, OSRF_BUFFER_C_STR( ses->outbuf ))) {
			osrfLogError( OSRF_LOG_MARK, "Unable to flush response buffer" );
			rc = -1;
		}
	}
	buffer_reset( ses->outbuf );
	return rc;
}
Exemple #13
0
Fichier : lex.c Projet : zayac/pipo
/* Internal function to read until the end of string/char ignoring
escape sequences. */
static inline enum token_class
lexer_read_string (struct lexer *lex, char **buf, size_t * size, char c)
{
  char *index = *buf;
  const char stop = c;

  assert (stop == '"', "inapproriate starting symbol for string or char");

  buffer_add_char (buf, &index, size, stop);

  while (true)
    {
      c = lexer_getch (lex);
      if (c == EOF)
	{
	  if (lex->error_notifications)
	    error_loc (lex->loc,
		       "unexpected end of file in the middle of string");
	  buffer_add_char (buf, &index, size, 0);
	  return tok_unknown;
	}

      buffer_add_char (buf, &index, size, c);
      if (c == '\\')
	{
	  char cc = lexer_getch (lex);
	  if (cc == EOF)
	    {
	      if (lex->error_notifications)
		error_loc (lex->loc,
			   "unexpected end of file in the middle of string");
	      buffer_add_char (buf, &index, size, 0);
	      return tok_unknown;
	    }
	  buffer_add_char (buf, &index, size, cc);
	}
      else if (c == stop)
	break;
    }

  buffer_add_char (buf, &index, size, 0);
  return tok_string;
}
Exemple #14
0
Fichier : lex.c Projet : zayac/pipo
/* Internal function to read until the end of number.  */
static inline enum token_class
lexer_read_number (struct lexer *lex, char **buf, size_t * size, char c)
{
  bool isreal = false;
  bool saw_dot = false;
  bool saw_exp = false;
  char *index = *buf;

  buffer_add_char (buf, &index, size, c);

  if (c == '.')
    {
      isreal = true;
      saw_dot = true;

      c = lexer_getch (lex);

      if (!isdigit (c))
	{
	  if (lex->error_notifications)
	    error_loc (lex->loc, "digit expected, '%c' found instead", c);
	  lexer_ungetch (lex, c);
	  goto return_unknown;
	}
      else
	buffer_add_char (buf, &index, size, c);
    }

  while (true)
    {
      c = lexer_getch (lex);
      if (c == EOF)
	{
	  if (lex->error_notifications)
	    error_loc (lex->loc, "unexpected end of file");
	  goto return_unknown;
	}
      else if (c == 'e' || c == 'E')
	{
	  if (saw_exp)
	    {
	      if (lex->error_notifications)
		error_loc (lex->loc, "exponent is specified more than once");
	      goto return_unknown;
	    }
	  isreal = true;

	  buffer_add_char (buf, &index, size, c);
	  c = lexer_getch (lex);

	  if (c == '+' || c == '-')
	    {
	      buffer_add_char (buf, &index, size, c);
	      c = lexer_getch (lex);
	    }

	  if (!isdigit (c))
	    {
	      if (lex->error_notifications)
		error_loc (lex->loc, "digit expected after exponent sign");
	      goto return_unknown;
	    }
	  else
	    buffer_add_char (buf, &index, size, c);

	  while (isdigit (c = lexer_getch (lex)))
	    buffer_add_char (buf, &index, size, c);

	  break;
	}
      else if (c == '.')
	{
	  if (saw_dot)
	    {
	      if (lex->error_notifications)
		error_loc (lex->loc, "more than one dot in the number ");
	      goto return_unknown;
	    }
	  saw_dot = true;
	  isreal = true;
	}
      else if (!isdigit (c))
	break;

      buffer_add_char (buf, &index, size, c);
    }
  lexer_ungetch (lex, c);
  buffer_add_char (buf, &index, size, 0);

  if (isreal)
    return tok_realnum;
  else
    return tok_intnum;

return_unknown:
  buffer_add_char (buf, &index, size, 0);
  return tok_unknown;
}
Exemple #15
0
void buffer_add_string(buffer *b, const char *c)
{
  while (*c) { buffer_add_char(b, *c); c++; }
}
static int osrf_json_gateway_method_handler (request_rec *r) {

	/* make sure we're needed first thing*/
	if (strcmp(r->handler, MODULE_NAME )) return DECLINED;


	osrf_json_gateway_dir_config* dir_conf =
		ap_get_module_config(r->per_dir_config, &osrf_json_gateway_module);


	/* provide 2 different JSON parsers and serializers to support legacy JSON */
	jsonObject* (*parseJSONFunc) (const char*) = legacy_jsonParseString;
	char* (*jsonToStringFunc) (const jsonObject*) = legacy_jsonObjectToJSON;

	if(dir_conf->legacyJSON) {
		ap_log_rerror( APLOG_MARK, APLOG_DEBUG, 0, r, "Using legacy JSON");

	} else {
		parseJSONFunc = jsonParse;
		jsonToStringFunc = jsonObjectToJSON;
	}


	osrfLogDebug(OSRF_LOG_MARK, "osrf gateway: entered request handler");

	/* verify we are connected */
	if( !bootstrapped || !osrfSystemGetTransportClient()) {
		ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "Cannot process request "
				"because the OpenSRF JSON gateway has not been bootstrapped...");
		usleep( 100000 ); /* 100 milliseconds */
		exit(1);
	}

	osrfLogSetAppname("osrf_json_gw");

	char* osrf_locale   = NULL;
	char* param_locale  = NULL;  /* locale for this call */
	char* service       = NULL;  /* service to connect to */
	char* method        = NULL;  /* method to perform */
	char* format        = NULL;  /* method to perform */
	char* a_l           = NULL;  /* request api level */
	char* input_format  = NULL;  /* POST data format, defaults to 'format' */
	int   isXML         = 0;
	int   api_level     = 1;

	r->allowed |= (AP_METHOD_BIT << M_GET);
	r->allowed |= (AP_METHOD_BIT << M_POST);

	osrfLogDebug(OSRF_LOG_MARK, "osrf gateway: parsing URL params");
	osrfStringArray* mparams = NULL;
	osrfStringArray* params  = apacheParseParms(r); /* free me */
	param_locale             = apacheGetFirstParamValue( params, "locale" );
	service                  = apacheGetFirstParamValue( params, "service" );
	method                   = apacheGetFirstParamValue( params, "method" );
	format                   = apacheGetFirstParamValue( params, "format" );
	input_format             = apacheGetFirstParamValue( params, "input_format" );
	a_l                      = apacheGetFirstParamValue( params, "api_level" );
	mparams                  = apacheGetParamValues( params, "param" ); /* free me */

	if(format == NULL)
		format = strdup( "json" );
	if(input_format == NULL)
		input_format = strdup( format );

	/* set the user defined timeout value */
	int timeout = 60;
	char* tout = apacheGetFirstParamValue( params, "timeout" ); /* request timeout in seconds */
	if( tout ) {
		timeout = atoi(tout);
		osrfLogDebug(OSRF_LOG_MARK, "Client supplied timeout of %d", timeout);
		free( tout );
	}

	if (a_l) {
		api_level = atoi(a_l);
		free( a_l );
	}

	if (!strcasecmp(format, "xml")) {
		isXML = 1;
		ap_set_content_type(r, "application/xml");
	} else {
		ap_set_content_type(r, "text/plain");
	}

	free( format );
	int ret = OK;

	/* ----------------------------------------------------------------- */
	/* Grab the requested locale using the Accept-Language header*/


	if ( !param_locale ) {
		if ( apr_table_get(r->headers_in, "X-OpenSRF-Language") ) {
			param_locale = strdup( apr_table_get(r->headers_in, "X-OpenSRF-Language") );
		} else if ( apr_table_get(r->headers_in, "Accept-Language") ) {
			param_locale = strdup( apr_table_get(r->headers_in, "Accept-Language") );
		}
	}


	if (param_locale) {
		growing_buffer* osrf_locale_buf = buffer_init(16);
		if (index(param_locale, ',')) {
			int ind = index(param_locale, ',') - param_locale;
			int i;
			for ( i = 0; i < ind && i < 128; i++ )
				buffer_add_char( osrf_locale_buf, param_locale[i] );
		} else {
			buffer_add( osrf_locale_buf, param_locale );
		}

		free(param_locale);
		osrf_locale = buffer_release( osrf_locale_buf );
	} else {
		osrf_locale = strdup( osrf_json_default_locale );
	}
	/* ----------------------------------------------------------------- */


	if(!(service && method)) {

		osrfLogError(OSRF_LOG_MARK,
			"Service [%s] not found or not allowed", service);
		ret = HTTP_NOT_FOUND;

	} else {

		/* This will log all heaers to the apache error log
		const apr_array_header_t* arr = apr_table_elts(r->headers_in);
		const void* ptr;

		while( (ptr = apr_array_pop(arr)) ) {
			apr_table_entry_t* e = (apr_table_entry_t*) ptr;
			fprintf(stderr, "Table entry: %s : %s\n", e->key, e->val );
		}
		fflush(stderr);
		*/

		osrfAppSession* session = osrfAppSessionClientInit(service);
		osrf_app_session_set_locale(session, osrf_locale);

		double starttime = get_timestamp_millis();
		int req_id = -1;

		if(!strcasecmp(input_format, "json")) {
			jsonObject * arr = jsonNewObject(NULL);

			const char* str;
			int i = 0;

			while( (str = osrfStringArrayGetString(mparams, i++)) )
				jsonObjectPush(arr, parseJSONFunc(str));

			req_id = osrfAppSessionSendRequest( session, arr, method, api_level );
			jsonObjectFree(arr);
		} else {

			/**
			* If we receive XML method params, convert each param to a JSON object
			* and pass the array of JSON object params to the method */
			if(!strcasecmp(input_format, "xml")) {
				jsonObject* jsonParams = jsonNewObject(NULL);

				const char* str;
				int i = 0;
				while( (str = osrfStringArrayGetString(mparams, i++)) ) {
					jsonObjectPush(jsonParams, jsonXMLToJSONObject(str));
				}

				req_id = osrfAppSessionSendRequest( session, jsonParams, method, api_level );
				jsonObjectFree(jsonParams);
			}
		}


		if( req_id == -1 ) {
			osrfLogError(OSRF_LOG_MARK, "I am unable to communicate with opensrf..going away...");
			osrfAppSessionFree(session);
			/* we don't want to spawn an intense re-forking storm
			 * if there is no jabber server.. so give it some time before we die */
			usleep( 100000 ); /* 100 milliseconds */
			exit(1);
		}


		/* ----------------------------------------------------------------- */
		/* log all requests to the activity log */
		const char* authtoken = apr_table_get(r->headers_in, "X-OILS-Authtoken");
		if(!authtoken) authtoken = "";
		growing_buffer* act = buffer_init(128);
		buffer_fadd(act, "[%s] [%s] [%s] %s %s", r->connection->remote_ip,
			authtoken, osrf_locale, service, method );
		const char* str; int i = 0;
		while( (str = osrfStringArrayGetString(mparams, i++)) ) {
			if( i == 1 ) {
				OSRF_BUFFER_ADD(act, " ");
				OSRF_BUFFER_ADD(act, str);
			} else {
				OSRF_BUFFER_ADD(act, ", ");
				OSRF_BUFFER_ADD(act, str);
			}
		}

		osrfLogActivity( OSRF_LOG_MARK, act->buf );
		buffer_free(act);
		/* ----------------------------------------------------------------- */


		osrfMessage* omsg = NULL;

		int statuscode = 200;

		/* kick off the object */
		if (isXML)
			ap_rputs( "<response xmlns=\"http://opensrf.org/-/namespaces/gateway/v1\"><payload>",
				r );
		else
			ap_rputs("{\"payload\":[", r);

		int morethan1       = 0;
		char* statusname    = NULL;
		char* statustext    = NULL;
		char* output        = NULL;

		while((omsg = osrfAppSessionRequestRecv( session, req_id, timeout ))) {

			statuscode = omsg->status_code;
			const jsonObject* res;

			if( ( res = osrfMessageGetResult(omsg)) ) {

				if (isXML) {
					output = jsonObjectToXML( res );
				} else {
					output = jsonToStringFunc( res );
					if( morethan1 ) ap_rputs(",", r); /* comma between JSON array items */
				}
				ap_rputs(output, r);
				free(output);
				morethan1 = 1;

			} else {

				if( statuscode > 299 ) { /* the request returned a low level error */
					statusname = omsg->status_name ? strdup(omsg->status_name)
						: strdup("Unknown Error");
					statustext = omsg->status_text ? strdup(omsg->status_text) 
						: strdup("No Error Message");
					osrfLogError( OSRF_LOG_MARK,  "Gateway received error: %s", statustext );
				}
			}

			osrfMessageFree(omsg);
			if(statusname) break;
		}

		double duration = get_timestamp_millis() - starttime;
		osrfLogDebug(OSRF_LOG_MARK, "gateway request took %f seconds", duration);


		if (isXML)
			ap_rputs("</payload>", r);
		else
			ap_rputs("]",r); /* finish off the payload array */

		if(statusname) {

			/* add a debug field if the request died */
			ap_log_rerror( APLOG_MARK, APLOG_INFO, 0, r,
					"OpenSRF JSON Request returned error: %s -> %s", statusname, statustext );
			int l = strlen(statusname) + strlen(statustext) + 32;
			char buf[l];

			if (isXML)
				snprintf( buf, sizeof(buf), "<debug>\"%s : %s\"</debug>", statusname, statustext );

			else {
				char bb[l];
				snprintf(bb, sizeof(bb),  "%s : %s", statusname, statustext);
				jsonObject* tmp = jsonNewObject(bb);
				char* j = jsonToStringFunc(tmp);
				snprintf( buf, sizeof(buf), ",\"debug\": %s", j);
				free(j);
				jsonObjectFree(tmp);
			}

			ap_rputs(buf, r);

			free(statusname);
			free(statustext);
		}

		/* insert the status code */
		char buf[32];

		if (isXML)
			snprintf(buf, sizeof(buf), "<status>%d</status>", statuscode );
		else
			snprintf(buf, sizeof(buf), ",\"status\":%d", statuscode );

		ap_rputs( buf, r );

		if (isXML)
			ap_rputs("</response>", r);
		else
			ap_rputs( "}", r ); /* finish off the object */

		osrfAppSessionFree(session);
	}

	osrfLogInfo(OSRF_LOG_MARK, "Completed processing service=%s, method=%s", service, method);
	osrfStringArrayFree(params);
	osrfStringArrayFree(mparams);
	free( osrf_locale );
	free( input_format );
	free( method );
	free( service );

	osrfLogDebug(OSRF_LOG_MARK, "Gateway served %d requests", ++numserved);
	osrfLogClearXid();

	return ret;
}