00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #ifndef __RXV_SPIN__
00048 #define __RXV_SPIN__
00049
00096 #include <stdio.h>
00097 #include <stdlib.h>
00098 #include <stddef.h>
00099 #include <stdarg.h>
00100 #include <string.h>
00101 #include <unistd.h>
00102 #include <sys/types.h>
00103 #include <apr.h>
00104 #include <apr_general.h>
00105 #include <apr_strings.h>
00106 #include <apr_lib.h>
00107 #include <apr_pools.h>
00108 #include <apr_buckets.h>
00109 #include <apr_hash.h>
00110 #include <apr_file_io.h>
00111 #include <apr_portable.h>
00112 #include <apr_time.h>
00113 #include <apr_sdbm.h>
00114 #include <apr_md5.h>
00115 #include <apr_base64.h>
00116 #include <apreq_param.h>
00117 #include <apreq_cookie.h>
00118
00119
00120 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00121 #undef PACKAGE_BUGREPORT
00122 #undef PACKAGE_NAME
00123 #undef PACKAGE_STRING
00124 #undef PACKAGE_TARNAME
00125 #undef PACKAGE_VERSION
00126 #endif
00127
00128
00129 #include <apreq_module_apache2.h>
00130
00131
00132 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00133 #undef PACKAGE_BUGREPORT
00134 #undef PACKAGE_NAME
00135 #undef PACKAGE_STRING
00136 #undef PACKAGE_TARNAME
00137 #undef PACKAGE_VERSION
00138 #define PACKAGE_BUGREPORT RXV_SPIN_PACKAGE_BUGREPORT
00139 #define PACKAGE_NAME RXV_SPIN_PACKAGE_NAME
00140 #define PACKAGE_STRING RXV_SPIN_PACKAGE_STRING
00141 #define PACKAGE_TARNAME RXV_SPIN_PACKAGE_TARNAME
00142 #define PACKAGE_VERSION RXV_SPIN_PACKAGE_VERSION
00143 #endif
00144
00145 #include <http_request.h>
00146
00147 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00148 #ifdef HAVE_AP_REGEX_H
00149 #include <ap_regex.h>
00150 #else
00151 #define ap_regex_t regex_t
00152 #define ap_regmatch_t regmatch_t
00153 #define ap_regcomp(a,b,c) regcomp((a),(b),(c))
00154 #define ap_regfree(a) regfree(a)
00155 #define AP_REG_ICASE REG_ICASE
00156 #define AP_REG_NEWLINE REG_NEWLINE
00157 #define AP_REG_NOTBOL REG_NOTBOL
00158 #define AP_REG_NOTEOL REG_NOTEOL
00159 #define AP_REG_EXTENDED REG_EXTENDED
00160 #define AP_REG_NOSUB REG_NOSUB
00161 #endif
00162 #endif
00163
00164 #include <libxml/parser.h>
00165 #include <libxml/tree.h>
00166
00167 #ifdef HAVE_LIBPQ
00168 #include <libpq-fe.h>
00169 #endif
00170 #ifdef HAVE_LIBMYSQLCLIENT
00171 #include <mysql.h>
00172 #endif
00173
00181 #define RXV_SPIN_DATA_SGL 0x01
00182
00183 #define RXV_SPIN_DATA_RWS 0x02
00184
00185 #define RXV_SPIN_DATA_MTA 0xFF
00186
00188 #define RXV_SPIN_TRIM_LEFT 0x01
00189
00190 #define RXV_SPIN_TRIM_RIGHT 0x02
00191
00193 typedef struct rxv_spin_data rxv_spin_data_t;
00204 typedef struct rxv_spin_context rxv_spin_context_t;
00205 typedef rxv_spin_context_t rxv_spin_ctx_t;
00216 typedef struct rxv_spin_conn rxv_spin_conn_t;
00217 typedef struct rxv_spin_cpool rxv_spin_cpool_t;
00228 typedef struct rxv_spin_db_result rxv_spin_db_result_t;
00232
00233
00239 struct rxv_spin_data{
00240 unsigned char type;
00241 size_t size;
00243 union{
00244 apr_hash_t *cols;
00245 char *data;
00246 rxv_spin_data_t *meta;
00247 void *both;
00248 };
00249 };
00250
00256 struct rxv_spin_context{
00257 request_rec *r;
00258 apr_pool_t *pool;
00259 rxv_spin_data_t *data;
00260 apreq_handle_t *req;
00261 rxv_spin_cpool_t *cpool;
00262 void *guts;
00263 void *extra;
00264 };
00265
00271
00272
00286 rxv_spin_data_t *rxv_spin_single(apr_pool_t *pool,const char *str);
00287
00302 char *rxv_spin_single_get(rxv_spin_data_t *single);
00303
00318 rxv_spin_data_t *rxv_spin_single_set(rxv_spin_data_t *single,const char *str);
00319
00339 rxv_spin_data_t *rxv_spin_single_mem(apr_pool_t *pool,const char *str,
00340 size_t size);
00341
00362 rxv_spin_data_t *rxv_spin_single_memset(rxv_spin_data_t *single,const char *str,
00363 size_t size);
00364
00376 rxv_spin_data_t *rxv_spin_single_tolower(rxv_spin_data_t *single);
00377
00389 rxv_spin_data_t *rxv_spin_single_toupper(rxv_spin_data_t *single);
00390
00402 rxv_spin_data_t *rxv_spin_single_trim(rxv_spin_data_t *single,
00403 unsigned char what);
00404 #define rxv_spin_single_trimboth(s) \
00405 rxv_spin_single_trim((s),(RXV_SPIN_TRIM_LEFT|RXV_SPIN_TRIM_RIGHT))
00406
00407 #define rxv_spin_single_trimleft(s) \
00408 rxv_spin_single_trim((s),(RXV_SPIN_TRIM_LEFT))
00409
00410 #define rxv_spin_single_trimright(s) \
00411 rxv_spin_single_trim((s),(RXV_SPIN_TRIM_RIGHT))
00412
00432 rxv_spin_data_t *rxv_spin_meta(apr_pool_t *pool,...);
00433
00449 rxv_spin_data_t *rxv_spin_meta_vstr(apr_pool_t *pool,...);
00450
00474 rxv_spin_data_t *rxv_spin_meta_parse(apr_pool_t *pool,
00475 char *str,const char *sep);
00476
00493 rxv_spin_data_t *rxv_spin_meta_empty(apr_pool_t *pool,size_t size);
00494
00508 apr_hash_t *rxv_spin_meta_hash(apr_pool_t *pool,rxv_spin_data_t *data);
00509
00523 rxv_spin_data_t *rxv_spin_meta_mark(rxv_spin_data_t *data,size_t element);
00524
00539 rxv_spin_data_t *rxv_spin_meta_markeach(rxv_spin_data_t *data,
00540 size_t off,size_t step);
00541
00558 rxv_spin_data_t *rxv_spin_meta_select(rxv_spin_data_t *data,
00559 rxv_spin_data_t *select,
00560 apr_hash_t *hash);
00561
00579 rxv_spin_data_t *rxv_spin_rows(apr_pool_t *pool,...);
00580
00595 apr_hash_t *rxv_spin_rows_hash(apr_pool_t *pool,rxv_spin_data_t *rows,
00596 const char *column);
00597
00611 rxv_spin_data_t *rxv_spin_rows_mark(rxv_spin_data_t *rows,const char *column,
00612 size_t element);
00613
00628 rxv_spin_data_t *rxv_spin_rows_markeach(rxv_spin_data_t *rows,
00629 const char *column,
00630 size_t off,size_t step);
00631
00651 rxv_spin_data_t *rxv_spin_rows_select(rxv_spin_data_t *rows,
00652 rxv_spin_data_t *select,
00653 const char *column,const char *marker,
00654 apr_hash_t *hash);
00655
00672 rxv_spin_data_t *rxv_spin_column_get(apr_pool_t *pool,
00673 rxv_spin_data_t *rows,const char *key);
00674
00691 rxv_spin_data_t *rxv_spin_column_set(rxv_spin_data_t *rows,
00692 const char *key,rxv_spin_data_t *column);
00693 #define rxv_spin_column_del(rows,key) rxv_spin_column_set((rows),(key),NULL)
00694
00714 rxv_spin_data_t *rxv_spin_resize(apr_pool_t *pool,rxv_spin_data_t *data,
00715 size_t size);
00716
00736 rxv_spin_data_t *rxv_spin_copy(apr_pool_t *pool,rxv_spin_data_t *data);
00737
00749 char *rxv_spin_str_tolower(const char *str);
00750
00762 char *rxv_spin_str_toupper(const char *str);
00763
00777 char *rxv_spin_str_trim(char *str,unsigned char what);
00778 #define rxv_spin_str_trimboth(s) \
00779 rxv_spin_str_trim((s),(RXV_SPIN_TRIM_LEFT|RXV_SPIN_TRIM_RIGHT))
00780
00781 #define rxv_spin_str_trimleft(s) \
00782 rxv_spin_str_trim((s),(RXV_SPIN_TRIM_LEFT))
00783
00784 #define rxv_spin_str_trimright(s) \
00785 rxv_spin_str_trim((s),(RXV_SPIN_TRIM_RIGHT))
00786
00795
00796
00808 rxv_spin_data_t *rxv_spin_ctx_get(rxv_spin_context_t *ctx,const char *key);
00809 #define rxv_spin_ctx_strget(ctx,key) \
00810 rxv_spin_single_get(rxv_spin_ctx_get((ctx),(key)))
00811
00841 rxv_spin_data_t *rxv_spin_ctx_set(rxv_spin_context_t *ctx,
00842 const char *key,rxv_spin_data_t *value);
00843 #define rxv_spin_ctx_strset(ctx,key,val) \
00844 rxv_spin_ctx_set((ctx),(key),rxv_spin_single((ctx)->pool,(val)))
00845
00846 #define rxv_spin_ctx_del(ctx,key) rxv_spin_ctx_set((ctx),(key),NULL)
00847
00851
00852
00871 rxv_spin_data_t *rxv_spin_app_get(rxv_spin_context_t *ctx,const char *key);
00872 #define rxv_spin_app_strget(ctx,key) \
00873 rxv_spin_single_get(rxv_spin_app_get((ctx),(key)))
00874
00889 rxv_spin_data_t *rxv_spin_app_set(rxv_spin_context_t *ctx,
00890 const char *key,rxv_spin_data_t *val);
00891 #define rxv_spin_app_strset(ctx,key,val) \
00892 rxv_spin_app_set((ctx),(key),rxv_spin_single((ctx)->pool,(val)))
00893
00907 apr_status_t rxv_spin_app_del(rxv_spin_context_t *ctx,const char *key);
00908
00920 rxv_spin_data_t *rxv_spin_ses_get(rxv_spin_context_t *ctx,const char *key);
00921 #define rxv_spin_ses_strget(ctx,key) \
00922 rxv_spin_single_get(rxv_spin_ses_get((ctx),(key)))
00923
00938 rxv_spin_data_t *rxv_spin_ses_set(rxv_spin_context_t *ctx,
00939 const char *key,rxv_spin_data_t *val);
00940 #define rxv_spin_ses_strset(ctx,key,val) \
00941 rxv_spin_ses_set((ctx),(key),rxv_spin_single((ctx)->pool,(val)))
00942
00956 apr_status_t rxv_spin_ses_del(rxv_spin_context_t *ctx,const char *key);
00957
00974 char *rxv_spin_ses_idget(rxv_spin_context_t *ctx);
00975
00991 int rxv_spin_ses_valid(rxv_spin_context_t *ctx);
00992
00995
00996
01002 #define RXV_SPIN_CONN_PGSQL 0x01
01003
01004 #define RXV_SPIN_CONN_MYSQL 0x02
01005
01006 #define RXV_SPIN_CONN_MINID 0x01
01007
01008 #define RXV_SPIN_CONN_MAXID 0x3F
01009
01010 #define RXV_SPIN_CONN_FOREIGN 0x40
01011
01012 #define RXV_SPIN_CONN_POOLED 0x80
01013
01015 #define RXV_SPIN_CONN_IS_PGSQL(c) ((((c)->type)&RXV_SPIN_CONN_MAXID)==RXV_SPIN_CONN_PGSQL)
01016
01017 #define RXV_SPIN_CONN_IS_MYSQL(c) ((((c)->type)&RXV_SPIN_CONN_MAXID)==RXV_SPIN_CONN_MYSQL)
01018
01019 #define RXV_SPIN_CONN_IS_FOREIGN(c) (((c)->type)&RXV_SPIN_CONN_FOREIGN)
01020
01021 #define RXV_SPIN_CONN_IS_POOLED(c) (((c)->type)&RXV_SPIN_CONN_POOLED)
01022
01031 struct rxv_spin_conn{
01032 unsigned char type;
01033 char *cinfo;
01035 union{
01036 #ifdef HAVE_LIBPQ
01037 PGconn *pgconn;
01038 #endif
01039 #ifdef HAVE_LIBMYSQLCLIENT
01040 MYSQL *myconn;
01041 #endif
01042 void *conn;
01043 };
01045 union{
01046 rxv_spin_cpool_t *cpool;
01047 apr_pool_t *pool;
01048 };
01049 apr_status_t (*cleanup)(void *data);
01050 };
01051
01057 struct rxv_spin_cpool{
01058 apr_pool_t *pool;
01059 apr_hash_t *conns;
01060 };
01061
01062
01063
01064
01070 struct rxv_spin_db_result{
01071 apr_status_t status;
01072 char *error;
01073 rxv_spin_data_t *data;
01074 };
01075
01116 rxv_spin_conn_t *rxv_spin_db_connect(apr_pool_t *pool,
01117 rxv_spin_cpool_t *cpool,
01118 const char *conninfo,
01119 unsigned char type);
01120
01137 rxv_spin_db_result_t *rxv_spin_db_exec(apr_pool_t *pool,
01138 rxv_spin_conn_t *conn,
01139 const char *query);
01140
01156 char *rxv_spin_db_info(rxv_spin_conn_t *conn,unsigned char what);
01157
01168 apr_status_t rxv_spin_db_status(rxv_spin_conn_t *conn);
01169
01189 char *rxv_spin_db_escape(apr_pool_t *pool,
01190 rxv_spin_conn_t *conn,
01191 const char *str);
01192
01207 apr_status_t rxv_spin_db_reset(rxv_spin_conn_t *conn);
01208
01239 rxv_spin_cpool_t *rxv_spin_cpool_create(apr_pool_t *pool);
01240
01254 rxv_spin_conn_t *rxv_spin_cpool_get(apr_pool_t *pool,rxv_spin_cpool_t *cpool,
01255 const char *conninfo);
01256
01295 rxv_spin_conn_t *rxv_spin_cpool_set(rxv_spin_cpool_t *cpool,
01296 const char *conninfo,void *conn,
01297 apr_status_t (*cleanup)(void *data));
01298
01314 apr_status_t rxv_spin_conn_close(rxv_spin_conn_t *conn);
01315
01318
01319
01325 #define RXV_SPIN_DB_INFO_DB 0x01
01326
01327 #define RXV_SPIN_DB_INFO_USER 0x02
01328
01329 #define RXV_SPIN_DB_INFO_PASS 0x03
01330
01331 #define RXV_SPIN_DB_INFO_HOST 0x04
01332
01333 #define RXV_SPIN_DB_INFO_PORT 0x05
01334
01335 #define RXV_SPIN_DB_INFO_TTY 0x06
01336
01337 #define RXV_SPIN_DB_INFO_OPTIONS 0x07
01338
01339 #define RXV_SPIN_DB_INFO_ERROR 0x08
01340
01344
01345
01351 #define rxv_spin_db_db(conn) \
01352 rxv_spin_db_info((conn),RXV_SPIN_DB_INFO_DB)
01353
01354 #define rxv_spin_db_user(conn) \
01355 rxv_spin_db_info((conn),RXV_SPIN_DB_INFO_USER)
01356
01357 #define rxv_spin_db_pass(conn) \
01358 rxv_spin_db_info((conn),RXV_SPIN_DB_INFO_PASS)
01359
01360 #define rxv_spin_db_host(conn) \
01361 rxv_spin_db_info((conn),RXV_SPIN_DB_INFO_HOST)
01362
01363 #define rxv_spin_db_port(conn) \
01364 rxv_spin_db_info((conn),RXV_SPIN_DB_INFO_PORT)
01365
01366 #define rxv_spin_db_tty(conn) \
01367 rxv_spin_db_info((conn),RXV_SPIN_DB_INFO_TTY)
01368
01369 #define rxv_spin_db_options(conn) \
01370 rxv_spin_db_info((conn),RXV_SPIN_DB_INFO_OPTIONS)
01371
01372 #define rxv_spin_db_error(conn) \
01373 rxv_spin_db_info((conn),RXV_SPIN_DB_INFO_ERROR)
01374
01385 typedef int (*rxv_spin_service_t)(rxv_spin_context_t *context);
01390
01391
01392 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01393
01394 #define rxv_spin_str_tometa(p,...) rxv_spin_meta_vstr((p),...)
01395 #define rxv_spin_column(p,s) rxv_spin_meta_empty((p),(s))
01396 #define rxv_spin_column_mark(c,e) rxv_spin_meta_mark((c),(e))
01397 #define rxv_spin_column_markeach(c,n) rxv_spin_meta_markeach((c),0,(n))
01398 #define rxv_spin_single_tostr(p,s) rxv_spin_single_get(s)
01399 #define rxv_spin_ctx_str_set(c,k,v) rxv_spin_ctx_strset((c),(k),(v))
01400 #define rxv_spin_app_str_get(c,k) rxv_spin_app_strget((c),(k))
01401 #define rxv_spin_app_str_set(c,k,v) rxv_spin_app_strset((c),(k),(v))
01402 #define rxv_spin_ses_str_get(c,k) rxv_spin_ses_strget((c),(k))
01403 #define rxv_spin_ses_str_set(c,k,v) rxv_spin_ses_strset((c),(k),(v))
01404 #define rxv_spin_db_conn rxv_spin_conn
01405 #define rxv_spin_db_conn_t rxv_spin_conn_t
01406 #define rxv_spin_db_pool rxv_spin_cpool
01407 #define rxv_spin_db_pool_t rxv_spin_cpool_t
01408 #define rxv_spin_db_pool_create(p) rxv_spin_cpool_create(p)
01409 #define rxv_spin_db_finish(c) rxv_spin_conn_close(c)
01410 #define RXV_SPIN_DB_PGSQL RXV_SPIN_CONN_PGSQL
01411 #define RXV_SPIN_DB_MYSQL RXV_SPIN_CONN_MYSQL
01412 #define RXV_SPIN_DB_MINID RXV_SPIN_CONN_MINID
01413 #define RXV_SPIN_DB_MAXID RXV_SPIN_CONN_MAXID
01414 #define RXV_SPIN_DB_POOLED RXV_SPIN_CONN_POOLED
01415 #define RXV_SPIN_DB_IS_PGSQL(c) RXV_SPIN_CONN_IS_PGSQL(c)
01416 #define RXV_SPIN_DB_IS_MYSQL(c) RXV_SPIN_CONN_IS_MYSQL(c)
01417 #define RXV_SPIN_DB_IS_POOLED(c) RXV_SPIN_CONN_IS_POOLED(c)
01418
01419 #endif
01420
01421
01422
01423 #endif