/* * private.h * * Copyright (C) 2003 - 2005 Bojan Smojver, Rexursive * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public Licence as published by the Free * Software Foundation; either version 2 of the Licence, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licence for * more details. * * You should have received a copy of the GNU General Public Licence along * with this program; if not, write to the Free Software Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as two special exceptions, Bojan Smojver, Rexursive, gives * permission to: * * 1. Link, both statically and dynamically, the code of this program with * Apache HTTP Server, Apache Portable Runtime and Apache Portable Runtime * Utility Library from Apache Software Foundation (or with modified versions * of the above, that use the same licence - Apache Software Licence 1.1, 2.0 * or any later version), and distribute linked combinations including the * program and the above software from Apache Software Foundation. You must * obey the GNU General Public Licence in all respects for all of the code * used other than Apache HTTP Server, Apache Portable Runtime and Apache * Portable Runtime Utility Library. * * 2. Dynamically link any shared library with this program at run-time, * through the interface of SpinApplication or LoadModule run-time * configuration directives of Apache HTTP Server, as provided by this program * or Apache HTTP Server itself, regardless of licensing terms of those shared * libraries. You must obey the GNU General Public Licence in all respects for * all of the code used other than that of those shared libraries. * * If you modify this file, you may extend these exceptions to your version of * the file, but you are not obligated to do so. If you do not wish to do so, * delete one or both of these exception statements from your version. * */ #ifndef __RXV_SPIN_PRIVATE__ #define __RXV_SPIN_PRIVATE__ #include #include /* * Type definitions before anything else */ typedef struct rxv_spin_txt rxv_spin_txt_t; typedef struct rxv_spin_ref rxv_spin_ref_t; typedef struct rxv_spin_for rxv_spin_for_t; typedef struct rxv_spin_if rxv_spin_if_t; typedef struct rxv_spin_node rxv_spin_node_t; typedef struct rxv_spin_cache rxv_spin_cache_t; typedef struct rxv_spin_extra rxv_spin_extra_t; typedef struct rxv_spin_config rxv_spin_config_t; typedef struct rxv_spin_conncf rxv_spin_conncf_t; typedef struct rxv_spin_reqcf rxv_spin_reqcf_t; typedef struct rxv_spin_guts rxv_spin_guts_t; typedef struct rxv_spin_private rxv_spin_private_t; /* * Default type: undefined */ #define RXV_SPIN_UDF 0x00 /* * Statement types */ #define RXV_SPIN_TXT 0x01 #define RXV_SPIN_REF 0x02 #define RXV_SPIN_FOR 0x03 #define RXV_SPIN_IF 0x04 #define RXV_SPIN_REG 0x05 #define RXV_SPIN_LIT 0x06 #define RXV_SPIN_NUM 0x07 /* * Reference types */ #define RXV_SPIN_REF_REG 0x01 #define RXV_SPIN_REF_SIZ 0x02 #define RXV_SPIN_REF_IND 0x03 /* * Conditional types: #if (guaranteed to be 0) and #unless (guaranteed to be 1) */ #define RXV_SPIN_IF_IF 0x00 #define RXV_SPIN_IF_UNLESS 0x01 /* * Generic, scanned operators */ #define RXV_SPIN_OP_NONE 0x00 #define RXV_SPIN_OP_MATCH 0x01 #define RXV_SPIN_OP_EQUAL 0x02 #define RXV_SPIN_OP_MODULO 0x03 /* * Specific operators (also define types of operands) */ #define RXV_SPIN_OP_EQ_LIT 0x21 #define RXV_SPIN_OP_EQ_NUM 0x22 #define RXV_SPIN_OP_EQ_REF 0x23 /* * Up to what size we never do sendfile(), direct lift from Apache's core.c */ #define RXV_SPIN_MIN_SENDFILE 256 #define RXV_SPIN_BUF_STEP 0x4000 /* * Generic true and false */ #define RXV_SPIN_FALSE 0 #define RXV_SPIN_TRUE (!RXV_SPIN_FALSE) /* * Maximum nesting depth of the #if/#unless and #for */ #define RXV_SPIN_MAX_DEPTH 32 /* * Data structures for Abstract Syntax Tree */ struct rxv_spin_txt{ apr_off_t offset; /* from the beginning of the file */ apr_size_t length; char *cache; /* cached file chunk, if enabled */ }; struct rxv_spin_ref{ char *name; /* full name of the reference */ char *chunk; /* last chunk of the full name */ rxv_spin_data_t *data; /* data currently associated with this reference */ rxv_spin_for_t *loop; /* points to its for loop, if any */ unsigned int looked:1; /* did we look for the data before */ unsigned int type:2; /* type of reference: regular, size or index */ }; struct rxv_spin_for{ rxv_spin_ref_t *ref; /* what to loop around */ rxv_spin_node_t *stmt; /* what to replicate each time */ size_t index; /* the index of the loop */ }; struct rxv_spin_if{ unsigned char type; /* is this actually the unless, not if */ unsigned char oper; /* what operator is used */ rxv_spin_ref_t *ref; /* the reference we're checking, on the left */ union{ ap_regex_t *reg; /* regular expression to match */ rxv_spin_ref_t *rfr; /* the reference to match, on the right */ char *lit; /* literal string */ struct{ unsigned long num; /* number to the right of the operator */ unsigned long res; /* result of the modulo comparison, right of == */ }; }; rxv_spin_node_t *pos; /* statement if ref is not null */ rxv_spin_node_t *neg; /* statement if ref is null */ }; struct rxv_spin_node{ unsigned char type; union{ rxv_spin_txt_t *txt; rxv_spin_ref_t *ref; rxv_spin_if_t *cond; rxv_spin_for_t *loop; ap_regex_t *reg; char *lit; unsigned long num; }; rxv_spin_node_t *next; }; /* * Parsed template (AST) cache structure */ struct rxv_spin_cache{ apr_pool_t *pool; /* pool specific to this template */ char *file; /* filename of this template */ rxv_spin_node_t *root; /* root node of the AST */ apr_ino_t inode; /* inode of the file */ apr_time_t mtime; /* previously recorded template mod time */ apr_off_t size; /* previously recorded template size */ unsigned int sendfile:1; /* are we using sendfile */ unsigned int cacheall:1; /* should we cache all text */ unsigned int kill:1; /* true if the whole template pool needs killing */ }; /* * Data structures for the scanner */ struct rxv_spin_extra{ apr_pool_t *pool; /* regular pool for all memory allocations */ apr_pool_t *tpool; /* template pool, from the cached entry */ apr_off_t offset; /* begining of TXT */ apr_size_t length; /* length of TXT */ apr_off_t row; /* current row of the template */ apr_off_t col; /* current column of the template */ unsigned int istxt:1; /* are we inside text */ unsigned int iseof:1; /* did we bump into the end of file */ unsigned int cacheall:1; /* do we cache all text */ unsigned int sendfile:1; /* should we enable sendfile */ unsigned int tcache:1; /* should cache templates between requests */ char *buf; /* buffer to hold cached text */ size_t bsize; /* size of the whole buffer */ rxv_spin_node_t *root; /* root of the abstract syntax tree */ rxv_spin_node_t **tail; /* tails of node lists on the stack */ rxv_spin_for_t **loop; /* nesting loops */ unsigned char *nest; /* nesting type stack, #if or #for */ size_t *boff; /* branch offset, RXV_SPIN_MAX_DEPTH for #else */ int depth; /* current nesting depth */ int ldepth; /* current loop nesting depth */ char *error; apr_bucket_brigade *brigade; /* where the result goes */ rxv_spin_context_t *ctx; /* the context - data, parameters etc. */ apr_file_t *fp; /* template file being processed */ apr_hash_t *cache; /* template cache */ apr_hash_t *used; /* used cache items that require cleaning */ rxv_spin_cache_t *ready; /* parsed, cached template */ }; /* Function declarations */ apr_status_t rxv_spin_file(const char *file,rxv_spin_extra_t *extra, apr_pool_t *pool,apr_finfo_t *finfo); rxv_spin_extra_t *rxv_spin_extra_create(apr_pool_t *pool, apr_bucket_alloc_t *balloc, rxv_spin_context_t *ctx); rxv_spin_context_t *rxv_spin_context_create(apr_pool_t *pool); rxv_spin_private_t *rxv_spin_private_create(apr_pool_t *pool); /* Missing parser and scanner stuff */ #define YYSTYPE rxv_spin_node_t* #define YY_EXTRA_TYPE rxv_spin_extra_t* int rxv_spin_parse(void *YYPARSE_PARAM); void rxv_spin_error(char *s); int rxv_spin_lex(rxv_spin_node_t **yyval_param,void *yyscanner); /* * Module configuration */ #define RXV_SPIN_APPLICATION_SET 0x00000001 #define RXV_SPIN_APPENTRY_SET 0x00000002 #define RXV_SPIN_APPFIXUP_SET 0x00000004 #define RXV_SPIN_CFGFN_SET 0x00000008 #define RXV_SPIN_WORKSPACE_SET 0x00000010 #define RXV_SPIN_COOKIE_SET 0x00000020 #define RXV_SPIN_SENDFILE_SET 0x00000040 #define RXV_SPIN_TCACHE_SET 0x00000080 #define RXV_SPIN_CACHEALL_SET 0x00000100 #define RXV_SPIN_CONNPOOL_SET 0x00000200 struct rxv_spin_config{ char *application; /* path to the application shared library */ char *appentry; /* application entry function name */ char *appfixup; /* application fixup function name */ char *cfgfn; /* configuration file filename */ char *workspace; /* directory for session/application data */ char *cookie; /* name of the cookie used for session tracking */ char *basfn; /* base filename of the application/session db */ char *pagfn; /* page filename of the application database */ unsigned int sendfile:1; /* sendfile flag */ unsigned int tcache:1; /* cache templates between requests */ unsigned int cacheall:1; /* cache whole files (i.e. all content) */ unsigned int connpool:1; /* enable connection pooling */ apr_uint32_t set; /* what options were actually set */ }; /* * Connection configuration */ struct rxv_spin_conncf{ rxv_spin_private_t *priv; /* thread private data */ apr_hash_t *used; /* used templates for this connection */ }; /* * Request configuration */ struct rxv_spin_reqcf{ char *sesid; /* session id */ int valid; /* session is valid: value 1, otherwise 0 */ rxv_spin_context_t *ctx; /* context passed from fixup to handler */ apr_dso_handle_sym_t fix; /* fixup function handle */ apr_dso_handle_sym_t svc; /* service function handle */ }; /* * Context guts, kept private */ struct rxv_spin_guts{ char *cfgfn; /* configuration file filename */ char *appfn; /* persistent application info filename */ char *pagfn; /* page filename of the application database */ apr_sdbm_t *app; /* persistent application info database */ char *sesfn; /* persistent session info filename */ apr_sdbm_t *ses; /* persistent session info database */ char *sesid; /* session id */ int valid; /* session is valid: value 1, otherwise 0 */ }; /* * Private thread data */ struct rxv_spin_private{ apr_pool_t *pool; /* thread specific pool to avoid concurrency */ apr_hash_t *cache; /* parsed template (AST) cache */ rxv_spin_cpool_t *cpool; /* connection pool */ apr_hash_t *dso; /* cache of DSOs so we don't keep opening */ }; #endif