/* * private.h * * Copyright (C) 2003, 2004 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/SpinAppEntry 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 /* * 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 /* * 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 char looked; /* did we look for the data before */ }; 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 */ rxv_spin_ref_t *ref; /* the reference we're checking */ 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; }; 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_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 */ 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); apr_status_t rxv_spin_extra_destroy(void *extra_v); 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_CFGFN_SET 0x00000004 #define RXV_SPIN_WORKSPACE_SET 0x00000008 #define RXV_SPIN_COOKIE_SET 0x00000010 #define RXV_SPIN_SENDFILE_SET 0x00000020 #define RXV_SPIN_CACHEALL_SET 0x00000040 struct rxv_spin_config{ char *application; /* path to the application shared library */ char *appentry; /* application entry 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 cacheall:1; /* cache whole files */ 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 */ }; /* * 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_uint64_t count; /* for how many requests was this pool used */ apr_hash_t *dso; /* cache of DSOs so we don't keep opening */ unsigned char kill; /* true if the whole private pool needs killing */ }; #endif