You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(38) |
Sep
(134) |
Oct
(30) |
Nov
(8) |
Dec
(17) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
|
Feb
|
Mar
(14) |
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(4) |
Dec
|
2009 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:34:33
|
Update of /cvsroot/mod-c/ehtml/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv17401/include Modified Files: Makefile.in Log Message: Bootstraped. Index: Makefile.in =================================================================== RCS file: /cvsroot/mod-c/ehtml/include/Makefile.in,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Makefile.in 23 Aug 2006 10:32:57 -0000 1.4 --- Makefile.in 8 Sep 2006 14:34:29 -0000 1.5 *************** *** 1,3 **** ! # Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ --- 1,3 ---- ! # Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ *************** *** 39,48 **** subdir = include DIST_COMMON = $(ehtml_HEADERS) $(srcdir)/Makefile.am \ ! $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) ! mkinstalldirs = $(SHELL) $(top_srcdir)/cfgaux/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = --- 39,48 ---- subdir = include DIST_COMMON = $(ehtml_HEADERS) $(srcdir)/Makefile.am \ ! $(srcdir)/Makefile.in ChangeLog ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) ! mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = *************** *** 86,89 **** --- 86,91 ---- DEFS = @DEFS@ DEPDIR = @DEPDIR@ + DOXYGEN = @DOXYGEN@ + DOXYGEN_SUBDIR = @DOXYGEN_SUBDIR@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:34:33
|
Update of /cvsroot/mod-c/ehtml/samples In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv17401/samples Modified Files: Makefile.in Log Message: Bootstraped. Index: Makefile.in =================================================================== RCS file: /cvsroot/mod-c/ehtml/samples/Makefile.in,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Makefile.in 22 Aug 2006 18:36:19 -0000 1.1 --- Makefile.in 8 Sep 2006 14:34:29 -0000 1.2 *************** *** 15,19 **** @SET_MAKE@ ! SOURCES = $(libbasic_la_SOURCES) srcdir = @srcdir@ --- 15,19 ---- @SET_MAKE@ ! SOURCES = $(libsamplebasic_la_SOURCES) $(libsamplesession_la_SOURCES) srcdir = @srcdir@ *************** *** 57,63 **** libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) ! libbasic_la_LIBADD = ! am_libbasic_la_OBJECTS = 01basic.lo ! libbasic_la_OBJECTS = $(am_libbasic_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/cfgaux/depcomp --- 57,66 ---- libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) ! libsamplebasic_la_LIBADD = ! am_libsamplebasic_la_OBJECTS = 01basic.lo ! libsamplebasic_la_OBJECTS = $(am_libsamplebasic_la_OBJECTS) ! libsamplesession_la_LIBADD = ! am_libsamplesession_la_OBJECTS = 02session.lo ! libsamplesession_la_OBJECTS = $(am_libsamplesession_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/cfgaux/depcomp *************** *** 71,76 **** CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ ! SOURCES = $(libbasic_la_SOURCES) ! DIST_SOURCES = $(libbasic_la_SOURCES) ETAGS = etags CTAGS = ctags --- 74,80 ---- CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ ! SOURCES = $(libsamplebasic_la_SOURCES) $(libsamplesession_la_SOURCES) ! DIST_SOURCES = $(libsamplebasic_la_SOURCES) \ ! $(libsamplesession_la_SOURCES) ETAGS = etags CTAGS = ctags *************** *** 101,104 **** --- 105,110 ---- DEFS = @DEFS@ DEPDIR = @DEPDIR@ + DOXYGEN = @DOXYGEN@ + DOXYGEN_SUBDIR = @DOXYGEN_SUBDIR@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ *************** *** 187,193 **** # 01basic.cpp \ # -shared -o basic.so -lehtml ! lib_LTLIBRARIES = libbasic.la ! libbasic_la_SOURCES = 01basic.cpp ! libbasic_la_LDFLAGS = -shared -module -lehtml all: all-am --- 193,202 ---- # 01basic.cpp \ # -shared -o basic.so -lehtml ! lib_LTLIBRARIES = libsamplebasic.la libsamplesession.la ! libsamplebasic_la_SOURCES = 01basic.cpp ! libsamplebasic_la_LDFLAGS = -shared -module -lehtml ! #libsamplebasic_la_LIBADD = ehtml ! libsamplesession_la_SOURCES = 02session.cpp ! libsamplesession_la_LDFLAGS = -shared -module -lehtml all: all-am *************** *** 250,255 **** rm -f "$${dir}/so_locations"; \ done ! libbasic.la: $(libbasic_la_OBJECTS) $(libbasic_la_DEPENDENCIES) ! $(CXXLINK) -rpath $(libdir) $(libbasic_la_LDFLAGS) $(libbasic_la_OBJECTS) $(libbasic_la_LIBADD) $(LIBS) mostlyclean-compile: --- 259,266 ---- rm -f "$${dir}/so_locations"; \ done ! libsamplebasic.la: $(libsamplebasic_la_OBJECTS) $(libsamplebasic_la_DEPENDENCIES) ! $(CXXLINK) -rpath $(libdir) $(libsamplebasic_la_LDFLAGS) $(libsamplebasic_la_OBJECTS) $(libsamplebasic_la_LIBADD) $(LIBS) ! libsamplesession.la: $(libsamplesession_la_OBJECTS) $(libsamplesession_la_DEPENDENCIES) ! $(CXXLINK) -rpath $(libdir) $(libsamplesession_la_LDFLAGS) $(libsamplesession_la_OBJECTS) $(libsamplesession_la_LIBADD) $(LIBS) mostlyclean-compile: *************** *** 260,263 **** --- 271,275 ---- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/01basic.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/02session.Plo@am__quote@ .cpp.o: *************** *** 462,466 **** uninstall-libLTLIBRARIES - #libbasic_la_LIBADD = ehtml # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. --- 474,477 ---- |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:34:33
|
Update of /cvsroot/mod-c/ehtml/src In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv17401/src Modified Files: Makefile.in Log Message: Bootstraped. Index: Makefile.in =================================================================== RCS file: /cvsroot/mod-c/ehtml/src/Makefile.in,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Makefile.in 23 Aug 2006 10:32:57 -0000 1.5 --- Makefile.in 8 Sep 2006 14:34:29 -0000 1.6 *************** *** 1,3 **** ! # Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ --- 1,3 ---- ! # Makefile.in generated by automake 1.9.5 from Makefile.am. # @configure_input@ *************** *** 23,26 **** --- 23,29 ---- # EHTML_INCLUDE_DIR is the include directory where EHTML header files are stored + + SOURCES = $(libdisksession_la_SOURCES) $(libehtml_la_SOURCES) $(libsession_la_SOURCES) $(libsessionid_la_SOURCES) $(mod_c_dss_SOURCES) + srcdir = @srcdir@ top_srcdir = @top_srcdir@ *************** *** 45,50 **** build_triplet = @build@ host_triplet = @host@ subdir = src ! DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in --- 48,54 ---- build_triplet = @build@ host_triplet = @host@ + bin_PROGRAMS = mod_c_dss$(EXEEXT) subdir = src ! DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in *************** *** 60,72 **** esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; ! am__installdirs = "$(DESTDIR)$(libdir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libehtml_la_LIBADD = ! am_libehtml_la_OBJECTS = EHTMLApplication.lo Common.lo PageWriter.lo \ ! TagAttribute.lo SimpleTagAttribute.lo StyleAttribute.lo \ ! TagRenderer.lo Component.lo Label.lo Input.lo Session.lo \ ! Container.lo Page.lo Form.lo Request.lo Response.lo libehtml_la_OBJECTS = $(am_libehtml_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/cfgaux/depcomp --- 64,95 ---- esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; ! am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) + libdisksession_la_LIBADD = + am_libdisksession_la_OBJECTS = DiskSessionDriver.lo + libdisksession_la_OBJECTS = $(am_libdisksession_la_OBJECTS) libehtml_la_LIBADD = ! am__objects_1 = Common.lo Component.lo Container.lo Dictionary.lo \ ! EHTMLApplication.lo Form.lo Input.lo Label.lo MemBuf.lo \ ! Page.lo PageWriter.lo Request.lo Response.lo Session.lo \ ! SimpleTagAttribute.lo StyleAttribute.lo TagAttribute.lo \ ! TagRenderer.lo ! am_libehtml_la_OBJECTS = $(am__objects_1) libehtml_la_OBJECTS = $(am_libehtml_la_OBJECTS) + libsession_la_LIBADD = + am__objects_2 = DefaultSessionAddress.lo DefaultSessionDriver.lo + am_libsession_la_OBJECTS = $(am__objects_2) + libsession_la_OBJECTS = $(am_libsession_la_OBJECTS) + libsessionid_la_LIBADD = + am__objects_3 = DefaultSessionIDDriver.lo + am_libsessionid_la_OBJECTS = $(am__objects_3) + libsessionid_la_OBJECTS = $(am_libsessionid_la_OBJECTS) + binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) + PROGRAMS = $(bin_PROGRAMS) + am_mod_c_dss_OBJECTS = mod_c_dss-DefaultSessionServer.$(OBJEXT) \ + mod_c_dss-DefaultSessionAddress.$(OBJEXT) + mod_c_dss_OBJECTS = $(am_mod_c_dss_OBJECTS) + mod_c_dss_DEPENDENCIES = DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/cfgaux/depcomp *************** *** 80,85 **** CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ ! SOURCES = $(libehtml_la_SOURCES) ! DIST_SOURCES = $(libehtml_la_SOURCES) ETAGS = etags CTAGS = ctags --- 103,112 ---- CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ ! SOURCES = $(libdisksession_la_SOURCES) $(libehtml_la_SOURCES) \ ! $(libsession_la_SOURCES) $(libsessionid_la_SOURCES) \ ! $(mod_c_dss_SOURCES) ! DIST_SOURCES = $(libdisksession_la_SOURCES) $(libehtml_la_SOURCES) \ ! $(libsession_la_SOURCES) $(libsessionid_la_SOURCES) \ ! $(mod_c_dss_SOURCES) ETAGS = etags CTAGS = ctags *************** *** 110,113 **** --- 137,142 ---- DEFS = @DEFS@ DEPDIR = @DEPDIR@ + DOXYGEN = @DOXYGEN@ + DOXYGEN_SUBDIR = @DOXYGEN_SUBDIR@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ *************** *** 189,198 **** INCLUDE_DIRS = -I$(APR_0_INCLUDE) -I$(HTTPD_INCLUDE_DIR) -I$(srcdir)/../include AM_CXXFLAGS = $(INCLUDE_DIRS) ! lib_LTLIBRARIES = libehtml.la ! libehtml_la_SOURCES = EHTMLApplication.cpp Common.cpp PageWriter.cpp TagAttribute.cpp \ ! SimpleTagAttribute.cpp StyleAttribute.cpp TagRenderer.cpp Component.cpp Label.cpp \ ! Input.cpp Session.cpp Container.cpp Page.cpp Form.cpp Request.cpp Response.cpp ! libehtml_la_LDFLAGS = -shared -module all: all-am --- 218,240 ---- INCLUDE_DIRS = -I$(APR_0_INCLUDE) -I$(HTTPD_INCLUDE_DIR) -I$(srcdir)/../include AM_CXXFLAGS = $(INCLUDE_DIRS) ! lib_LTLIBRARIES = libehtml.la libsession.la libdisksession.la libsessionid.la ! EHTML_SOURCES = Common.cpp Component.cpp Container.cpp Dictionary.cpp \ ! EHTMLApplication.cpp Form.cpp Input.cpp Label.cpp MemBuf.cpp \ ! Page.cpp PageWriter.cpp Request.cpp Response.cpp Session.cpp \ ! SimpleTagAttribute.cpp StyleAttribute.cpp TagAttribute.cpp \ ! TagRenderer.cpp $(COMMON) ! libehtml_la_SOURCES = $(EHTML_SOURCES) libehtml_la_LDFLAGS = -shared -module + mod_c_dss_SOURCES = DefaultSessionServer.cpp DefaultSessionAddress.cpp + mod_c_dss_LDADD = -lpthread + mod_c_dss_CXXFLAGS = $(INCLUDE_DIRS) + LIBSESS_SOURCES = DefaultSessionAddress.cpp DefaultSessionDriver.cpp + libsession_la_SOURCES = $(LIBSESS_SOURCES) + libsession_la_LDFLAGS = -shared -module + libdisksession_la_SOURCES = DiskSessionDriver.cpp + libdisksession_la_LDFLAGS = -shared -module + LIBSESSID_SOURCES = DefaultSessionIDDriver.cpp + libsessionid_la_SOURCES = $(LIBSESSID_SOURCES) + libsessionid_la_LDFLAGS = -shared -module all: all-am *************** *** 255,260 **** --- 297,339 ---- rm -f "$${dir}/so_locations"; \ done + libdisksession.la: $(libdisksession_la_OBJECTS) $(libdisksession_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libdisksession_la_LDFLAGS) $(libdisksession_la_OBJECTS) $(libdisksession_la_LIBADD) $(LIBS) libehtml.la: $(libehtml_la_OBJECTS) $(libehtml_la_DEPENDENCIES) $(CXXLINK) -rpath $(libdir) $(libehtml_la_LDFLAGS) $(libehtml_la_OBJECTS) $(libehtml_la_LIBADD) $(LIBS) + libsession.la: $(libsession_la_OBJECTS) $(libsession_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libsession_la_LDFLAGS) $(libsession_la_OBJECTS) $(libsession_la_LIBADD) $(LIBS) + libsessionid.la: $(libsessionid_la_OBJECTS) $(libsessionid_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libsessionid_la_LDFLAGS) $(libsessionid_la_OBJECTS) $(libsessionid_la_LIBADD) $(LIBS) + install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + + uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + + clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done + mod_c_dss$(EXEEXT): $(mod_c_dss_OBJECTS) $(mod_c_dss_DEPENDENCIES) + @rm -f mod_c_dss$(EXEEXT) + $(CXXLINK) $(mod_c_dss_LDFLAGS) $(mod_c_dss_OBJECTS) $(mod_c_dss_LDADD) $(LIBS) mostlyclean-compile: *************** *** 267,274 **** --- 346,359 ---- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Component.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Container.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultSessionAddress.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultSessionDriver.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultSessionIDDriver.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Dictionary.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DiskSessionDriver.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EHTMLApplication.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Form.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Input.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Label.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemBuf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Page.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PageWriter.Plo@am__quote@ *************** *** 280,283 **** --- 365,370 ---- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TagAttribute.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TagRenderer.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_c_dss-DefaultSessionAddress.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_c_dss-DefaultSessionServer.Po@am__quote@ .cpp.o: *************** *** 302,305 **** --- 389,420 ---- @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + mod_c_dss-DefaultSessionServer.o: DefaultSessionServer.cpp + @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_c_dss_CXXFLAGS) $(CXXFLAGS) -MT mod_c_dss-DefaultSessionServer.o -MD -MP -MF "$(DEPDIR)/mod_c_dss-DefaultSessionServer.Tpo" -c -o mod_c_dss-DefaultSessionServer.o `test -f 'DefaultSessionServer.cpp' || echo '$(srcdir)/'`DefaultSessionServer.cpp; \ + @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/mod_c_dss-DefaultSessionServer.Tpo" "$(DEPDIR)/mod_c_dss-DefaultSessionServer.Po"; else rm -f "$(DEPDIR)/mod_c_dss-DefaultSessionServer.Tpo"; exit 1; fi + @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DefaultSessionServer.cpp' object='mod_c_dss-DefaultSessionServer.o' libtool=no @AMDEPBACKSLASH@ + @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_c_dss_CXXFLAGS) $(CXXFLAGS) -c -o mod_c_dss-DefaultSessionServer.o `test -f 'DefaultSessionServer.cpp' || echo '$(srcdir)/'`DefaultSessionServer.cpp + + mod_c_dss-DefaultSessionServer.obj: DefaultSessionServer.cpp + @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_c_dss_CXXFLAGS) $(CXXFLAGS) -MT mod_c_dss-DefaultSessionServer.obj -MD -MP -MF "$(DEPDIR)/mod_c_dss-DefaultSessionServer.Tpo" -c -o mod_c_dss-DefaultSessionServer.obj `if test -f 'DefaultSessionServer.cpp'; then $(CYGPATH_W) 'DefaultSessionServer.cpp'; else $(CYGPATH_W) '$(srcdir)/DefaultSessionServer.cpp'; fi`; \ + @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/mod_c_dss-DefaultSessionServer.Tpo" "$(DEPDIR)/mod_c_dss-DefaultSessionServer.Po"; else rm -f "$(DEPDIR)/mod_c_dss-DefaultSessionServer.Tpo"; exit 1; fi + @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DefaultSessionServer.cpp' object='mod_c_dss-DefaultSessionServer.obj' libtool=no @AMDEPBACKSLASH@ + @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_c_dss_CXXFLAGS) $(CXXFLAGS) -c -o mod_c_dss-DefaultSessionServer.obj `if test -f 'DefaultSessionServer.cpp'; then $(CYGPATH_W) 'DefaultSessionServer.cpp'; else $(CYGPATH_W) '$(srcdir)/DefaultSessionServer.cpp'; fi` + + mod_c_dss-DefaultSessionAddress.o: DefaultSessionAddress.cpp + @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_c_dss_CXXFLAGS) $(CXXFLAGS) -MT mod_c_dss-DefaultSessionAddress.o -MD -MP -MF "$(DEPDIR)/mod_c_dss-DefaultSessionAddress.Tpo" -c -o mod_c_dss-DefaultSessionAddress.o `test -f 'DefaultSessionAddress.cpp' || echo '$(srcdir)/'`DefaultSessionAddress.cpp; \ + @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/mod_c_dss-DefaultSessionAddress.Tpo" "$(DEPDIR)/mod_c_dss-DefaultSessionAddress.Po"; else rm -f "$(DEPDIR)/mod_c_dss-DefaultSessionAddress.Tpo"; exit 1; fi + @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DefaultSessionAddress.cpp' object='mod_c_dss-DefaultSessionAddress.o' libtool=no @AMDEPBACKSLASH@ + @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_c_dss_CXXFLAGS) $(CXXFLAGS) -c -o mod_c_dss-DefaultSessionAddress.o `test -f 'DefaultSessionAddress.cpp' || echo '$(srcdir)/'`DefaultSessionAddress.cpp + + mod_c_dss-DefaultSessionAddress.obj: DefaultSessionAddress.cpp + @am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_c_dss_CXXFLAGS) $(CXXFLAGS) -MT mod_c_dss-DefaultSessionAddress.obj -MD -MP -MF "$(DEPDIR)/mod_c_dss-DefaultSessionAddress.Tpo" -c -o mod_c_dss-DefaultSessionAddress.obj `if test -f 'DefaultSessionAddress.cpp'; then $(CYGPATH_W) 'DefaultSessionAddress.cpp'; else $(CYGPATH_W) '$(srcdir)/DefaultSessionAddress.cpp'; fi`; \ + @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/mod_c_dss-DefaultSessionAddress.Tpo" "$(DEPDIR)/mod_c_dss-DefaultSessionAddress.Po"; else rm -f "$(DEPDIR)/mod_c_dss-DefaultSessionAddress.Tpo"; exit 1; fi + @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DefaultSessionAddress.cpp' object='mod_c_dss-DefaultSessionAddress.obj' libtool=no @AMDEPBACKSLASH@ + @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_c_dss_CXXFLAGS) $(CXXFLAGS) -c -o mod_c_dss-DefaultSessionAddress.obj `if test -f 'DefaultSessionAddress.cpp'; then $(CYGPATH_W) 'DefaultSessionAddress.cpp'; else $(CYGPATH_W) '$(srcdir)/DefaultSessionAddress.cpp'; fi` + mostlyclean-libtool: -rm -f *.lo *************** *** 389,395 **** check-am: all-am check: check-am ! all-am: Makefile $(LTLIBRARIES) installdirs: ! for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done --- 504,512 ---- check-am: all-am check: check-am ! all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) ! install-binPROGRAMS: install-libLTLIBRARIES ! installdirs: ! for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(mkdir_p) "$$dir"; \ done *************** *** 420,425 **** clean: clean-am ! clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ ! mostlyclean-am distclean: distclean-am --- 537,542 ---- clean: clean-am ! clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ ! clean-libtool mostlyclean-am distclean: distclean-am *************** *** 441,445 **** install-data-am: ! install-exec-am: install-libLTLIBRARIES install-info: install-info-am --- 558,562 ---- install-data-am: ! install-exec-am: install-binPROGRAMS install-libLTLIBRARIES install-info: install-info-am *************** *** 467,485 **** ps-am: ! uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES ! .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ ! clean-libLTLIBRARIES clean-libtool ctags distclean \ ! distclean-compile distclean-generic distclean-libtool \ ! distclean-tags distdir dvi dvi-am html html-am info info-am \ ! install install-am install-data install-data-am install-exec \ ! install-exec-am install-info install-info-am \ ! install-libLTLIBRARIES install-man install-strip installcheck \ ! installcheck-am installdirs maintainer-clean \ ! maintainer-clean-generic mostlyclean mostlyclean-compile \ ! mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ ! tags uninstall uninstall-am uninstall-info-am \ uninstall-libLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. --- 584,606 ---- ps-am: ! uninstall-am: uninstall-binPROGRAMS uninstall-info-am \ ! uninstall-libLTLIBRARIES ! .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ ! clean-generic clean-libLTLIBRARIES clean-libtool ctags \ ! distclean distclean-compile distclean-generic \ ! distclean-libtool distclean-tags distdir dvi dvi-am html \ ! html-am info info-am install install-am install-binPROGRAMS \ ! install-data install-data-am install-exec install-exec-am \ ! install-info install-info-am install-libLTLIBRARIES \ ! install-man install-strip installcheck installcheck-am \ ! installdirs maintainer-clean maintainer-clean-generic \ ! mostlyclean mostlyclean-compile mostlyclean-generic \ ! mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ ! uninstall-am uninstall-binPROGRAMS uninstall-info-am \ uninstall-libLTLIBRARIES + + #SUBDIRS = dss_tool # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:33:07
|
Update of /cvsroot/mod-c/ehtml In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv16622 Modified Files: TODO Log Message: A better random number generator is needed. Index: TODO =================================================================== RCS file: /cvsroot/mod-c/ehtml/TODO,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** TODO 13 Jan 2006 23:20:17 -0000 1.1.1.1 --- TODO 8 Sep 2006 14:33:03 -0000 1.2 *************** *** 22,24 **** --- 22,25 ---- - check if application/x-www-form-urlencoded strings can be parsed faster and more efficiently as with my ad-hoc ParseURLEncodedArgs... + - Better random number generation. |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:31:03
|
Update of /cvsroot/mod-c/ehtml/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv15294/include Modified Files: Session.h Log Message: Session handling shifted from mod_c to EHTML (more work on this to come). Session handling is divided into: - Session ID generation (SessionIDDriver class/Session.h) - Session storage (SessionDrive class/Session.h) - Session usage: o serialization & marshalling, o accessing/setting session variables, (Session classs/Session.h) Index: Session.h =================================================================== RCS file: /cvsroot/mod-c/ehtml/include/Session.h,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Session.h 6 Mar 2006 08:00:34 -0000 1.8 --- Session.h 8 Sep 2006 14:30:58 -0000 1.9 *************** *** 22,46 **** #define _SESSION_H_ - #include "ehtml.h" - #include <time.h> #include <string> /** ! * A pointer to the function that should deallocate data provided in the first ! * parameter of <code>Session::ClearData</code>. */ ! typedef void (*DeallocatorFunc)(void *); /** ! * The default deallocator. This one does nothing because memory allocation in ! * the Session class is done with Apache's memory pools. These need not be ! * deallocated. ! * <p>If you allocate data with <code>apr_palloc</code>, then you can use the ! * default deallocator without the fear of memory leaks.</p> */ ! void DefaultDeallocator( void * Data ); ! class EHTMLApplication; /** --- 22,199 ---- #define _SESSION_H_ #include <time.h> + + #ifdef __cplusplus + + #include "ehtml.h" + #include "EHTMLApplication.h" + #include "Plugin.h" + #include "Dictionary.h" + #include "MemBuf.h" #include <string> + class EHTMLApplication; + class Session; + + class SessionID { + MemBuf _binary; + mutable std::string _base64; + mutable std::string _hex; + mutable std::string _urlencoded; + + mutable unsigned _binary_set: 1; + mutable unsigned _base64_set: 1; + mutable unsigned _hex_set: 1; + mutable unsigned _url_set: 1; + + public: + SessionID(); + SessionID(const SessionID& id); + SessionID(void* b, size_t nbytes, bool dup = false); + ~SessionID(); + + MemBuf& binary() throw (const char*); + const MemBuf& binary() const throw (const char*); + bool binary(MemBuf&); + + std::string& base64() throw (const char*); + const std::string& base64() const throw (const char*); + bool base64(std::string&); + + std::string& hex() throw (const char*); + const std::string& hex() const throw (const char*); + bool hex(std::string&); + + std::string& urlencoded() throw (const char*); + const std::string& urlencoded() const throw (const char*); + bool urlencoded(std::string&); + }; + + class SessionIDDriver; /** ! * Session id generation class. ! * Each subclass provide a different algorightm for session id generation. */ ! class SessionIDDriver: public Pluggable<SessionIDDriver> { ! public: ! /** ! * Set arguments for algorithm tunning. May be called more than once. ! * @return false on error. true on success. ! */ ! virtual bool SetArgs(const std::string& arg) = 0; ! virtual bool ValidID(SessionID& id) = 0; ! virtual SessionID GenerateID() = 0; ! }; ! ! class SessionDriver; ! class SessionDriver: public Pluggable<SessionDriver> { ! EHTMLApplication* _app; ! public: ! /** ! * SessionDrvier default constructor (must not be used). ! */ ! SessionDriver(): _app(NULL) { ! } ! ! /** ! * SessionDriver destructor. ! */ ! virtual ~SessionDriver(); ! ! /** ! * Sets arguments. May be called more than once. ! * @return false on error, true otherwise. ! */ ! virtual bool SetArgs(const std::string& arg) = 0; ! ! /** ! * Sets the application to use. May be called more than once. ! * @return false on error, true otherwise. ! */ ! virtual void Application(EHTMLApplication* app) { _app = app; } ! ! /** ! * Connect to backend. ! * @return false on error. ! */ ! virtual bool Connect() = 0; ! ! /** ! * Disconnect from backend. ! * @return false on error. ! */ ! virtual bool Disconnect() = 0; ! ! /** ! * Retrieve a session from the store. ! * @param id ! * id of the session to retrieve ! * @return NULL on error or if session is not found. ! */ ! virtual Session* Get(const SessionID& id) = 0; ! ! /** ! * Retrieve a session from query string or cookie from the store. ! * The session is locked to avoid overlapping updates. ! */ ! virtual Session* Get(); ! ! /** ! * Save the session in the store. ! * @return false on error. ! */ ! virtual bool Save(Session*) = 0; ! ! /** ! * Remove the session (id) from the store. ! * @return false if session is not found or if there is no connection ! * to the backend. ! */ ! virtual bool Remove(Session*) = 0; ! ! /** ! * Release the session lock. ! */ ! virtual bool Release(Session*) = 0; ! }; ! #define EXTERNC extern "C" ! #else /* ifdef __cplusplus */ ! #define EXTERNC extern ! #endif /** ! * Registers a session driver. ! * Registers the session driver "<param>driver_name</param>" located in ! * <param>filename</param>. ! * Note that this has C linkeage. ! * @return 0 on success, a negative value on error. */ ! EXTERNC int registerSessionDriver(const char* driver_name, const char* filename); ! /** ! * Selects a session driver (and sets the argument). ! * See each session driver for specific format and values of ! * <param>arg</param>. ! * @return 0 on success, a negative value on error. ! */ ! EXTERNC int useSessionDriver(const char* name, const char* arg); ! ! /** ! * Registers a session id generation driver. ! * Registers the session driver "<param>driver_name</param>" located in ! * <param>filename</param>. ! * Note that this has C linkeage. ! * @return 0 on success, a negative value on error. ! */ ! EXTERNC int registerSessionIDDriver(const char* driver_name, const char* filename); ! /** ! * Selects a session id generation driver (and sets the argument). ! * See each session driver for specific format and values of ! * <param>arg</param>. ! * @return 0 on success, a negative value on error. ! */ ! EXTERNC int useSessionIDDriver(const char* name, const char* arg); ! ! #ifdef __cplusplus /** *************** *** 51,431 **** * application in the 'init' stage. If there is no session to restore, the * application does not create one! EHTML is designed not to use per session ! * data if not needed by the application. A session is created if and only if an ! * old session has not been restored AND the developer first writes some session ! * data.</p> * <p>Session data is written to the server in the 'finish' stage.</p> */ ! class Session ! { ! public: ! /** ! * Initialises a connection with the session server. This function has ! * no effect if a connection has already been initialised. ! */ ! int InitConnection(); ! /** ! * Closes a connection with the session server. This function has no ! * effect if a connection has already been closed. ! */ ! int CloseConnection(); ! /** ! * Returns the ID of the current session. ! * ! * @return A binary array containing the Id. This function returns ! * <code>NULL</code> if a session is not valid. ! * <p>Call the <code>GetIdSize</code> function to obtain the ! * size of this array.</p> ! */ ! const void * GetId() const { return Data.Id; } ! /** ! * Returns the size of the session ID. ! * ! * @return the size of the session ID. This function should not be used ! * to determine whether a session is valid or not. Use ! * <code>IsValid</code> or <code>GetId</code> ! * instead. ! */ ! int GetIdSize() const { return Data.IdSize; } ! /** ! * Returns the duration of the session in minutes. ! * ! * @return the duration of the session in minutes. ! */ ! int GetDuration() const { return Data.Duration; } ! /** ! * Sets the duration of a session in minutes. This method fails if the ! * session is not valid or not connected. ! * ! * @param Duration ! * The duration of a session in minutes. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int SetDuration( int Duration ); ! /** ! * Returns the time (in seconds since 1970) when the session was ! * created. ! * ! * @return the time (in seconds since 1970) when the session was ! * created. ! */ ! time_t GetCreationTime() const { return Data.SessionStarted; } ! /** ! * Returns the time (in seconds since 1970) when the session was last ! * accessed. ! * ! * @return the time (in seconds since 1970) when the session was last ! * accessed. ! */ ! time_t GetAccessTime() const { return Data.LastAccess; } ! /** ! * Returns the time (in seconds since 1970) when the session was last ! * modified (with <code>Store</code>). ! * ! * @return the time (in seconds since 1970) when the session was last ! * modified (with <code>Store</code>). ! */ ! time_t GetModificationTime() const { return Data.Modified; } ! /** ! * Tries to write current data to the server. This method fails if the ! * session is not valid or not connected. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Store(); ! /** ! * Tries to reload the data from the server. This method fails if the ! * session is not valid or not connected. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Reload(); ! /** ! * Returns stored data with the given name. ! * ! * @param Data ! * The method will store the pointer to the data into this ! * parameter. ! * ! * @return The size of the data array. ! */ ! int GetData( void ** Data ); ! /** ! * Sets the data for this session. ! * <p>Any previous data is deallocated with the current deallocator. So ! * never set the data which is already set.</p> ! * ! * @param Data ! * The actual data. ! * ! * @param DataSize ! * The size of the data array. ! * ! * @param Deallocator ! * The function with which to deallocate the newly set data ! * upon destruction. ! * <p>If you allocate data with <code>apr_palloc</code>, ! * then you don't have to provide a deallocator.</p> ! */ ! void SetData( void * Data = NULL, int DataSize = 0, DeallocatorFunc Deallocator = NULL ); ! /** ! * Deletes data as stored in the session. It deallocates data with the ! * current deallocator. ! */ ! void DeleteData(); ! /** ! * Unregisters the current session. The session is 'lost forever' with ! * this call. ! * <p>The session becomes <b>invalid</b> after the call of ! * this method and can not be used anymore (the behaviour of many ! * methods of this class is undefined when the session is invalid).</p> ! * <p>The connection is also closed with this method.</p> ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Unregister(); ! /** ! * Returns a value that indicates whether this session object is valid ! * or not. ! */ ! bool IsValid() const { return Data.Id != NULL; } ! /** ! * Indicates whether a connection with the session server has been ! * initialised. ! */ ! bool IsConnected() const { return ConnectionInited; } ! /** ! * Returns a usable string that represents the ID of the current ! * session. ! * ! * @return Returns a string representation of this session. ! */ ! const std::string & GetIdString() const; ! /** ! * Tries to restore the session. ! * <p>If the argument <code>Id</code> equals <code>NULL</code>, then ! * this method tries to look for the ID in the cookie with the name ! * <code><b>SessionIdName</b></code>.</p> ! * <p>If the application is configured to be cookieless and the ! * argument <code>Id</code> equals <code>NULL</code>, then this method ! * tries to find the name <code><b>SessionIdName</b></code> in the query ! * string.</p> ! * <p>This method returns a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the session ! * has not been restored, <code>NULL</code> is returned to indicate the ! * error.</p> ! * ! * @param App ! * A reference to the main EHTML application which contains ! * mod_c configuration structures and the Session Management ! * API. ! * ! * @param Id ! * The Id of the session to be restored (may be ! * <code>NULL</code> to automatically resolve the Id from a ! * cookie or from the query). ! * ! * @param IdSize ! * The size of the Id. ! * ! * @return a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the ! * session has not been restored, <code>NULL</code> is returned ! * to indicate the error. ! * <p><b>Note</b>: You mustn't delete the returned session ! * when you stop using it - sessions are deleted automatically ! * by <code>EHTMLApplication</code> in the finish stage where ! * <code>EHTMLApplication</code> calls the ! * <code>EHTMLApplication::ShutSessionsDown</code>.</p> ! */ ! static Session * RestoreSession( EHTMLApplication & App, const void * Id = NULL, int IdSize = 0 ); ! /** ! * Tries to restore the session. ! * <p>This method returns a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the session ! * has not been restored, <code>NULL</code> is returned to indicate the ! * error.</p> ! * ! * @param App ! * A reference to the main EHTML application which contains ! * mod_c configuration structures and the Session Management ! * API. ! * ! * @param Id ! * The string representation of the Id of the session to be ! * restored. ! * ! * @return a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the ! * session has not been restored, <code>NULL</code> is returned ! * to indicate the error. ! * <p><b>Note</b>: You mustn't delete the returned session ! * when you stop using it - sessions are deleted automatically ! * by <code>EHTMLApplication</code> in the finish stage where ! * <code>EHTMLApplication</code> calls the ! * <code>EHTMLApplication::ShutSessionsDown</code>.</p> ! */ ! static Session * RestoreSession( EHTMLApplication & App, const std::string & Id ); ! /** ! * Tries to restore the session. ! * <p>This method returns a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the session ! * has not been restored, <code>NULL</code> is returned to indicate the ! * error.</p> ! * ! * @param App ! * A reference to the main EHTML application which contains ! * mod_c configuration structures and the Session Management ! * API. ! * ! * @param Id ! * The string representation of the Id of the session to be ! * restored. ! * ! * @return a valid pointer to a restored sesstion if ! * and only if the session has been completely restored. If the ! * session has not been restored, <code>NULL</code> is returned ! * to indicate the error. ! * <p><b>Note</b>: You mustn't delete the returned session ! * when you stop using it - sessions are deleted automatically ! * by <code>EHTMLApplication</code> in the finish stage where ! * <code>EHTMLApplication</code> calls the ! * <code>EHTMLApplication::ShutSessionsDown</code>.</p> ! */ ! static Session * RestoreSession( EHTMLApplication & App, const char * Id ); ! /** ! * Creates a new session. It registers an Id in the session manager and ! * stores the acquired configuration in the <code>PerSessionData</code> ! * structure. ! * ! * @param App ! * A reference to the main EHTML application which contains ! * mod_c configuration structures and the Session Management ! * API. ! * ! * @param IdSize ! * The desired size of the Id. ! * ! * @param Duration ! * The desired session duration. ! * ! * @return a valid pointer to a new session on success, otherwise it ! * returns <code>NULL</code>. ! * <p><b>Note</b>: You mustn't delete the returned session ! * when you stop using it - sessions are deleted automatically ! * by <code>EHTMLApplication</code> in the finish stage where ! * <code>EHTMLApplication</code> calls the ! * <code>EHTMLApplication::ShutSessionsDown</code>.</p> ! */ ! static Session * CreateSession( EHTMLApplication & App, int IdSize = 0, int Duration = 0 ); ! /** ! * The key with which one should name the cookie or the query string ! * that contains the main session ID string. ! */ ! static const std::string SessionIdName; ! protected: ! friend class EHTMLApplication; ! /** ! * The default constructor is disabled and throws errors. ! */ ! Session() throw ( const char * ); ! /** ! * Creates a new and uninitialised session. ! */ ! Session( EHTMLApplication & App ); ! ~Session(); ! /** ! * Recovers data from the server. If the session is not yet registered ! * this method fails. ! * ! * @param Id ! * The Id of the session to be restored (may be ! * <code>NULL</code> to automatically resolve the Id from a ! * cookie or from the query). ! * ! * @param IdSize ! * The size of the Id. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Restore( void * Id = NULL, int IdSize = 0 ); ! /** ! * Recovers data from the server. If the session is not yet registered ! * this method fails. ! * ! * @param Id ! * The Id of the session to be restored. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Restore( const char * Id ); ! /** ! * Recovers data from the server. If the session is not yet registered ! * this method fails. ! * ! * @param Id ! * The Id of the session to be restored. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Restore( const std::string & Id ); ! /** ! * Registers a new session. Closes the existing session if one is open. ! * ! * @return Returns <code>EHTML_OK</code> on success. ! */ ! int Register(); ! /** ! * Sets the desired size of the ID and the duration of the session. ! * This procedure has no effect if the session is already valid. ! * ! * @param IdSize ! * The desired size of the Id. ! * ! * @param Duration ! * The desired session duration. ! */ ! void SetInitConfig( int IdSize, int Duration ); ! ! protected: ! /** ! * This record stores configuration data as returned by the session ! * manager. ! */ ! PerSessionData Data; ! /** ! * Current deallocator. ! */ ! DeallocatorFunc Dealloc; ! /** ! * The owning application. ! */ ! EHTMLApplication * Application; ! /** ! * The session API to use. ! */ ! ses_api_t * SessionApi; ! /** ! * Driver data. ! */ ! void * DrData; ! /** ! * Request context. ! */ ! __request_context * ReqCon; ! /** ! * The string representation of the id. ! */ ! std::string EncodedId; ! /** ! * Indicates whether a connection was initialized or not. ! */ ! bool ConnectionInited; ! /** ! * Indicates whether this session is broken. ! */ ! bool IsBroken; }; #endif /*_SESSION_H_*/ --- 204,360 ---- * application in the 'init' stage. If there is no session to restore, the * application does not create one! EHTML is designed not to use per session ! * data if not needed by the application. A session is created if and only if ! * an old session has not been restored AND the developer first writes some ! * session data.</p> * <p>Session data is written to the server in the 'finish' stage.</p> */ ! class Session: public Dictionary { ! protected: ! static bool _cookie_less; /**< true iff the session is cookie-based */ ! static std::string _session_id_name; /**< cookie name for session id */ ! public: ! /** ! * RO accessor of @ref _cookie_less. ! * @return true iff session is NOT cookie-based. ! */ ! static bool CookieLess() { return _cookie_less; } ! ! /** ! * WO accessor of @ref _cookie_less. ! * @param cookie_less new value of _cookie_less. ! */ ! static void CookieLess(bool cookie_less) { ! _cookie_less = cookie_less ? true : false; ! } ! ! /** ! * RO accessor of @ref _session_id_name. ! * @return the name of the cookie where the session id is stored. ! */ ! static const std::string& SessionIDName() { ! return _session_id_name; ! } ! ! /** ! * WO accessor of @ref _session_id_name. ! * @param s the name of the cookie. ! */ ! static void SessionIDName(const std::string& s) { ! _session_id_name = s; ! } ! ! protected: ! time_t _expires; /**< expiration date/time */ ! time_t _started; /**< start time */ ! time_t _last_access; /**< last access time */ ! time_t _modification; /**< last modification time */ ! SessionID _id; /**< this session id */ ! ! public: ! /** ! * Default session constructor. ! */ ! Session(): _expires(0) { ; } ! ! /** ! * Session constructor. ! */ ! Session(const SessionID& __id): _expires(0), _id(__id) { ; } ! ! /** ! * Session destructor. ! */ ! virtual ~Session(); ! ! //@todo I'm not happy with this, anyone can modify last access?? ! //RW accessors should be friend of SessionDriver. ! ! /** ! * Sets session last access date/time. ! */ ! void LastAccess(time_t __last_access) { _last_access = __last_access; } ! ! /** ! * Gets session last access date/time. ! */ ! time_t LastAccess(void) { return _last_access; } ! ! /** ! * Sets session modification date/time. ! */ ! void Modification(time_t __mtime) { _modification = __mtime; } ! ! /** ! * Gets session modification date/time. ! */ ! time_t Modification(void) { return _modification; } ! ! /** ! * Sets session start date/time. ! */ ! void Started(time_t __started) { _started = __started; } ! ! /** ! * Gets session start date/time. ! */ ! time_t Started(void) { return _started; } ! ! /** ! * Sets session expiration date/time. ! */ ! void Expires(time_t __expires) { _expires = __expires; } ! ! /** ! * Gets session expiration date/time. ! */ ! time_t Expires(void) { return _expires; } ! ! //{set,get,unset}Value: use operator[](), find(), erase(). ! ! /** ! * Gets session id. ! */ ! ! const SessionID& ID() const { return _id; } ! /** ! * Gets session id. ! */ ! SessionID& ID() { return _id; } ! ! /** ! * Session serialization. ! * ! * Represents session object in a printable (multiline) string, ! * suitable for saving in a platform-indedent (!?) maner. ! * ! * @todo This should be a const memeber. But making dict as mutable ! * is not an option. ! */ ! std::string Serialize(); ! ! /** ! * Session marshalling. ! * ! * This is the opposite of serialization. Given a textual printable ! * (multiline) representation, this method restores the session state. ! */ ! bool Marshall(const std::string& s); ! ! friend std::ostream& operator << (std::ostream& o, Session& s); ! friend std::istream& operator >> (std::istream& i, Session& s); }; + /** + * Session serialization operator (@see Session::serialize). + */ + std::ostream& operator << (std::ostream& o, Session& s); + + /** + * Session marshalling operator (@see Session::marshall). + */ + std::istream& operator >> (std::istream& i, Session& s); + + #endif + #endif /*_SESSION_H_*/ |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:31:02
|
Update of /cvsroot/mod-c/ehtml/src In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv15294/src Modified Files: Session.cpp Added Files: DefaultSessionAddress.h DefaultSessionDriver.h DefaultSessionProtocol.h DefaultSessionAddress.cpp DefaultSessionDriver.cpp DefaultSessionIDDriver.cpp DefaultSessionServer.cpp DiskSessionDriver.cpp Log Message: Session handling shifted from mod_c to EHTML (more work on this to come). Session handling is divided into: - Session ID generation (SessionIDDriver class/Session.h) - Session storage (SessionDrive class/Session.h) - Session usage: o serialization & marshalling, o accessing/setting session variables, (Session classs/Session.h) --- NEW FILE: DefaultSessionAddress.h --- #ifndef __DEFAULT_SESSION_ADDRESS_H_ #define __DEFAULT_SESSION_ADDRESS_H_ #include <string> extern "C" { #include <sys/socket.h> // ipv4 sockets #include <netinet/in.h> #include <netinet/ip.h> /* superset of previous */ #include <arpa/inet.h> // unix sockets #include <sys/un.h> #include <unistd.h> }; class Address { public: int address_family, protocol_family; union { struct sockaddr _addr; struct sockaddr_un _unix; struct sockaddr_in _inet; } addr; size_t addr_len; Address(); ~Address(); bool SetArgs (const std::string& arg); }; #endif --- NEW FILE: DiskSessionDriver.cpp --- #include <Session.h> #include <Common.h> #include <unistd.h> #include <iostream> #include <sstream> #include <fstream> using namespace std; class DiskSessionDriver: public SessionDriver { string spool; bool connected; uint32_t collect_prob; time_t old_enough; string filename(const string& id); string locked_filename(const string& id); public: DiskSessionDriver(): connected(false), collect_prob(1), old_enough(86400) { ; } DiskSessionDriver(const char* _name): connected(false), collect_prob(1), old_enough(86400) { name(_name); } virtual ~DiskSessionDriver() { ; } virtual bool SetArgs(const std::string& arg); virtual bool Connect(); virtual bool Disconnect(); virtual Session* Get(const SessionID& id); virtual bool Save(Session*); virtual bool Remove(Session*); virtual bool Release(Session*); bool mayBeCollect(); }; string DiskSessionDriver::filename(const string& hexid) { return spool + "/" + hexid; } string DiskSessionDriver::locked_filename(const string& hexid) { return filename(hexid) + ",$$"; } bool DiskSessionDriver::mayBeCollect() { uint32_t i = random(); time_t now = time(NULL); if (i < collect_prob) { // find $spool -type f -mtime +old_enough DIR* dh = opendir(spool.c_str()); if (dh == NULL) return false; struct dirent* de; while (de = readdir(dh)) { string path = spool + " " + de->d_name; struct stat st; if (stat(path.c_str(), &st) < 0) return false; if (!S_ISREG(st.st_mode)) continue; if (st.st_mtime + old_enough < now && st.st_ctime + old_enough < now) { unlink(path.c_str()); continue; } //@TODO: we should check for expired sessions //old_enough should cover this. } closedir(dh); } return true; } bool DiskSessionDriver::SetArgs(const string& arg) { //@TODO: should check that no session is open. istringstream i(arg.c_str()); string _arg; while (i >> _arg) { if (!strncmp(_arg.c_str(),"spool=",6)) { spool = _arg.c_str() + 6; } else if (!strncmp(_arg.c_str(), "collect_prob=", 13)) { double p = xatod(_arg.c_str()+13); if (p > 1 || p < 0) return false; collect_prob = uint32_t(p * RAND_MAX); if (collect_prob == 0 && p != 0.0) collect_prob = 1; } else if (!strncmp(_arg.c_str(), "old_enough=", 11)) { char* end; old_enough = strtoul(_arg.c_str()+11, &end, 10); if (*end) return false; } else return false; } return true; } bool DiskSessionDriver::Connect() { if (connected) return false; return connected = is_directory(spool.c_str()); } bool DiskSessionDriver::Disconnect() { if (connected) { connected = false; return true; } return false; } Session* DiskSessionDriver::Get(const SessionID& id) { if (!connected) return NULL; mayBeCollect(); string name = filename(id.hex()); string lname = locked_filename(id.hex()); if (rename(name.c_str(), lname.c_str())) return NULL; Session* dev = new Session(); ifstream in(lname.c_str()); in >> *dev; if (!in.eof()) { delete dev; return NULL; } if (dev->Expires() < time(NULL)) { unlink(lname.c_str()); delete dev; dev = NULL; } //should check if !expired.... return dev; } bool DiskSessionDriver::Save(Session* s) { if (!connected) return false; string lfile = locked_filename(s->ID().hex()); ofstream out(lfile.c_str()); if (!out) return false; out << *s; return true; } bool DiskSessionDriver::Remove(Session* s) { if (!connected) return false; unlink(filename(s->ID().hex()).c_str()); unlink(locked_filename(s->ID().hex()).c_str()); } bool DiskSessionDriver::Release(Session* s) { if (!connected) return false; return rename(locked_filename(s->ID().hex()).c_str(), filename(s->ID().hex()).c_str()) == 0 ? true : false; } extern "C" SessionDriver* Disk() { return new DiskSessionDriver("Disk"); } --- NEW FILE: DefaultSessionDriver.h --- /*************************************************************************** * Copyright (C) 2005 by Matej Urbas * * mat...@gm... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, 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 License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _DEF_SESSION_DRIVER_H_ #define _DEF_SESSION_DRIVER_H_ #include "Session.h" #include "DefaultSessionAddress.h" class DefaultSessionDriver: public SessionDriver { /** * File descriptor. */ Address addr; int fd; void init(); public: DefaultSessionDriver(); DefaultSessionDriver(const char* name); ~DefaultSessionDriver(); virtual bool SetArgs(const std::string& arg); virtual bool Connect(); virtual bool Disconnect(); virtual Session* Get(const SessionID& id); int Socket(); bool Bind(); virtual bool Save(Session*); virtual bool Remove(Session*); virtual bool Release(Session*); }; #endif --- NEW FILE: DefaultSessionAddress.cpp --- #include "DefaultSessionAddress.h" #include <sstream> using namespace std; Address::Address() { address_family = protocol_family = 0; addr_len = 0; } Address::~Address() { } bool Address::SetArgs (const string& arg) { istringstream s(arg); string opt; while (s >> opt) { if (!strncmp("addr=",opt.c_str(),5)) { string _addr(opt.c_str()+5); if (!strncmp("unix://",_addr.c_str(),7)) { address_family = AF_UNIX; protocol_family = PF_UNIX; addr_len = sizeof(sockaddr_un); addr._unix.sun_family = AF_UNIX; strncpy(addr._unix.sun_path,_addr.c_str()+7,sizeof(addr._unix.sun_path)); } else if (!_addr[0] == '/') { address_family = AF_UNIX; protocol_family = PF_UNIX; addr_len = sizeof(sockaddr_un); addr._unix.sun_family = AF_UNIX; strncpy(addr._unix.sun_path,_addr.c_str(),sizeof(addr._unix.sun_path)); } else if ("inet://",_addr.c_str(),7) { char host[16]; unsigned short port; if (sscanf(_addr.c_str()+7,"%16[.0-9]:%hu", host, &port) != 2) { errno = EINVAL; return false; } address_family = AF_INET; protocol_family = PF_INET; addr_len = sizeof(sockaddr_in); addr._inet.sin_family = AF_INET; addr._inet.sin_port = htons(port); if (!inet_aton(host, &addr._inet.sin_addr)) { errno = EINVAL; return false; } } else { errno = EINVAL; return false; } } else { errno = EINVAL; return false; } } return true; } Index: Session.cpp =================================================================== RCS file: /cvsroot/mod-c/ehtml/src/Session.cpp,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Session.cpp 3 Mar 2006 14:45:17 -0000 1.11 --- Session.cpp 8 Sep 2006 14:30:59 -0000 1.12 *************** *** 20,408 **** #include <Common.h> ! #include <Session.h> ! #include <EHTMLApplication.h> #include <Request.h> ! ! #include <string> using namespace std; ! Session::Session() throw ( const char * ) ! { ! throw "The default constructor is disabled for sessions."; ! } ! ! Session::~Session() ! { ! CloseConnection(); ! DeleteData(); ! } ! Session::Session( EHTMLApplication & App ) ! : Application( &App ), ConnectionInited( false ), IsBroken( false ) ! { ! ReqCon = App.GetRequestContext(); ! mod_c_dir_config * dir = ReqCon->dir_config; ! // Set the ID, Data and Capacity to to NULL ! Data.Id = NULL; ! Data.Capacity = 0; ! Data.Data = NULL; ! Data.Duration = dir->session_duration; ! Data.IdSize = dir->key_size; ! // Get the session API ! SessionApi = dir->session_funcs; ! ! // Set the default deallocator ! Dealloc = NULL; } ! int Session::InitConnection() ! { ! if ( !ConnectionInited ) ! { ! int retVal = EHTML_OK; ! if ( SessionApi->InitConnection ) ! retVal = SessionApi->InitConnection( &Data, ReqCon, &DrData ); ! IsBroken = ( retVal != EHTML_OK ); ! ConnectionInited = !IsBroken; ! return retVal; ! } ! else ! return EHTML_OK; } ! int Session::CloseConnection() ! { ! if ( ConnectionInited && SessionApi->EndConnection ) ! { ! ConnectionInited = false; ! return SessionApi->EndConnection( &Data, ReqCon, DrData ); ! } ! else ! return EHTML_OK; } ! int Session::SetDuration( int Duration ) ! { ! if ( IsValid() && IsConnected() ) ! { ! // Save the old duration in case it didn't get updated ! int tmpDur = Data.Duration; ! // Set the new duration ! Data.Duration = Duration; ! int retVal = SessionApi->SetDuration( &Data, ReqCon, DrData ); ! // Change the duration back to the previous value if the call failed ! if ( retVal != EHTML_OK ) ! Data.Duration = tmpDur; ! return retVal; ! } ! else ! return EHTML_ERR; } ! int Session::Store() ! { ! if ( IsValid() && IsConnected() ) ! return SessionApi->SetSessionData( &Data, ReqCon, DrData ); ! else ! return EHTML_ERR; } ! int Session::Reload() ! { ! if ( IsValid() && IsConnected() ) ! { ! void * tmp = Data.Data; ! int tmpDataSize = Data.DataSize; ! int tmpCapacity = Data.Capacity; ! int retVal = SessionApi->GetSessionData( &Data, ReqCon, DrData ); ! ! // Free the data if it changed... ! if ( retVal == EHTML_OK && tmp != Data.Data && tmp != NULL && Dealloc ) ! { ! Dealloc( tmp ); ! Dealloc = NULL; ! } ! else if ( Data.Data != tmp ) ! { ! // If the call failed and the data got changed, don't update ! Data.Data = tmp; ! Data.DataSize = tmpDataSize; ! Data.Capacity= tmpCapacity; ! } ! ! return retVal; ! } ! else ! return EHTML_OK; } ! int Session::GetData( void ** Data ) ! { ! *Data = this->Data.Data; ! return this->Data.DataSize; } ! void Session::SetData( void * Data, int DataSize, DeallocatorFunc Deallocator ) ! { ! // Deallocate old data ! if ( Dealloc && this->Data.Data ) ! Dealloc( this->Data.Data ); ! // Set the new deallocator and new data ! Dealloc = Deallocator; ! this->Data.Data = Data; ! this->Data.Capacity = this->Data.DataSize = DataSize; } ! void Session::DeleteData() ! { ! if ( Dealloc && Data.Data ) ! Dealloc( Data.Data ); ! Data.Data = 0; ! Data.Capacity = 0; ! Data.DataSize = 0; } ! int Session::Unregister() ! { ! if ( IsValid() && IsConnected() ) ! { ! SessionApi->UnregisterID( &Data, ReqCon, DrData ); ! CloseConnection(); ! Data.Id = 0; ! } ! ! return EHTML_OK; } ! const std::string & Session::GetIdString() const ! { ! if ( EncodedId.empty() && IsValid() ) ! { ! int len = ( Data.IdSize << 1 ) + 1; ! char * tmp = new char[ len ]; ! int retVal = GetStringFromByte( tmp, len, (unsigned char*) Data.Id, Data.IdSize ); ! if ( retVal > 0 ) ! const_cast< Session* >( this )->EncodedId = tmp; ! delete tmp; ! } ! return EncodedId; } ! Session * Session::RestoreSession( EHTMLApplication & App, const void * Id, int IdSize ) ! { ! Session * tmp = new Session( App ); ! ! // Copy the Id... ! void * tmpId = NULL; ! if ( Id != NULL && IdSize > 0 ) ! { ! tmpId = apr_palloc( App.GetRequestContext()->r->pool, IdSize ); ! memcpy( tmpId, Id, IdSize ); ! } ! // Initialize the connection ! if ( tmp->InitConnection() == EHTML_OK ) ! // Register the session ! tmp->Restore( tmpId, IdSize ); ! // Was the session restored correctly? ! if ( tmp->IsValid() ) ! { ! App.OpenSessions.push_back( tmp ); ! return tmp; ! } ! else ! { ! delete tmp; ! return NULL; ! } } ! Session * Session::RestoreSession( EHTMLApplication & App, const std::string & Id ) ! { ! if ( Id.length() > 0 ) ! { ! Session * tmp = new Session( App ); ! // Initialize the connection ! if ( tmp->InitConnection() == EHTML_OK ) ! // Register the session ! tmp->Restore( Id ); ! // Was the session restored correctly? ! if ( tmp->IsValid() ) ! { ! App.OpenSessions.push_back( tmp ); ! return tmp; ! } ! else ! { ! delete tmp; ! return NULL; ! } ! } ! else ! return NULL; } - Session * Session::RestoreSession( EHTMLApplication & App, const char * Id ) - { - if ( Id && *Id ) - { - Session * tmp = new Session( App ); - // Initialize the connection - if ( tmp->InitConnection() == EHTML_OK ) - // Register the session - tmp->Restore( Id ); ! // Was the session restored correctly? ! if ( tmp->IsValid() ) ! { ! App.OpenSessions.push_back( tmp ); ! return tmp; ! } ! else ! { ! delete tmp; ! return NULL; ! } ! } ! else ! return NULL; } ! Session * Session::CreateSession( EHTMLApplication & App, int IdSize, int Duration ) ! { ! Session * tmp = new Session( App ); ! // Set the Id size and duration ! tmp->SetInitConfig( IdSize, Duration ); ! // Initialize the connection ! if ( tmp->InitConnection() == EHTML_OK ) ! // Register the session ! tmp->Register(); ! ! // Was the session registered correctly? ! if ( tmp->IsValid() ) ! { ! App.OpenSessions.push_back( tmp ); ! return tmp; ! } ! else ! { ! delete tmp; ! return NULL; ! } } ! int Session::Register() ! { ! // The session should be inited first ! if ( !IsConnected() ) ! return EHTML_ERR; ! // Register a new session ! int retVal = SessionApi->RegisterID( &Data, ReqCon, DrData ); ! if ( retVal != EHTML_OK ) ! Data.Id = NULL; ! return retVal; } ! int Session::Restore( const string & Id ) ! { ! // The session should be inited first ! if ( !IsConnected() ) ! return EHTML_ERR; ! if ( Id.length() > 0 ) ! { ! // We have found the Id ! EncodedId = Id; ! // Convert it into a more understandable format ! int tmp = ( Id.length() >> 1 ) + 1; ! Data.Id = apr_palloc( ReqCon->r->pool, tmp ); ! if ( ( Data.IdSize = GetByteFromString( (unsigned char*) Data.Id, tmp, EncodedId.c_str() ) ) > 0 ) ! { ! // We have the Id, get the data ! tmp = SessionApi->GetSessionData( &Data, ReqCon, DrData ); ! // If not successful, invalidate the session ! if ( tmp != EHTML_OK ) ! Data.Id = NULL; ! return tmp; ! } ! else ! // The conversion did not succeed ! Data.Id = NULL; ! } ! ! return EHTML_ERR; } ! int Session::Restore( const char * Id ) ! { ! if ( Id && *Id ) ! { ! // We have found the Id ! EncodedId = Id; ! return Restore( EncodedId ); ! } ! ! return EHTML_ERR; } ! int Session::Restore( void * Id, int IdSize ) ! { ! // The session should be inited first ! if ( !IsConnected() ) ! return EHTML_ERR; ! ! // The restore method should not be called after a session has already been ! // created. ! if ( IsValid() ) ! return EHTML_INVALID_CALL; ! if ( Id == NULL ) ! { ! // Search for the Id in the arguments (or in the cookie) ! if ( Application->GetRequestContext()->dir_config->cookieless ) ! { ! // Search in the query string ! const string * str = Application->GetRequest()->GetArgument( Session::SessionIdName ); ! if ( str ) ! return Restore( *str ); ! } ! else ! { ! // Search in the cookies ! // TODO: Search for the cookie ! } ! ! return EHTML_ERR; ! } ! else ! { ! // Set the desired Id ! Data.Id = Id; ! Data.IdSize = IdSize; ! // Get the data ! int retVal = SessionApi->GetSessionData( &Data, ReqCon, DrData ); ! if ( retVal != EHTML_OK ) ! Data.Id = NULL; ! // Return the return code ! return retVal; ! } } ! void Session::SetInitConfig( int IdSize, int Duration ) ! { ! if ( !IsValid() ) ! { ! Data.Duration = ( Duration > 0 ) ? Duration : ReqCon->dir_config->session_duration; ! Data.IdSize = ( IdSize > 0 ) ? IdSize : ReqCon->dir_config->key_size; ! } } - const string Session::SessionIdName( "ehtmlSID" ); --- 20,305 ---- #include <Common.h> ! #include "Session.h" #include <Request.h> ! #include <dlfcn.h> using namespace std; ! string Session::_session_id_name( "ehtmlSID" ); ! DECLARE_PLUGIN(SessionDriver); ! DECLARE_PLUGIN(SessionIDDriver); ! ////////////////////////////////////////////////////////////////////////////// ! // ! // Session ID ! // ! SessionID::SessionID() { ! _binary_set = 0; ! _base64_set = 0; ! _hex_set = 0; ! _url_set = 0; } ! SessionID::SessionID(const SessionID& id): _binary(id._binary), ! _base64(id._base64), _hex(id._hex), _urlencoded(id._urlencoded) { ! _binary_set = id._binary_set; ! _base64_set = id._base64_set; ! _hex_set = id._hex_set; ! _url_set = id._url_set; } ! SessionID::SessionID(void* b, size_t nbytes, bool dup): _binary(b,nbytes) { ! if (dup) ! _binary = MemBuf::Dup(b,nbytes); ! _binary_set = 1; ! _base64_set = 0; ! _hex_set = 0; ! _url_set = 0; } ! SessionID::~SessionID() { } ! MemBuf& SessionID::binary() throw (const char*) { ! if (!_binary_set) ! throw "binary session id is not set"; ! return _binary; } ! const MemBuf& SessionID::binary() const throw (const char*) { ! if (!_binary_set) ! throw "binary session id is not set"; ! return _binary; } ! bool SessionID::binary(MemBuf& mb) { ! _binary = mb; ! _binary_set = 1; ! _base64_set = 0; _base64.clear(); ! _hex_set = 0; _hex.clear(); ! _url_set = 0; _urlencoded.clear(); } ! string& SessionID::base64() throw (const char*) { ! if (!_base64_set) { ! _base64 = base64encode(MemBuf(binary().Buffer(), binary().Size())); ! _base64_set = 1; ! } ! return _base64; } ! const string& SessionID::base64() const throw (const char*) { ! if (!_base64_set) { ! //@todo we could avoid memdup here.... ! _base64 = base64encode(MemBuf::Dup(binary().Buffer(), binary().Size())); ! _base64_set = 1; ! } ! return _base64; } ! bool SessionID::base64(string& s) { ! _base64 = s; ! _binary = base64decode(s); ! _base64_set = 1; ! _hex_set = 0; _hex.clear(); ! _url_set = 0; _urlencoded.clear(); } ! string& SessionID::hex() throw (const char*) { ! if (!_hex_set) { ! _hex = hexencode(MemBuf::Dup(binary().Buffer(), binary().Size())); ! _hex_set = 1; ! } ! return _hex; } ! const string& SessionID::hex() const throw (const char*) { ! if (!_hex_set) { ! //@todo we could avoid memdup here.... ! _hex = hexencode(MemBuf::Dup(binary().Buffer(), binary().Size())); ! _hex_set = 1; ! } ! return _hex; ! } ! bool SessionID::hex(string& s) { ! _hex = s; ! _binary = hexdecode(s); ! _base64_set = 0; ! _hex_set = 1; _hex.clear(); ! _url_set = 0; _urlencoded.clear(); ! } ! string& SessionID::urlencoded() throw (const char*) { ! if (!_url_set) { ! _urlencoded = urlencode(_binary); ! _url_set = 1; ! } ! return _urlencoded; } ! const string& SessionID::urlencoded() const throw (const char*) { ! if (!_url_set) { ! _urlencoded = urlencode(_binary); ! _url_set = 1; ! } ! return _urlencoded; ! } ! bool SessionID::urlencoded(string& s) { ! _urlencoded = s; ! _binary = urldecode(s); ! _url_set = 1; ! _hex_set = 0; _hex.clear(); ! _base64_set = 0; _base64.clear(); } ! ! ////////////////////////////////////////////////////////////////////////////// ! // ! // Session Driver ! // ! ! int registerSessionDriver(const char* driver_name, const char* filename) { ! fprintf(stderr, "registerSessionDriver(%s,%s)\n",driver_name, filename); ! void* dlh = dlopen(filename, RTLD_LAZY); ! if (dlh == NULL) ! return -1; ! void* dls = dlsym(dlh, driver_name); ! if (dls == NULL) { ! errno = ENOENT; ! dlclose(dlh); ! return -1; ! } ! SessionDriver::Factory build = (SessionDriver::Factory)dls; ! SessionDriver* driver = build(); ! if (!SessionDriver::Register(driver)) { ! errno = EEXIST; ! return -1; ! } ! return 0; } ! int useSessionDriver(const char* name, const char* arg) { ! fprintf(stderr,"useSessionDriver(%s,%s)\n",name,arg); ! SessionDriver* selected = SessionDriver::getByName(name); ! if (selected == NULL) { ! errno = ENOENT; ! return -1; ! } ! selected = SessionDriver::Select(selected); ! if (selected == NULL) { ! errno = EFAULT; ! return -1; ! } ! if (!selected->SetArgs(arg)) ! return -1; ! return 0; } ! ////////////////////////////////////////////////////////////////////////////// ! // ! // Session ID Driver ! // ! int registerSessionIDDriver(const char* driver_name, const char* filename) { ! fprintf(stderr, "registerSessionIDDriver(%s,%s)\n",driver_name, filename); ! void* dlh = dlopen(filename, RTLD_LAZY); ! if (dlh == NULL) ! return -1; ! void* dls = dlsym(dlh, driver_name); ! if (dls == NULL) { ! errno = ENOENT; ! dlclose(dlh); ! return -1; ! } ! SessionIDDriver::Factory build = (SessionIDDriver::Factory)dls; ! SessionIDDriver* driver = build(); ! if (!SessionIDDriver::Register(driver)) { ! errno = EEXIST; ! return -1; ! } ! return 0; ! } ! int useSessionIDDriver(const char* name, const char* arg) { ! fprintf(stderr,"useSessionIDDriver(%s,%s)\n",name,arg); ! SessionIDDriver* selected = SessionIDDriver::getByName(name); ! if (selected == NULL) { ! errno = ENOENT; ! return -1; ! } ! selected = SessionIDDriver::Select(selected); ! if (selected == NULL) { ! errno = EFAULT; ! return -1; ! } ! if (arg && !selected->SetArgs(arg)) ! return -1; ! return 0; ! } ! SessionDriver::~SessionDriver() { ! //@todo what has to be done here?? ! //should check that no pending sessions are hanging. } ! ////////////////////////////////////////////////////////////////////////////// ! // ! // Session ! // ! Session* SessionDriver::Get() { ! assert(_app != NULL); ! Request* req = _app->GetRequest(); ! const string* id = Session::CookieLess() ? ! req->GetArgument(Session::SessionIDName()) : ! req->GetArgument(Session::SessionIDName()); ! /* @TODO req->GetCookie(Session::session_id_name()) */ ! //@todo TODO: MUST USE CONFIGURATION DIRECTIVE TO SEE WHICH ENCODING ! //IS TO BE USED. ! return id ? Get(SessionID((void*)id->c_str(), id->length())) : NULL; } ! string Session::Serialize() { ! char _e[11]; ! snprintf(_e, 11, "%lu", _expires); ! operator[]("$$__EXPIRES$$") = _e; ! string s(Dictionary::Serialize()); ! erase("$$__EXPIRES$$"); ! return s; } ! ostream& operator << (ostream& o, Session& s) { ! char _e[11]; ! snprintf(_e, 11, "%lu", s.Expires()); ! s["$$__EXPIRES$$"] = _e; ! o << *static_cast<Dictionary*>(&s); ! s.erase("$$__EXPIRES$$"); ! return o; ! } ! bool Session::Marshall(const string& s) { ! if (!Dictionary::Marshall(s)) ! return false; ! _expires = xatoul(operator[]("$$__EXPIRES$$").c_str()); ! erase("$$__EXPIRES$$"); ! return true; } ! istream& operator >> (istream& i, Session& s) { ! i >> *static_cast<Dictionary*>(&s); ! s.Expires(xatoul(s["$$__EXPIRES$$"].c_str())); ! s.erase("$$__EXPIRES$$"); ! return i; ! } ! ! Session::~Session() { ! //@TODO: would be nice to check selected is the same session driver which ! //created me.... ! SessionDriver::Selected()->Release(this); } --- NEW FILE: DefaultSessionIDDriver.cpp --- #include "Session.h" #include "Common.h" using namespace std; //@TODO: add librandom: r250 (http://www.taygeta.com/random.html) //@TODO: add librandom: mls //@todo define a custom HTTP encoding #if 0 char i2c[65] = "abcdefghijklmnopqrstuvwxyz" // 26 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" // 26 => 52 "0123456789" // 10 => 62 "_-"; // 2 => 64 int c2i(char c) { if (c >= 'a' && c <= 'z') return c-'a'; if (c >= 'A' && c <= 'Z') return int(c)-'A'+26; if (c == '_') return 62; if (c == '-') return 63; } // in: char[3] // out: char[4] static void b64_ntoa(const char* in, char* out) { // 0000 0011 | 1111 2222 | 2233 3333 out[0] = i2c[(in[0] >> 2) & 0x3f]; out[1] = i2c[((in[0] << 4) | (in[1] >> 4)) & 0x3f]; out[2] = i2c[in[2] & 0x3f]; } // in: char[4] // out: char[3] static void b64_aton(const char* in, char* out) { // 0000 0011 | 1111 2222 | 2233 3333 uint32_t x[4]; x[0] = c2i(in[0]); x[1] = c2i(in[1]); x[2] = c2i(in[2]); x[3] = c2i(in[3]); out[0] = (x[0] << 2) | (x[1] >> 4); out[1] = (x[1] << 4) | (x[2] >> 2); out[3] = (x[2] << 6) | (x[3]); } #endif class DefaultSessionIDDriver: public SessionIDDriver { string priv_key; size_t extra_entropy; public: DefaultSessionIDDriver(const char* _name): extra_entropy(0) { name(_name); } DefaultSessionIDDriver(): extra_entropy(0) { ; } virtual bool SetArgs(const string& id); virtual bool ValidID(SessionID& id); virtual SessionID GenerateID(); }; bool DefaultSessionIDDriver::SetArgs(const string& arg) { bool dev = true; if (!strncmp(arg.c_str(), "extra_entropy=", 14)) extra_entropy = xatoul(arg.c_str()+14); else { errno = EINVAL; dev = false; } return dev; } bool DefaultSessionIDDriver::ValidID(SessionID& id) { if (id.binary().Size() != 4*(1+extra_entropy)) return false; struct timeval now, _id; uint32_t* uv = (uint32_t*)id.binary().Buffer(); gettimeofday(&now, NULL); _id.tv_sec = uv[0]; _id.tv_usec = uv[1]; return now.tv_sec+1 >= _id.tv_sec ? true : false; } struct sesid_t { uint32_t sec, usec, seq, rnd; }; SessionID DefaultSessionIDDriver::GenerateID() { static uint32_t seq = ehtml_random(); sesid_t* id = (sesid_t*)malloc(sizeof(sesid_t)); struct timeval now; gettimeofday(&now, NULL); id->sec = now.tv_sec; id->usec = (now.tv_usec << 12) | (ehtml_random() & 0x0fff); id->seq = ++seq; id->rnd = ehtml_random(); return SessionID(id, sizeof(*id)); } extern "C" SessionIDDriver* Default() { return new DefaultSessionIDDriver("Default"); } --- NEW FILE: DefaultSessionDriver.cpp --- /*************************************************************************** * Copyright (C) 2005 by Matej Urbas * * mat...@gm... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, 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 License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ //#include "DefaultSessionDriver.h" #include "Session.h" #include "DefaultSessionProtocol.h" #include <sstream> #include "DefaultSessionDriver.h" using namespace std; bool DefaultSessionDriver::SetArgs(const string& arg) { istringstream s(arg); string opt; while (s >> opt) { if (!strncmp("addr=",opt.c_str(),5)) { string _addr(opt.c_str()+5); if (!strncmp("unix://",_addr.c_str(),7)) { addr.address_family = AF_UNIX; addr.protocol_family = PF_UNIX; addr.addr_len = sizeof(sockaddr_un); addr.addr._unix.sun_family = AF_UNIX; strncpy(addr.addr._unix.sun_path,_addr.c_str()+7,sizeof(addr.addr._unix.sun_path)); } else if (!_addr[0] == '/') { addr.address_family = AF_UNIX; addr.protocol_family = PF_UNIX; addr.addr_len = sizeof(sockaddr_un); addr.addr._unix.sun_family = AF_UNIX; strncpy(addr.addr._unix.sun_path,_addr.c_str(),sizeof(addr.addr._unix.sun_path)); } else if (!strncmp("inet://",_addr.c_str(),7)) { char host[16]; unsigned short port; if (sscanf(_addr.c_str()+7, "%[.0-9]:%hu", host, &port) != 2) { errno = EINVAL; return false; } addr.address_family = AF_INET; addr.protocol_family = PF_INET; addr.addr_len = sizeof(sockaddr_in); addr.addr._inet.sin_family = AF_INET; addr.addr._inet.sin_port = htons(port); if (!inet_aton(host, &addr.addr._inet.sin_addr)) { errno = EINVAL; return false; } } else { errno = EINVAL; return false; } } else { errno = EINVAL; return false; } } return true; } void DefaultSessionDriver::init() { fd = -1; } DefaultSessionDriver::DefaultSessionDriver() { init(); } DefaultSessionDriver::DefaultSessionDriver(const char* _name) { init(); name(_name); } DefaultSessionDriver::~DefaultSessionDriver() { ; } Session* DefaultSessionDriver::Get (const SessionID& id) { // We are connected. Send the request and wait for the answer DSSGetData get_data; get_data.MsgType = DSS_CMD_GET_DATA; get_data.IdSize = id.binary().Size(); memcpy(get_data.Id, id.binary().Buffer(), get_data.IdSize); // Send the request if (send(fd, &get_data, sizeof(DSSGetData), 0) < 0) return NULL; // Receive the answer from the server - it should be data... DSSFetcherStruct buf; if (recv(fd, &buf, sizeof(DSSFetcherStruct), 0) < 0 || buf.MsgType != DSS_CMD_GET_DATA ) { if (buf.MsgType == DSS_CMD_STATUS && ((DSSStatusRespond*)&buf)->Type == DSS_STATUS_SESSION_OVER) errno = EHTML_TIMEOUT; else errno = EHTML_ERR; return NULL; } // Ok, we've got the data. Read the size and put it into the 'Parms' structure DSSGetData_Response * resp = ( DSSGetData_Response * ) &buf; Session* s = new Session(id); s->Expires(resp->LastAccess + resp->Duration); s->LastAccess(resp->LastAccess); s->Started(resp->SessionStarted); s->Modification(resp->Modified); // Two scenarios: a) one packet, or b) two packets if (resp->DataSize > MAX_GET_DATA_SIZE) { if (recv(fd, resp->Data + MAX_GET_DATA_SIZE, resp->DataSize - MAX_GET_DATA_SIZE, 0) < 0 || buf.MsgType != DSS_CMD_GET_DATA ) { delete s; return NULL; } } s->Marshall(string(resp->Data)); return s; } bool DefaultSessionDriver::Save(Session* s) { // We are connected. Send the request and wait for the answer bool dev = true; DSSFetcherStruct max_size; string data(s->Serialize()); DSSSetData * set_data = (DSSSetData*)&max_size; set_data->MsgType = DSS_CMD_SET_DATA; set_data->IdSize = s->ID().binary().Size(); set_data->DataSize = data.length(); set_data->Duration = s->Expires() - s->Started(); memcpy(set_data->Id, s->ID().binary().Buffer(), set_data->IdSize ); // We have 2 scenarios: // a) either all data fits into the first packet, or // b) the alternative ;) if (set_data->DataSize <= MAX_SET_DATA_SIZE) { memcpy(set_data->Data, data.c_str(), set_data->DataSize); if (send(fd, set_data, sizeof(DSSSetData) + set_data->DataSize, 0) < 0 ) dev = false; } else { memcpy(set_data->Data, data.c_str(), MAX_SET_DATA_SIZE ); if (send(fd, set_data, sizeof(DSSSetData) + MAX_SET_DATA_SIZE, 0) < 0 || send(fd, data.c_str() + MAX_SET_DATA_SIZE, set_data->DataSize - MAX_SET_DATA_SIZE, 0 ) < 0 ) dev = false; } // Receive the status answer... DSSStatusRespond response; if (recv(fd, &response, sizeof(DSSStatusRespond), 0 ) < 0 ) dev = false; else if ( response.MsgType == DSS_CMD_STATUS ) { int retVal = EHTML_OK; switch (response.Type ) { case DSS_STATUS_SESSION_OVER: errno = EHTML_TIMEOUT; dev = false; break; case DSS_STATUS_ERROR: errno = EHTML_ERR; dev = false; break; } return dev; } return dev; } bool DefaultSessionDriver::Remove (Session* s) { // Send the request and wait for the answer DSSUnregisterID unreg; unreg.MsgType = DSS_CMD_UNREGISTER_ID; unreg.IdSize = s->ID().binary().Size(); memcpy( unreg.Id, s->ID().binary().Buffer(), unreg.IdSize ); // Here goes our request if (send(fd, &unreg, sizeof(DSSUnregisterID), 0 ) < 0 ) return false; // Get the answer DSSStatusRespond response; if (recv(fd, &response, sizeof(DSSStatusRespond), 0) > 0 && response.MsgType == DSS_CMD_STATUS && response.Type == DSS_STATUS_OK) return true; errno = EHTML_ERR; return false; } bool DefaultSessionDriver::Release(Session* s) { //@todo we should implement this feature return true; } int DefaultSessionDriver::Socket() { if (fd < 0) fd = socket(addr.protocol_family, SOCK_STREAM, 0); return fd; } bool DefaultSessionDriver::Bind() { return bind(Socket(), &addr.addr._addr, addr.addr_len) == 0 ? true : false; } bool DefaultSessionDriver::Connect() { // Open a new connection to the server int fd = Socket(); if (fd < 0) return false; // Try to connect return connect(fd, &addr.addr._addr, addr.addr_len) >= 0 ? true : false; } bool DefaultSessionDriver::Disconnect() { // Post a quit message and close the connection DSSStandard rec; rec.MsgType = DSS_CMD_CLOSE; if(send(fd, &rec, sizeof( DSSStandard ), 0) < 0) { errno = EHTML_ERR; return false; } return close(fd) >= 0 ? true : false; } //@todo: register this driver extern "C" SessionDriver* Default() { return new DefaultSessionDriver("Default"); } --- NEW FILE: DefaultSessionServer.cpp --- /*************************************************************************** * Copyright (C) 2005 by Matej Urbas * * mat...@gm... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, 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 License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "DefaultSessionProtocol.h" #include "DefaultSessionAddress.h" #include "Session.h" #include <time.h> #include <sys/time.h> #include <map> #include <string.h> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #include <errno.h> #include <pthread.h> #include <stdlib.h> using namespace std; /** * Initialize the session server... Should be only called once (before child * init). * * @return 0 on success, otherwise it returns a pointer to a string explaining * the error... */ const char* DefSesSr_Init( mod_c_config* config ); /** * This method creates a new thread and returns instantly. * * @param config * additional configuration for the default session manager. */ void DefSesSr_RunServer( server_rec * s, mod_c_config* config, apr_pool_t *p ); /** * This number is used to generate an array that initializes the random number * generator to generate keys. The higher the number, the more secure the ID. */ #define RANDOM_KEY_SIZE 32 #define DEF_CLEANUP_INTERVAL 3600 /**< an hour */ /** * The interval (in seconds) in which the session map will be cleaned. */ static int CLEANUP_INTERVAL = DEF_CLEANUP_INTERVAL; /** * This one is for internal use... */ struct Id_Internal { char Id[MAX_ID_SIZE]; int IdSize; }; /** * This one is for internal use... */ struct DataEntry { void * Data; time_t SessionStarted; time_t LastTouched; time_t Modified; int Duration; int DataSize; int Capacity; }; /** * This one compares IDs for correct sorting in the map... */ struct IDComparator { bool operator()( const Id_Internal& __x, const Id_Internal& __y) const { return ( memcmp( __x.Id, __y.Id, MAX_ID_SIZE ) < 0 ) ? true : false; } }; /** * The map that stores session data... */ typedef map< Id_Internal, DataEntry, IDComparator > SessionDataMap; /** * This structure is used to pass the session server any configuration stuff it needs. */ struct __server_private_data { int socket; SessionDataMap * map; }; /** * The mutex that locks the map when reading/writing from/to it. */ pthread_mutex_t session_map_mutex = PTHREAD_MUTEX_INITIALIZER; /** * Key generation is a little ad hoc... * * TODO: Check for a better implementation... */ void GenerateId( char * Buf, int BufSize ); /** * The entry function - defined below... */ template < typename T > static void * RunServer ( void * ); /** * Starts the socket connection... */ void StartConnection( SessionDataMap * map, int socket ); /** * Cleans outdated sessions */ void* CleanerFunc( void* ); /** * The indicator which tells whether the server is still running or if it * stopped already. */ bool ServerRunning = false; /** * Removes a session entry from the map... */ inline void RemoveSessionEntry( SessionDataMap& TheMap, SessionDataMap::iterator& Entry ) { if ( Entry->second.Data ) delete [] (char*)Entry->second.Data; TheMap.erase( Entry ); } /** * Stores data for an existing session... */ inline void ProcessSetData( DSSFetcherStruct& Buf, SessionDataMap& TheMap, int connection ) { DSSSetData * data = ( DSSSetData * ) &Buf; int status = DSS_STATUS_SESSION_OVER; // Is the size OK? if ( data->IdSize < MIN_ID_SIZE || data->IdSize > MAX_ID_SIZE ) // Send an error message! status = DSS_STATUS_ERROR; else { // We can proceed with setting data Id_Internal tmp; tmp.IdSize = data->IdSize; memset( tmp.Id + data->IdSize, 0, MAX_ID_SIZE - data->IdSize ); memcpy( tmp.Id, data->Id, data->IdSize ); // Find the session in the map... pthread_mutex_lock( &session_map_mutex ); SessionDataMap::iterator _iter = TheMap.find( tmp ); if ( _iter != TheMap.end() ) { time_t now = time( 0 ); // Is the session outdated? if ( now - _iter->second.LastTouched > _iter->second.Duration * 60 ) { RemoveSessionEntry( TheMap, _iter ); status = DSS_STATUS_SESSION_OVER; } else { // Touch the session _iter->second.Modified = _iter->second.LastTouched = now; // Get the data size... if ( data->DataSize <= 0 ) { // Set the data size to zero... _iter->second.DataSize = 0; // We are finished - unlock the map... pthread_mutex_unlock( &session_map_mutex ); } else { // There is actually some data incoming... _iter->second.DataSize = data->DataSize; // If the current capacity of the data array is to small, // create a new one if ( _iter->second.Capacity < _iter->second.DataSize ) { _iter->second.Capacity = _iter->second.DataSize + 256; // Delete the old data array... if ( _iter->second.Data ) delete [] ((char*)_iter->second.Data); // Create a new one... _iter->second.Data = new char[ _iter->second.Capacity ]; } // Copy the data we already have int * data_size = &_iter->second.DataSize; char * new_data = (char*)_iter->second.Data; // WARNING: Unlocking for performance reasons - could cause segfaults // or incomplete session data - should be moved further below if // any problems... pthread_mutex_unlock( &session_map_mutex ); // Copying... if ( *data_size <= MAX_SET_DATA_SIZE ) { // We have only one packet memcpy( new_data, data->Data, *data_size ); } else { // We've got a big one comming // First store the first packet memcpy( new_data, data->Data, MAX_SET_DATA_SIZE ); // Now get the rest recv( connection, new_data + MAX_SET_DATA_SIZE, *data_size - MAX_SET_DATA_SIZE, 0 ); } } // Send an OK sign... DSSStatusRespond stResp = { DSS_CMD_STATUS, DSS_STATUS_OK }; send( connection, &stResp, sizeof( DSSStatusRespond ), 0 ); return; } } else // The session does not exist... return an error code status = DSS_STATUS_ERROR; pthread_mutex_unlock( &session_map_mutex ); } DSSStatusRespond stResp = { DSS_CMD_STATUS, status }; send( connection, &stResp, sizeof( DSSStatusRespond ), 0 ); } /** * Stores data for an existing session... */ inline void ProcessGetData( DSSFetcherStruct& Buf, SessionDataMap& TheMap, int connection ) { DSSGetData * data = ( DSSGetData * ) &Buf; // Is the size OK? if ( data->IdSize < MIN_ID_SIZE || data->IdSize > MAX_ID_SIZE ) { // Send an error message! DSSStatusRespond stResp = { DSS_CMD_STATUS, DSS_STATUS_ERROR }; send( connection, &stResp, sizeof( DSSStatusRespond ), 0 ); } else { // We can proceed with getting the data Id_Internal tmp; tmp.IdSize = data->IdSize; memset( tmp.Id + data->IdSize, 0, MAX_ID_SIZE - data->IdSize ); memcpy( tmp.Id, data->Id, data->IdSize ); int status = DSS_STATUS_OK; // Find the session in the map... pthread_mutex_lock( &session_map_mutex ); SessionDataMap::iterator _iter = TheMap.find( tmp ); if ( _iter != TheMap.end() ) { time_t now = time( 0 ); // Is the session outdated? if ( now - _iter->second.LastTouched > _iter->second.Duration * 60 ) { RemoveSessionEntry( TheMap, _iter ); status = DSS_STATUS_SESSION_OVER; } else { // The session has been found and is still valid... // Touch the session... DSSGetData_Response * response = ( DSSGetData_Response * ) &Buf; response->DataSize = _iter->second.DataSize; response->Duration = _iter->second.Duration; response->LastAccess = _iter->second.LastTouched = now; response->MsgType = DSS_CMD_GET_DATA; response->SessionStarted = _iter->second.SessionStarted; response->Modified = _iter->second.Modified; // Send the data! if ( response->DataSize > MAX_GET_DATA_SIZE ) { memcpy( response->Data, _iter->second.Data, MAX_GET_DATA_SIZE ); send( connection, response, sizeof( DSSGetData_Response ) + MAX_GET_DATA_SIZE, 0 ); send( connection, ((char *)_iter->second.Data) + MAX_GET_DATA_SIZE, response->DataSize - MAX_GET_DATA_SIZE, 0 ); } else { memcpy( response->Data, _iter->second.Data, response->DataSize ); send( connection, response, sizeof( DSSGetData_Response ) + response->DataSize, 0 ); } // Unlock the map... pthread_mutex_unlock( &session_map_mutex ); return; } } else status = DSS_STATUS_ERROR; pthread_mutex_unlock( &session_map_mutex ); // Answer according to the status... DSSStatusRespond stResp = { DSS_CMD_STATUS, status }; send( connection, &stResp, sizeof( DSSStatusRespond ), 0 ); } } /** * Sets the duration of an existing session... */ inline void ProcessSetDuration( DSSFetcherStruct& Buf, SessionDataMap& TheMap, int connection ) { DSSSetDuration * data = ( DSSSetDuration * ) &Buf; // Are the session ID and the new duration invalid? if ( data->IdSize < MIN_ID_SIZE || data->IdSize > MAX_ID_SIZE || data->Duration < 1 || data->Duration > MAX_SESSION_DURATION ) { // Send an error message! DSSStatusRespond stResp = { DSS_CMD_STATUS, DSS_STATUS_ERROR }; send( connection, &stResp, sizeof( DSSStatusRespond ), 0 ); } else { // We can proceed with setting the duration Id_Internal tmp; tmp.IdSize = data->IdSize; memset( tmp.Id + data->IdSize, 0, MAX_ID_SIZE - data->IdSize ); memcpy( tmp.Id, data->Id, data->IdSize ); int status = DSS_STATUS_OK; // Find the session in the map... pthread_mutex_lock( &session_map_mutex ); SessionDataMap::iterator _iter = TheMap.find( tmp ); if ( _iter != TheMap.end() ) { time_t now = time( 0 ); // Is the session outdated? if ( now - _iter->second.LastTouched > _iter->second.Duration * 60 ) { RemoveSessionEntry( TheMap, _iter ); status = DSS_STATUS_SESSION_OVER; } else { // Set the new duration and touch it... _iter->second.Duration = data->Duration; _iter->second.LastTouched = now; } } else status = DSS_STATUS_ERROR; pthread_mutex_unlock( &session_map_mutex ); // Answer according to the status... DSSStatusRespond stResp = { DSS_CMD_STATUS, status }; send( connection, &stResp, sizeof( DSSStatusRespond ), 0 ); } } /** * Unregisters an existing session. */ inline void ProcessUnregisterId( DSSFetcherStruct& Buf, SessionDataMap& TheMap, int connection ) { DSSUnregisterID * data = ( DSSUnregisterID * ) &Buf; if ( data->IdSize < MIN_ID_SIZE || data->IdSize > MAX_ID_SIZE ) { // Send an error message! DSSStatusRespond stResp = { DSS_CMD_STATUS, DSS_STATUS_ERROR }; send( connection, &stResp, sizeof( DSSStatusRespond ), 0 ); } else { Id_Internal tmp; tmp.IdSize = data->IdSize; memset( tmp.Id + data->IdSize, 0, MAX_ID_SIZE - data->IdSize ); memcpy( tmp.Id, data->Id, data->IdSize ); // Find the session in the map... pthread_mutex_lock( &session_map_mutex ); SessionDataMap::iterator _iter = TheMap.find( tmp ); if ( _iter != TheMap.end() ) // Remove it and free the data! RemoveSessionEntry( TheMap, _iter ); pthread_mutex_unlock( &session_map_mutex ); // Send an OK message... DSSStatusRespond stResp = { DSS_CMD_STATUS, DSS_STATUS_OK }; send( connection, &stResp, sizeof( DSSStatusRespond ), 0 ); } } int __i = 0; /** * Processes id session registration. */ inline void ProcessRegisterId( DSSFetcherStruct& Buf, SessionDataMap& TheMap, int connection ) { // Get the received data DSSRegisterID * data = ( DSSRegisterID * ) &Buf; // Are the size of the ID and the duration of the session within range? if ( data->IdSize < MIN_ID_SIZE || data->IdSize > MAX_ID_SIZE ) data->IdSize = DEF_ID_SIZE; if ( data->Duration < 1 || data->Duration > MAX_SESSION_DURATION ) data->Duration = DEF_SESSION_DURATION; // The size of the key is OK. Create one... pair< Id_Internal, DataEntry > tmp; tmp.first.IdSize = data->IdSize; memset( tmp.first.Id + data->IdSize, 0, MAX_ID_SIZE - data->IdSize ); GenerateId( tmp.first.Id, tmp.first.IdSize ); // Initialize other data... tmp.second.Capacity = 0; tmp.second.Data = 0; tmp.second.DataSize = 0; tmp.second.Duration = data->Duration; tmp.second.Modified = tmp.second.SessionStarted = time( &tmp.second.LastTouched ); // Store it into the map pthread_mutex_lock( &session_map_mutex ); pair< SessionDataMap::iterator, bool > retVal = TheMap.insert( tmp ); pthread_mutex_unlock( &session_map_mutex ); if ( retVal.second ) { // It was inserted correctly, return a success code DSSRegisterID_Respond * response = ( DSSRegisterID_Respond * ) &Buf; response->MsgType = DSS_CMD_REGISTER_ID; response->Duration = tmp.second.Duration; memcpy( response->Id, tmp.first.Id, response->IdSize = tmp.first.IdSize ); response->SessionStarted = response->LastAccess = tmp.second.SessionStarted; send( connection, response, sizeof( DSSRegisterID_Respond ), 0 ); } else { // It wasn't inserted... DSSStatusRespond stResp = { DSS_CMD_STATUS, DSS_STATUS_ERROR }; send( connection, &stResp, sizeof( DSSStatusRespond ), 0 ); } } inline void ProcessServerStatus( DSSFetcherStruct& Buf, SessionDataMap& TheMap, int connection ) { DSSServerStatus * status = ( DSSServerStatus * ) &Buf; time_t Time = time( 0 ); status->MsgType = DSS_SERVER_STATUS; status->OutdatedSessions = 0; status->TotalBytes = 0; // Get the desired data pthread_mutex_lock( &session_map_mutex ); // Get the total amount of sessions status->TotalSessions = TheMap.size(); // Go through the map... SessionDataMap::iterator _itr = TheMap.begin(); while( _itr != TheMap.end() ) { if ( Time - _itr->second.LastTouched > _itr->second.Duration * 60 ) // An outdated session ++status->OutdatedSessions; // Count the bytes status->TotalBytes += (unsigned int) _itr->second.DataSize; ++_itr; } pthread_mutex_unlock( &session_map_mutex ); // Send the results... send( connection, status, sizeof( DSSServerStatus ), 0 ); } /** * Removes sessions that have timed out... */ inline void Cleanup( SessionDataMap& TheMap, time_t Time ) { pthread_mutex_lock( &session_map_mutex ); // Go through the map... SessionDataMap::iterator _itr = TheMap.begin(); const SessionDataMap::const_iterator & end = TheMap.end(); while( _itr != end ) { if ( Time - _itr->second.LastTouched > _itr->second.Duration * 60 ) { // Delete it! SessionDataMap::iterator _tmp = _itr; ++_itr; RemoveSessionEntry( TheMap, _tmp ); } else ++_itr; } pthread_mutex_unlock( &session_map_mutex ); } /** * This one ensures that the shared segment is properly initialized. */ int DefSesSr_Init( ) { // Unlink the path for the RF_LOCAL sockets... unlink( UNIX_SOCKET_ADDRESS ); // You should always succeed... return 0; } /** * This function starts the session server. It ensures that only one server runs at any time. */ int DefSesSr_RunServer(Address& addr ) { // The server has started ServerRunning = true; umask( 0 ); // Create the map SessionDataMap * map = new SessionDataMap; // Prepare the thread structure pthread_t thread; void * returnThread = 0; int serverHandle = socket(addr.protocol_family, SOCK_STREAM, 0); if (serverHandle < 0) { printf ("socket(2) error: %s\n", strerror(errno)); return 0; } if (bind(serverHandle, &addr.addr._addr, addr.addr_len) < 0) { printf ("bind(2) error: %s\n", strerror(errno)); return 0; } // Create the cleaner thread (this one cleans outdated sessions from the map) pthread_t cleanerThread; pthread_attr_t thread_attr; pthread_attr_init( &thread_attr ); int retVal = pthread_create( &cleanerThread, &thread_attr, CleanerFunc, map ); if ( retVal != 0 ) { printf ("Could not create a thread in '%s' at line '%d': '%s'\n", __FILE__, __LINE__, strerror(errno)); goto finish; } // Has a server already been created? if ( retVal < 0 ) { printf ("Could not create a listening socket in '%s' at line '%d': '%s'\n", __FILE__, __LINE__, strerror(errno)); goto finish; } retVal = listen( serverHandle, MAX_QUEUE ); if ( retVal < 0 ) { printf ("Could not listen in '%s' at line '%d': '%s'\n", __FILE__, __LINE__, strerror(errno)); shutdown( serverHandle, SHUT_RDWR ); close( serverHandle ); goto finish; } else { // We have a server ;) Create a listening thread and buzz off... pthread_attr_init( &thread_attr ); // Create the parameters to pass to the server __server_private_data * parms = new __server_private_data; parms->socket = serverHandle; parms->map = map; // Create the listening thread int retVal = pthread_create( &thread, &thread_attr, RunServer< sockaddr_un >, parms ); if ( retVal != 0 ) { printf ("Could not create a thread that would listen in '%s' at line '%d': '%s'\n", __FILE__, __LINE__, strerror(errno)); delete parms; shutdown( serverHandle, SHUT_RDWR ); close( serverHandle ); goto finish; } } // TODO: Add the remote part of the server... pthread_join( thread, &returnThread ); // Shutdown and close shutdown( serverHandle, SHUT_RDWR ); close( serverHandle ); finish: // The server is definitely not running anymore ServerRunning = false; return 0; } /** * Starts listening... */ template < typename T > void * RunServer ( void * data ) { srand( time( 0 ) ); // Initialize the random number generator char * state = new char[RANDOM_KEY_SIZE]; FILE * rnd = fopen( "/dev/urandom", "r" ); fread( state, 1, RANDOM_KEY_SIZE, rnd ); fclose( rnd ); // Initialize the state of the random number generator initstate( rand(), state, RANDOM_KEY_SIZE ); __server_private_data * parms = ( __server_private_data* ) data; int serverHandle = parms->socket; // Start accepting connections... while( ServerRunning ) { T loc_addr; socklen_t loc_addr_size = sizeof( T ); // Accept the connection int retVal = accept( serverHandle, reinterpret_cast< sockaddr* >( &loc_addr ), &loc_addr_size ); if ( retVal >= 0 ) // The connection has been accepted... // Start the communication: create a new thread and echo/output recieved data... StartConnection( parms->map, retVal ); } return 0; } void GenerateId( char * Buf, int BufSize ) { // How many 'int' types fit in int _blocks = BufSize / sizeof( int ); int _tail = BufSize % sizeof( int ); int * piBuf = (int *)Buf; for( int i = 0; i < _blocks; i++ ) piBuf[ i ] += ( random() << 1 ) | ( rand() & 1 ); if ( _tail ) { Buf = Buf + BufSize - _tail; for ( int i = 0; i < _tail; i++ ) Buf[ i ] += rand(); } } /** * This structure contains info for the Communicate function. */ struct ConnectionArguments { SessionDataMap * map; int socket; }; /** * Starts receiving and sending data... */ void * Communicate( void * args ) { ConnectionArguments * parms = ( ConnectionArguments * ) args; DSSFetcherStruct buf; bool goOn = true; while ( goOn ) { // Get the request - figure out what type it is ssize_t tmp = recv( parms->socket, &buf, sizeof( DSSFetcherStruct ), 0 ); if ( tmp > 0 ) { // We have successfully read some data... now check the type switch ( buf.MsgType ) { case DSS_CMD_REGISTER_ID: ProcessRegisterId( buf,... [truncated message content] |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:28:21
|
Update of /cvsroot/mod-c/ehtml/samples In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv14857/samples Added Files: 02session.cpp Log Message: Session usage sample. --- NEW FILE: 02session.cpp --- // $Id: 02session.cpp,v 1.1 2006/09/08 14:28:17 garana Exp $ #include <ehtml.h> #include <EHTMLApplication.h> #include <Page.h> #include <Label.h> #include <http_log.h> #include <time.h> using namespace std; const string COUNT("count"); class SessionEHTMLApp: public EHTMLApplication { SessionDriver* driver; Session* session; size_t cnt; public: size_t CNT() const { return cnt; } size_t CNT() { return cnt; } Label lblSessionDriver; Label lblCount; SessionEHTMLApp(request_context* req): EHTMLApplication(req), session(NULL), cnt(0), lblSessionDriver("No session driver. Use EHTMLSessionType."), lblCount("count = no session"){ ; } virtual int DoInitStage() { int dev = EHTMLApplication::DoInitStage(); if (dev) return dev; if (Page) { Page->Add(&lblSessionDriver); Page->Add(&lblCount); } driver = SessionDriver::Selected(); if (driver == NULL) return 0; if (!driver->Connect()) { ap_log_error(APLOG_MARK, LOG_ERR, 0, Request->GetRequestContext()->r->server, "Error connecting to session server: %s", strerror(errno)); lblSessionDriver.SetText("Error connecting to session store."); lblCount.SetText(strerror(errno)); return 0; } lblSessionDriver.SetText("Session driver = " + driver->name()); session = driver->Get(); if (session == NULL) { SessionIDDriver* iddriver = SessionIDDriver::Selected(); if (iddriver != NULL) { SessionID id = iddriver->GenerateID(); session = new Session(id); } else { lblCount.SetText("no session ID driver. Use EHTMLSessionIDType."); } } if (session != NULL) { Session::iterator i = session->find(COUNT); if (i == session->end()) { (*session)[COUNT] = "1"; cnt = 1; } else { cnt = atoi((*session)[COUNT].c_str()); (*session)[COUNT] = cnt + 1; } lblCount.SetText("count = " + (*session)[COUNT]); } return dev; } virtual int DoFinishStage() { if (session && driver) { if (!driver->Save(session)) { ap_log_error(APLOG_MARK, LOG_ERR, 0, Request->GetRequestContext()->r->server, "Error saving session (hex=%s): %s", session->ID().hex().c_str(), strerror(errno)); } if (!driver->Disconnect()) { ap_log_error(APLOG_MARK, LOG_ERR, 0, Request->GetRequestContext()->r->server, "Error disconnecting to session server: %s", strerror(errno)); } } return EHTMLApplication::DoFinishStage(); } }; extern "C" int ehtml_run(request_context* rc) { SessionEHTMLApp ap(rc); Page p; Label l("Hello World."); time_t now = time(NULL); Label l2(ctime(&now)); p.SetTitle("Hello World."); p.Add(&l); p.Add(&l2); ap.SetPage(&p); return ap.Run(); } |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:27:51
|
Update of /cvsroot/mod-c/ehtml/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv14484/include Added Files: Plugin.h Log Message: Plugin<C>: a plug-in class framework (see SessionDriver for an example). --- NEW FILE: Plugin.h --- #ifndef __PLUGIN_H_ #define __PLUGIN_H_ #include <assert.h> #include <string> #include <map> template <class C> class Pluggable { typedef std::map<std::string,C*> _map_t; static _map_t _map; std::string _name; static C* _selected; public: Pluggable() { ; } Pluggable(const char* name): _name(name) { ; } virtual ~Pluggable() { ; } const std::string& name() const { return _name; } std::string& name() { return _name; } void name(const std::string& __name) { _name = __name; } static C* Selected() { return _selected; } static C* Select(std::string name) { return _selected = getByName(name); } static C* Select(C* c) { return _selected = getByName(c->name()); } static C* getByName(std::string name) { typename _map_t::iterator i = _map.find(name); if (i == _map.end()) { errno = ENOENT; return NULL; } return i->second; } static bool Register(C* c) { _map[c->name()] = c; // this does not work .... //std::pair<typename _map_t::iterator,bool> dev = // _map.insert(_map_t::value_type(c->name(),c)); return true; } typedef C* (*Factory)(); }; #define DECLARE_PLUGIN(C) \ map<string,C*> Pluggable<C>::_map; \ C* Pluggable<C>::_selected = NULL; //@TODO: write a plug-in registerer #endif |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:27:13
|
Update of /cvsroot/mod-c/ehtml/src In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv14047/src Added Files: Dictionary.cpp Log Message: * Dictionary: a convenience child of map<string,string> --- NEW FILE: Dictionary.cpp --- #include "Dictionary.h" #include "Common.h" #include <sstream> using namespace std; //void replace(string& s, const char* a, const char* b) { // size_type i = 0; // size_t a_len = strlen(a); // size_t b_len = strlen(a); // while (i = s.find(a, i), i != string::npos) { // s.replace(i, a_len, b); // i += b_len - a_len; // } //} string Dictionary::Serialize() { string str; for (Dictionary::iterator i = begin(); i != end(); ++i) { string k = urlencode(i->first); string v = urlencode(i->second); str += k + " " + v + "\n"; } return str; } ostream& operator << (ostream& o, Dictionary& d) { for (Dictionary::iterator i = d.begin(); i != d.end(); ++i) o << urlencode(i->first) << " " << urlencode(i->second) << "\n"; return o; } bool Dictionary::Marshall(const string& s) { size_type i = 0; size_type ii = 0; while (i = s.find("\n", i), i != string::npos) { size_type sp = s.find(" ", ii); if (sp > i || sp == string::npos) return false; string k, v; k.assign(s, ii, sp-ii); v.assign(s, sp+1, i-sp); ii = ++i; k = urldecode(k).AsString(); v = urldecode(v).AsString(); if (!insert(pair<string,string>(k,v)).second) return false; } return true; } istream& operator >> (istream& i, Dictionary& d) { char line[512]; while (!i.getline(line,sizeof(line)-1)) { istringstream l(line); string k, v; l >> k; if (!l); throw "Invalid input stream"; l >> v; if (!l.eof()) throw "Invalid input stream"; // should check that urldecode(k) is not present. d[urldecode(k).AsString()] = urldecode(v).AsString(); } return i; } |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:27:13
|
Update of /cvsroot/mod-c/ehtml/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv14047/include Added Files: Dictionary.h Log Message: * Dictionary: a convenience child of map<string,string> --- NEW FILE: Dictionary.h --- #ifndef _DICT_H_ #define _DICT_H_ #include <string> #include <map> #include <iostream> /** * Dictionary (map<string,string>). */ class Dictionary: public std::map<std::string,std::string> { public: /** * serialize: transform into a printable (multiline) string. */ std::string Serialize(); /** * marshall: opposite of seralize. */ bool Marshall(const std::string& str); friend std::ostream& operator << (std::ostream& o, Dictionary& s); friend std::istream& operator >> (std::istream& i, Dictionary& s); }; /** * Dictionary serialization operator (@see Dictionary::serialize). */ std::ostream& operator << (std::ostream& o, Dictionary& s); /** * Dictionary marshalling operator (@see Dictionary::marhsall). */ std::istream& operator >> (std::istream& i, Dictionary& s); #endif |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:26:38
|
Update of /cvsroot/mod-c/ehtml/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv13627/include Modified Files: ehtml.h Log Message: * EHTML_* macros are now negative values (suitable for storing in errno). * Session api is now in Session.h * Prepared ehtml_random() for random number generation. Index: ehtml.h =================================================================== RCS file: /cvsroot/mod-c/ehtml/include/ehtml.h,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** ehtml.h 2 Mar 2006 23:02:53 -0000 1.18 --- ehtml.h 8 Sep 2006 14:26:32 -0000 1.19 *************** *** 27,45 **** /** ! * Standard OK return code. ! */ ! #define EHTML_OK 0 ! /** ! * Standard ERROR return code. ! */ ! #define EHTML_ERR 1 ! /** ! * Return value that session drivers return if a session has timed out. ! */ ! #define EHTML_SESSION_TIMEOUT 2 ! /** ! * Invalid call. */ ! #define EHTML_INVALID_CALL 3 /** --- 27,40 ---- /** ! * Status codes: ! * ! * If possitive, it is a valid errno error. ! * Otherwise, it is an adhoc error code (see below). */ ! #define EHTML_OK 0 /** Everything went ok */ ! #define EHTML_ERR -1 /** Unspecified error */ ! #define EHTML_TIMEOUT -2 /** Operation time out */ ! #define EHTML_INVALID_CALL -3 /** Invalid call */ ! #define EHTML_INVALID_CALL -3 /** Invalid call */ /** *************** *** 160,213 **** /** - * The main structure for the session API. - */ - struct ses_api_t - { - /** - * The arguments for the session driver. These are provided by the user - * in 'httpd.conf' or '.htaccess' files. - * This one contains data as parsed by the driver itself. - */ - void* arguments; - /** - * This member is meant for the driver to pass additional information to - * itself. - */ - void* dr_data; - /** - * This function is always called first (before any actual session - * operation is invoked). - * <p>This function is intended for drivers that support persistent - * connections.</p> - */ - int (*InitConnection) (PerSessionData*, request_context*, void **); - /** - * This function must be called last. - */ - int (*EndConnection) (PerSessionData*, request_context*, void *); - /** - * This function creates a new session. - */ - int (*RegisterID) (PerSessionData*, request_context*, void *); - /** - * This function closes an existing session. - */ - int (*UnregisterID) (PerSessionData*, request_context*, void *); - /** - * This function sets the duration of an existing session. - */ - int (*SetDuration) (PerSessionData*, request_context*, void *); - /** - * This function fetches data from the session manager if the session with - * the ID given in the <code>PerSessionData</code> actually exists. - */ - int (*GetSessionData) (PerSessionData*, request_context*, void *); - /** - * Sets the data of an existing session. - */ - int (*SetSessionData) (PerSessionData*, request_context*, void *); - }; - - /** * The main entry function of an EHTML file. This function is called upon a * request for the EHTML file. --- 155,158 ---- *************** *** 215,217 **** --- 160,165 ---- typedef int (*ehtml_run_func) ( request_context* ); + //@TODO: we can write a better random number generator. + #define ehtml_random() random() + #endif /*_EHTML_H_*/ |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:24:20
|
Update of /cvsroot/mod-c/ehtml/src In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv12608/src Modified Files: Common.cpp Log Message: * Wrote hex_aton. * Recoded GetByteFromHex into 2 calls of hex_aton. * Wrote xatoul. * Wrote is_directory. * Wrote xmemdup. Index: Common.cpp =================================================================== RCS file: /cvsroot/mod-c/ehtml/src/Common.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Common.cpp 13 Mar 2006 15:52:04 -0000 1.6 --- Common.cpp 8 Sep 2006 14:24:05 -0000 1.7 *************** *** 19,25 **** ***************************************************************************/ ! #include <Common.h> #include <stdlib.h> #include <sstream> using namespace std; --- 19,26 ---- ***************************************************************************/ ! #include "Common.h" #include <stdlib.h> #include <sstream> + #include <ctype.h> using namespace std; *************** *** 192,214 **** } ! static inline unsigned char GetByteFromHex( char a, char b ) { ! register unsigned char retVal = 0; if ( a >= '0' && a <= '9' ) ! retVal |= (a - '0') << 4; else if ( a >= 'a' && a <= 'f' ) ! retVal |= (a - 'a' + 10) << 4; else if ( a >= 'A' && a <= 'F' ) ! retVal |= (a - 'A' + 10) << 4; ! if ( b >= '0' && b <= '9' ) ! retVal |= b - '0'; ! else if ( b >= 'a' && b <= 'f' ) ! retVal |= b - 'a' + 10; ! else if ( b >= 'A' && b <= 'F' ) ! retVal |= b - 'A' + 10; ! return retVal; } --- 193,213 ---- } ! static inline unsigned char hex_aton(char a) { ! unsigned char c = 0xff; if ( a >= '0' && a <= '9' ) ! c = (a - '0'); else if ( a >= 'a' && a <= 'f' ) ! c = (a - 'a' + 10); else if ( a >= 'A' && a <= 'F' ) ! c = (a - 'A' + 10); ! return c; ! } ! static inline unsigned char GetByteFromHex( char a, char b ) ! { ! return (hex_aton(a) << 4) | hex_aton(b); } *************** *** 254,255 **** --- 253,465 ---- return -1; } + + const char* ehtml_strerror(int errno) { + if (errno >= 0) + return strerror(errno); + switch (errno) { + case EHTML_ERR: return "Unspecified error"; + case EHTML_TIMEOUT: return "Timeout"; + case EHTML_INVALID_CALL: return "Invalid call"; + } + return "Unknown error"; + } + + static const char h2c[17] = "0123456789ABCDEF"; + + static inline bool must_escape(char c) { + return !isalnum(c) && c != '-' && c != '_'; + } + + string urlencode(const string& s) { + //@todo better way to fix this const issue? + return urlencode(MemBuf::Dup((void*)s.c_str(), s.length())); + } + + string urlencode(const MemBuf& mb) { + size_t n_escape = 0; + const char* s = mb.Char(); + for (int i = mb.Size(); i--;) + if (must_escape(s[i])) + ++n_escape; + + string dev; + dev.reserve(mb.Size() + 2 * n_escape + 1); + + size_t i_escape = 0; + size_t size = mb.Size(); + for (int i = 0; i < size; ++i) { + if (!must_escape(s[i])) { + dev += s[i]; + continue; + } + char escape[4] = { + '%', + h2c[(dev[i] >> 4) & 0x0f], + h2c[dev[i] & 0x0f], + '\0' + }; + dev += escape; + } + + return dev; + } + + MemBuf urldecode(const string& s) throw (const char*) { //@todo test + MemBuf dev(strdup(s.c_str()), s.length()+1); + char* obuf = dev.Char(); + int ii = 0; + int i = 0; + for (; ii < dev.Size(); ++i, ++ii) { + if (obuf[ii] != '%') + continue; + if (ii >= dev.Size() - 2) + throw "Invalid string to decode"; + dev[i] = GetByteFromHex(obuf[++ii], obuf[++ii]); + } + dev.resize(i); + return dev; + } + + string hexencode(const MemBuf& mb) { + string dev; + dev.reserve(mb.Size()*2+1); + + for (int i = 0; i < mb.Size(); ++i) { + char c = mb.Char()[i]; + dev += h2c[(c >> 4) & 0x0f]; + dev += h2c[c & 0x0f]; + } + + return dev; + } + + MemBuf hexdecode(const string& s) throw (const char*) { + MemBuf dev; + dev.resize(s.length()/2); + char* obuf = dev.Char(); + if (s.length() & 1) + throw "Invalid format"; + for (int i = 0; i < s.length(); ++i) + dev[i>>1] = GetByteFromHex(s[i], s[++i]); + return dev; + } + + char _b64[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456879" + "+/"; + + std::string base64encode(const MemBuf& mb) { //@todo test + string dev; + dev.reserve(mb.Size() * 4 / 3 + 2); + int i = 0; + while (mb.Size() - i >= 3) { + const char* in = mb.Char()+i; + char out[5] = { + // XX00 0000 | XX00 1111 | XX11 1122 | XX22 2222 + _b64[(in[0] >> 2) & 0x03f], + _b64[((in[0] << 4) & 0x030) | ((in[1] >> 4) & 0x00f)], + _b64[((in[1] << 2) & 0x03C) | ((in[2] >> 6) & 0x003)], + _b64[(in[2] & 0x03f)], + '\0' + }; + dev += out; + i += 3; + } + switch (mb.Size() - i) { + case 0: + break; + case 1: { // 1 byte missing + const char* in = mb.Char()+i; + char out[5] = { + // XX00 0000 | XX00 1111 | XX11 1122 | XX22 2222 + _b64[(in[0] >> 2) & 0x03f], + _b64[((in[0] << 4) & 0x030)], + '=', '=', '\0' + }; + dev += out; + } + break; + case 2: { // 2 bytes missing + const char* in = mb.Char()+i; + char out[5] = { + // XX00 0000 | XX00 1111 | XX11 1122 | XX22 2222 + _b64[(in[0] >> 2) & 0x03f], + _b64[((in[0] << 4) & 0x030) | ((in[1] >> 4) & 0x00f)], + _b64[((in[1] << 2) & 0x03C)], + '=', + '\0' + }; + dev += out; + } + break; + } + return dev; + } + + unsigned char _b64_aton(char c) { + if (c >= 'A' && c <= 'Z') return int(c-'A'); + if (c >= 'a' && c <= 'z') return int(c-'a') + ('Z'-'A'); + if (c >= '0' && c <= '9') return int(c-'0') + ('z'-'a') + ('Z'-'A'); + if (c == '+') return 62; + if (c == '/') return 63; + if (c == '=') return 0; + return 255; + } + + MemBuf base64decode(const std::string& s) throw (const char*) { //@todo test + // 0000 0011 | 1111 2222 | 2233 3333 + MemBuf dev; + dev.resize(s.length() * 3 / 4); + if (s.length() & 0x03) + throw "Invalid base64 string."; + int ii = 0; + int i = 0; + for (; i < s.length();) { + const char* in = s.c_str()+i; + unsigned char iv[4] = { + _b64_aton(in[0]), + _b64_aton(in[1]), + _b64_aton(in[2]), + _b64_aton(in[3]) + }; + dev.Char()[ii++] = (iv[0] << 2) | (iv[1] >> 4); + dev.Char()[ii++] = (iv[1] << 4) | (iv[2] >> 2); + dev.Char()[ii++] = (iv[2] << 6) | (iv[3]); + i += 4; + } + return dev; + } + + unsigned long xatoul(const char* s) throw (const char*) { //@todo test + char* end; + if (!s || !s[0]) + throw "Invalid string for unsigned long"; + unsigned long dev = strtol(s, &end, 10); + if (*end) + throw "Invalid string for unsigned long"; + return dev; + } + + double xatod(const char* s) throw (const char*) { //@todo test + char* end; + if (!s || !s[0]) + throw "Invalid string for unsigned long"; + double dev = strtod(s, &end); + if (*end) + throw "Invalid string for unsigned long"; + return dev; + } + + bool is_directory(const char* name) { + struct stat st; + return stat(name, &st) == 0 && S_ISDIR(st.st_mode); + } + + void* xmemdup(const void* p, size_t n) { + void* dev = malloc(n); + assert(dev != NULL); + return memcpy(dev, p, n); + } + |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:24:16
|
Update of /cvsroot/mod-c/ehtml/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv12608/include Modified Files: Common.h Log Message: * Wrote hex_aton. * Recoded GetByteFromHex into 2 calls of hex_aton. * Wrote xatoul. * Wrote is_directory. * Wrote xmemdup. Index: Common.h =================================================================== RCS file: /cvsroot/mod-c/ehtml/include/Common.h,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Common.h 6 Mar 2006 08:00:34 -0000 1.7 --- Common.h 8 Sep 2006 14:24:05 -0000 1.8 *************** *** 24,27 **** --- 24,29 ---- //#include <new> + #include <string> + #include "MemBuf.h" #include "ehtml.h" #include <apr_pools.h> *************** *** 175,178 **** --- 177,198 ---- extern int GetByteFromString( unsigned char * buf, int buf_len, const char * hex_string ); + const char* ehtml_strerror(int errno); + + std::string urlencode(const MemBuf& mb); //TODO: updateme + std::string urlencode(const std::string& s); //TODO: updateme + MemBuf urldecode(const std::string& s) throw (const char*); //TODO: updateme + + std::string hexencode(const MemBuf& mb); //TODO: writeme + MemBuf hexdecode(const std::string& s) throw (const char*); //TODO: writeme + + std::string base64encode(const MemBuf& mb); //TODO: writeme + MemBuf base64decode(const std::string& s) throw (const char*); //TODO: writeme + + unsigned long xatoul(const char* s) throw(const char*); + double xatod(const char* s) throw(const char*); + bool is_directory(const char* filename); + + void* xmemdup(const void* p, size_t n); + #ifdef DEBUG #define ASSERT( expr ) {\ |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:22:51
|
Update of /cvsroot/mod-c/ehtml/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv12336/include Added Files: MemBuf.h Log Message: A convenience Memory Buffer class. --- NEW FILE: MemBuf.h --- #ifndef __MEMBUF_H_ #define __MEMBUF_H_ #include <assert.h> #include <stddef.h> #include <stdlib.h> #include <string> //TODO: document class MemBuf { class Buf { void* _buf; size_t _size; size_t _refcnt; Buf(): _buf(NULL), _size(0), _refcnt(0) { ; } Buf(void* p, size_t s); ~Buf(); friend class MemBuf; }; Buf* _b; public: MemBuf(): _b(NULL) { ; } MemBuf(void* p, size_t l): _b(new Buf(p,l)) { ; } MemBuf(size_t l): _b(new Buf(malloc(l),l)) { ; } MemBuf(const MemBuf& mb): _b(mb._b) { _b->_refcnt++; } ~MemBuf(); static MemBuf Dup(const void* p, size_t l); void* Buffer() { return _b->_buf; } const void* Buffer() const { return _b->_buf; } size_t Size() const { return _b->_size; } char& operator[](int x) { return ((char*)_b->_buf)[x]; } char* Char() { return (char*)_b->_buf; } const char* Char() const { return (const char*)_b->_buf; } std::string AsString() throw (const char*); void resize(size_t s); }; #endif |
From: Gonzalo A. <ga...@us...> - 2006-09-08 14:22:50
|
Update of /cvsroot/mod-c/ehtml/src In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv12336/src Added Files: MemBuf.cpp Log Message: A convenience Memory Buffer class. --- NEW FILE: MemBuf.cpp --- #include "MemBuf.h" #include "Common.h" #include <stdlib.h> MemBuf::Buf::Buf(void* p, size_t s): _buf(p), _size(s), _refcnt(1) { } MemBuf::Buf::~Buf() { free(_buf); } MemBuf::~MemBuf() { if (_b && _b->_refcnt == 1) { delete _b; } else { _b->_refcnt--; } } void MemBuf::resize(size_t s) { assert(_b != NULL); void* p = realloc(_b->_buf, s); if (p == NULL) throw "Not enough memory"; _b->_buf = p; _b->_size = s; } MemBuf MemBuf::Dup(const void* p, size_t l) { return MemBuf(xmemdup(p,l),l); } using namespace std; string MemBuf::AsString() throw (const char*) { string dev(Char()); if (Size()-1 != dev.length()) throw "Invalid string representation"; return dev; } |
From: Gonzalo A. <ga...@us...> - 2006-09-08 13:55:47
|
Update of /cvsroot/mod-c/ehtml In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv970 Modified Files: ChangeLog Log Message: Meaningless cosmetic changes. Index: ChangeLog =================================================================== RCS file: /cvsroot/mod-c/ehtml/ChangeLog,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ChangeLog 23 Aug 2006 10:44:19 -0000 1.2 --- ChangeLog 8 Sep 2006 13:55:43 -0000 1.3 *************** *** 1,13 **** 2006-01-07 Matej Urbas <mat...@gm...> ! - I have decided that EHTML be designed for speed in favour to ! 'careless-programmer-correction' bullshit. Which strengthens the fact that ! EHTML is not quite suitable for script kiddies. ! I have replaced all string objects with pointers to char (char*). Which ! reduces the amount of memory allocations and avoids other types of ! overhead (thereby programmers take the responsibility of being a little ! careful). ! - Redesigned the 'tag rendering' infrastructure to easier implement true ! style attributes... --- 1,15 ---- 2006-01-07 Matej Urbas <mat...@gm...> ! * EHTML: ! I have decided that EHTML be designed for speed in favour to ! 'careless-programmer-correction' bullshit. Which strengthens the fact ! that EHTML is not quite suitable for script kiddies. ! I have replaced all string objects with pointers to char (char*). Which ! reduces the amount of memory allocations and avoids other types of ! overhead (thereby programmers take the responsibility of being a little ! careful). ! ! * Tar rendering: ! Has been redesigned to easier implement true style attributes... |
From: Gonzalo A. <ga...@us...> - 2006-08-25 14:25:46
|
Update of /cvsroot/mod-c/mod_c/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv13415 Modified Files: mod_c.h Log Message: [RS]DEBUG are NOOPS ifndef DEBUG (suggested by Matej Urbas). Index: mod_c.h =================================================================== RCS file: /cvsroot/mod-c/mod_c/include/mod_c.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mod_c.h 25 Aug 2006 14:08:38 -0000 1.4 --- mod_c.h 25 Aug 2006 14:25:40 -0000 1.5 *************** *** 88,91 **** --- 88,93 ---- } ehtml_rec; + #ifdef DEBUG + #define RDEBUG(level,request,msg,...) \ SDEBUG(level, (request)->server, msg, ## __VA_ARGS__) *************** *** 93,95 **** --- 95,104 ---- ap_log_error(__FILE__, __LINE__, level, 0, server, msg, ## __VA_ARGS__) + #else + + #define RDEBUG(level,request,msg,...) + #define SDEBUG(level,server,msg,...) + + #endif + #endif |
From: Gonzalo A. <ga...@us...> - 2006-08-25 14:24:00
|
Update of /cvsroot/mod-c/mod_c/src In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv12589 Modified Files: ChangeLog Log Message: Updated. Index: ChangeLog =================================================================== RCS file: /cvsroot/mod-c/mod_c/src/ChangeLog,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ChangeLog 23 Aug 2006 10:43:38 -0000 1.1 --- ChangeLog 25 Aug 2006 14:23:57 -0000 1.2 *************** *** 1,3 **** 2006-08-23 Matej Urbas <mat...@gm...> ! * ChangeLog: Added ChangeLog. --- 1,20 ---- + + 2006-08-25 Gonzalo Arana <gon...@gm...> + + * bootstrap does not delete unmodified files. + * cosmetic change: define RDEBUG & SDEBUG macros. + * cosmetic change: cached_ehtml is renamed to ehtml_rec. + * ehtml_rec has two new fields: mtime & size (used for auto-reloading). + * lib_cache: PutEHTMLIntoCache changes its signature. + * lib_cache: LoadEHTMLFile changes its signature. + * lib_cache: defined LoadAndCacheEHTML. + * lib_cache functions smaller. + * mod_c.c: defined c_[sdp]config() to get mod_c configuration. + * mod_c.c: CHandler: changed behaviour, supporting auto cache & + auto-refreshing ehtml files. + * mod_c.c: cosmetic change in command record definitions. + 2006-08-23 Matej Urbas <mat...@gm...> ! * ChangeLog: Added ChangeLog. ! |
From: Gonzalo A. <ga...@us...> - 2006-08-25 14:08:42
|
Update of /cvsroot/mod-c/mod_c/include In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv5622/include Modified Files: mod_c.h Log Message: Forgot to commit this file: * cosmetic change: define RDEBUG & SDEBUG macros. * cosmetic change: cached_ehtml is renamed to ehtml_rec. * ehtml_rec has two new fields: mtime & size (used for auto-reloading). Index: mod_c.h =================================================================== RCS file: /cvsroot/mod-c/mod_c/include/mod_c.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** mod_c.h 1 Feb 2006 21:37:58 -0000 1.3 --- mod_c.h 25 Aug 2006 14:08:38 -0000 1.4 *************** *** 56,60 **** --- 56,95 ---- */ int disable_session_server; + /** + * On demand application loading. + */ + int allow_on_demand; + /** + * On demand application reloading. + */ + int allow_auto_refresh; }; + typedef struct ehtml_rec + { + /** + * File handle + */ + void* fileh; + /** + * Entry function + */ + void* entryf; + /** + * Application's file modification time. + * This is used for auto-reloading. + */ + time_t mtime; + /** + * Application's file size. + * This is used for auto-reloading. + */ + off_t size; + } ehtml_rec; + + #define RDEBUG(level,request,msg,...) \ + SDEBUG(level, (request)->server, msg, ## __VA_ARGS__) + #define SDEBUG(level,server,msg,...) \ + ap_log_error(__FILE__, __LINE__, level, 0, server, msg, ## __VA_ARGS__) + #endif |
From: Gonzalo A. <ga...@us...> - 2006-08-25 13:28:30
|
Update of /cvsroot/mod-c/mod_c In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv19171 Modified Files: bootstrap.sh Log Message: cosmetic changes. Index: bootstrap.sh =================================================================== RCS file: /cvsroot/mod-c/mod_c/bootstrap.sh,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** bootstrap.sh 23 Aug 2006 14:16:38 -0000 1.1 --- bootstrap.sh 25 Aug 2006 13:28:20 -0000 1.2 *************** *** 7,11 **** rm -rvf configure config.log config.h autom4te.cache aclocal.m4 rm -rvf Makefile.in stamp-h.in src/Makefile.in ! rm -rvf cfgaux/[a-z]* src/cfgaux/[a-z]* config.status config.guess mkdir cfgaux || true --- 7,12 ---- rm -rvf configure config.log config.h autom4te.cache aclocal.m4 rm -rvf Makefile.in stamp-h.in src/Makefile.in ! rm -rvf cfgaux/[a-z]* src/cfgaux/[a-z]* ! rm -rvf config.status config.guess mkdir cfgaux || true |
From: Gonzalo A. <ga...@us...> - 2006-08-25 13:27:47
|
Update of /cvsroot/mod-c/mod_c/src In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv16606 Modified Files: lib_cache.h lib_cache.cpp mod_c.c Log Message: * cosmetic change: define RDEBUG & SDEBUG macros. * cosmetic change: cached_ehtml is renamed to ehtml_rec. * ehtml_rec has two new fields: mtime & size (used for auto-reloading). * lib_cache: PutEHTMLIntoCache changes its signature (add ehtml_rec). * lib_cache: removed GetEHTMLEntry. * lib_cache: added LoadEHTMLFile (like GetEHTMLEntry, but uses ehtml_rec). * lib_cache: defined LoadAndCacheEHTML. * lib_cache functions smaller. * mod_c.c: defined c_[sdp]config() to get mod_c configuration. * mod_c.c: CHandler: changed behaviour, supporting auto cache & auto-refreshing ehtml files. * mod_c.c: cosmetic change in command record definitions. Index: lib_cache.cpp =================================================================== RCS file: /cvsroot/mod-c/mod_c/src/lib_cache.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** lib_cache.cpp 1 Feb 2006 21:37:58 -0000 1.3 --- lib_cache.cpp 25 Aug 2006 13:27:41 -0000 1.4 *************** *** 19,22 **** --- 19,23 ---- ***************************************************************************/ + #include "mod_c.h" #include "lib_cache.h" *************** *** 24,28 **** #include <dlfcn.h> #include <string.h> - #include "mod_c.h" #include <ehtml.h> --- 25,28 ---- *************** *** 37,48 **** }; ! struct cached_ehtml ! { ! void * handle; ! void * entry_func; ! int ref_count; ! }; ! ! typedef map< const char *, cached_ehtml, lib_cache_StringCompare > EHTMLCacheMap; #ifdef __cplusplus --- 37,41 ---- }; ! typedef map< const char *, ehtml_rec, lib_cache_StringCompare > EHTMLCacheMap; #ifdef __cplusplus *************** *** 56,108 **** } ! int PutEHTMLIntoCache( void * cache, const char * ehtml ) { ! pair< char *, cached_ehtml > _tmp; ! if ( ( _tmp.second.handle = dlopen( ehtml, RTLD_LAZY ) ) ) ! { ! if ( ( _tmp.second.entry_func = dlsym( _tmp.second.handle, EHTML_ENTRY_FUNC ) ) ) ! { ! _tmp.second.ref_count = 0; ! register int i = strlen( ehtml ) + 1; ! _tmp.first = new char[ i ]; ! memcpy( _tmp.first, ehtml, i ); ! EHTMLCacheMap * map = (EHTMLCacheMap *) cache; ! map->insert( _tmp ); ! return 0; ! } ! else ! { ! dlclose( _tmp.second.handle ); ! return 1; ! } ! } ! else ! return 1; } ! void* GetEHTMLEntry( void * cache, const char * ehtml ) { EHTMLCacheMap * map = (EHTMLCacheMap *) cache; EHTMLCacheMap::iterator itr = map->find( ehtml ); ! if ( itr != map->end() ) ! { ! itr->second.ref_count++; ! return itr->second.entry_func; ! } ! else ! return 0; } ! void ReleaseEHTMLEntry( void * cache, const char * ehtml ) { ! EHTMLCacheMap * map = (EHTMLCacheMap *) cache; ! EHTMLCacheMap::iterator itr = map->find( ehtml ); ! if ( itr != map->end() && itr->second.ref_count > 1 ) ! itr->second.ref_count--; } #ifdef __cplusplus --- 49,132 ---- } ! int LoadEHTMLFile(const char* ehtml, ehtml_rec* e) { ! e->fileh = dlopen(ehtml, RTLD_LAZY); ! if (e->fileh == NULL) ! return -1; ! e->entryf = dlsym(e->fileh, EHTML_ENTRY_FUNC); ! if (e->entryf == NULL) { ! ehtml_close(e); ! dlclose(e->fileh); ! e->fileh = NULL; ! return -1; ! } ! e->mtime = 0; ! e->size = 0; ! struct stat st; ! // If the stat fails, we simply ignore this. ! if (stat(ehtml, &st) == 0) { ! e->mtime = st.st_mtime; ! e->size = st.st_size; ! } ! return 0; ! } ! const char* LoadAndCacheEHTML(void* cache, const char* ehtml, ehtml_rec* e) ! { ! if (LoadEHTMLFile(ehtml, e) < 0) ! return dlerror(); ! if (PutEHTMLIntoCache(cache, ehtml, e) < 0) ! return strerror(errno); ! return NULL; ! } ! int PutEHTMLIntoCache(void * cache, const char* ehtml, ehtml_rec* e ) ! { ! pair< char *, ehtml_rec > _tmp; ! _tmp.first = strdup(ehtml); ! memcpy(&_tmp.second, e, sizeof(*e)); ! ! EHTMLCacheMap * map = (EHTMLCacheMap *) cache; ! bool ok = map->insert( _tmp ).second; ! if (!ok) { ! free(_tmp.first); ! _tmp.first = NULL; ! ehtml_close(&_tmp.second); ! } ! return ok ? 0 : -1; } ! int GetEHTMLEntry(void * cache, const char * ehtml, ehtml_rec* e) { EHTMLCacheMap * map = (EHTMLCacheMap *) cache; EHTMLCacheMap::iterator itr = map->find( ehtml ); ! if ( itr == map->end() ) ! return -1; ! memcpy(e, &itr->second, sizeof(*e)); ! return 0; } ! int ReleaseCachedEHTML(void* cache, const char* ehtml) { ! EHTMLCacheMap* map = (EHTMLCacheMap*)cache; ! EHTMLCacheMap::iterator i = map->find(ehtml); ! if (i != map->end()) { ! ehtml_close(&i->second); ! map->erase(i); ! return 0; ! } ! return -1; } + void ehtml_close(ehtml_rec* e) + { + if (e->fileh != NULL) + dlclose(e->fileh); + e->fileh = NULL; + e->entryf = NULL; + e->mtime = 0; + e->size = 0; + } #ifdef __cplusplus Index: mod_c.c =================================================================== RCS file: /cvsroot/mod-c/mod_c/src/mod_c.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** mod_c.c 23 Aug 2006 10:43:38 -0000 1.17 --- mod_c.c 25 Aug 2006 13:27:41 -0000 1.18 *************** *** 35,39 **** static const char * ehtml_handler = "ehtml-bin"; ! //static const char * root_dir_id = "__root_dir_113"; /** --- 35,54 ---- static const char * ehtml_handler = "ehtml-bin"; ! mod_c_config* c_sconfig(server_rec* s) ! { ! return (mod_c_config*) ap_get_module_config(s->module_config, &c_module); ! } ! ! mod_c_dir_config* c_dconfig(request_rec* r) ! { ! return (mod_c_dir_config*) ! ap_get_module_config(r->per_dir_config, &c_module); ! } ! ! mod_c_dir_config* c_pconfig(cmd_parms* parms) ! { ! return (mod_c_dir_config*) ! ap_get_module_config(parms->context, &c_module); ! } /** *************** *** 48,93 **** static int CHandler( request_rec *r ) { ! int retVal = DECLINED; ! if ( r->handler && strncmp( r->handler, ehtml_handler, sizeof( ehtml_handler ) ) == 0 ) ! { ! ap_log_error( __FILE__, __LINE__, LOG_ERR, 0, r->server, "The file to open: '%s'", r->filename ); ! mod_c_config * config = ( mod_c_config * ) ap_get_module_config( r->server->module_config, &c_module ); ! mod_c_dir_config* dir_config = (mod_c_dir_config*) ap_get_module_config( r->per_dir_config, &c_module ); ! void * handle_to_lib = 0; ! // Try to load the handle to the loaded library from the cache ! void * handle = GetEHTMLEntry( config->ehtml_cache, r->filename ); ! // Was the handle present in the cache ! if ( !handle ) ! { ! // The handle wasn't there - load the library to memory ! if ( ( handle_to_lib = dlopen( r->filename, RTLD_LAZY ) ) ) ! { ! handle = dlsym( handle_to_lib, EHTML_ENTRY_FUNC ); ! if ( !handle ) ! dlclose( handle_to_lib ); ! } ! } ! // We have found the library that contains the EHTML application ! // execute its ehtml_run function ! if ( handle ) ! { ! ehtml_run_func _tmp = ( ehtml_run_func ) handle; ! request_context rc = { r, config, dir_config }; ! retVal = _tmp( &rc ); ! // TODO: We don't close the EHTML file as is seems to cause a crash ! // Why would closing a dl lib crash mod_c? ! // If the EHTML application wasn't loaded from the cache, close the handle ! /*if ( handle_to_lib ) ! dlclose( handle_to_lib );*/ ! } ! else ! retVal = HTTP_INTERNAL_SERVER_ERROR; ! } ! return retVal; } --- 63,120 ---- static int CHandler( request_rec *r ) { ! mod_c_config * config; ! mod_c_dir_config* dir_config; ! int retVal; ! ehtml_rec e = { NULL, NULL, 0, 0 }; ! const char* msg = NULL; ! if (r->handler == NULL || ! strncmp(r->handler, ehtml_handler, sizeof(ehtml_handler)) != 0) { ! return DECLINED; ! } ! // We must handle this request ! RDEBUG(LOG_INFO, r, "The file to open: '%s'", r->filename); ! config = c_sconfig(r->server); ! dir_config = c_dconfig(r); ! // Try to load the handle to the loaded library from the cache ! if (GetEHTMLEntry(config->ehtml_cache, r->filename, &e) <= 0) { ! // If it was not present in cache ! // Are we allowed to serve on demand requests? ! if (!config->allow_on_demand) ! return HTTP_SERVICE_UNAVAILABLE; ! ! } else { ! ! // It was present in the cache, check for auto-refresh ! if (config->allow_auto_refresh) { ! struct stat st; ! if (stat(r->filename, &st) == 0 && ! (st.st_mtime != e.mtime || st.st_size != e.size)) { ! ReleaseCachedEHTML(config->ehtml_cache, r->filename); ! } ! } ! } ! ! // Not cached || cached but stale ! if (e.entryf == NULL) { ! RDEBUG(LOG_ERR, r, "Loading %s", r->filename); ! msg = LoadAndCacheEHTML(config->ehtml_cache, r->filename, &e); ! if (msg != NULL) { ! RDEBUG(LOG_ERR, r, "Error caching %s: %s", r->filename, msg); ! return HTTP_INTERNAL_SERVER_ERROR; ! } ! } ! ! // We have found the library that contains the EHTML application ! // execute its ehtml_run function ! ehtml_run_func _tmp = ( ehtml_run_func ) e.entryf; ! request_context rc = { r, config, dir_config }; ! retVal = _tmp( &rc ); ! ! return retVal; } *************** *** 137,144 **** config->session_server_port = -1; config->disable_session_server = 0; // Add the default session driver to the driver list const char* retVal = PutSessionDriverEx( config->session_drivers, DefaultSessionIdFunc ); if ( retVal ) ! ap_log_error( __FILE__, __LINE__, LOG_ERR, 0, s, "The default driver could not have been imported. Error message: '%s'", retVal ); return config; --- 164,174 ---- config->session_server_port = -1; config->disable_session_server = 0; + config->allow_on_demand = 0; + config->allow_auto_refresh = 0; // Add the default session driver to the driver list const char* retVal = PutSessionDriverEx( config->session_drivers, DefaultSessionIdFunc ); if ( retVal ) ! SDEBUG(LOG_ERR, s, "The default driver could not have been imported. " ! "Error message: '%s'", retVal ); return config; *************** *** 193,202 **** static char* LoadEHTMLDirective( cmd_parms* parms, void *mconfig, const char * path ) { ! mod_c_config * config = ( mod_c_config * ) ap_get_module_config( parms->server->module_config, &c_module ); ! int retVal = PutEHTMLIntoCache( config->ehtml_cache, path ); ! if ( retVal ) { char * errorMsg = ( char * ) apr_palloc( parms->temp_pool, 512 ); ! snprintf( errorMsg, 512, "LoadEHTML: Could not load the specified file '%s'. Error: '%s'.", path, dlerror() ); return errorMsg; } --- 223,235 ---- static char* LoadEHTMLDirective( cmd_parms* parms, void *mconfig, const char * path ) { ! mod_c_config * config = c_sconfig(parms->server); ! ehtml_rec e; ! const char* msg = LoadAndCacheEHTML(config->ehtml_cache, path, &e); ! if (msg != NULL) { char * errorMsg = ( char * ) apr_palloc( parms->temp_pool, 512 ); ! snprintf( errorMsg, 512, ! "LoadEHTML: Could not load the specified file '%s'. " ! "Error: '%s'.", path, msg); return errorMsg; } *************** *** 205,208 **** --- 238,255 ---- } + static char* EHTMLSetAllowOnDemand(cmd_parms* parms, void *mconfig, int flag) + { + mod_c_config* config = c_sconfig(parms->server); + config->allow_on_demand = flag; + return NULL; + } + + static char* EHTMLSetCacheAutoRefresh(cmd_parms* parms, void *mconfig, int flag) + { + mod_c_config* config = c_sconfig(parms->server); + config->allow_auto_refresh = flag; + return NULL; + } + /** * Loads and registers a session driver. *************** *** 257,262 **** static char * EHTMLSessionTypeDirective( cmd_parms* parms, void *mconfig, const char * type, const char * arguments ) { ! mod_c_config * config = ( mod_c_config * ) ap_get_module_config( parms->server->module_config, &c_module ); ! mod_c_dir_config* dir_config = (mod_c_dir_config*) ap_get_module_config( parms->context, &c_module ); // Search for the session driver that supports the desired type of session management ses_dr_info_t* dr_info = GetSessionDriver( config->session_drivers, type ); --- 304,309 ---- static char * EHTMLSessionTypeDirective( cmd_parms* parms, void *mconfig, const char * type, const char * arguments ) { ! mod_c_config * config = c_sconfig(parms->server); ! mod_c_dir_config* dir_config = c_pconfig(parms); // Search for the session driver that supports the desired type of session management ses_dr_info_t* dr_info = GetSessionDriver( config->session_drivers, type ); *************** *** 310,314 **** static char * EHTMLCookielessDirective( cmd_parms * parms, void *mconfig, int on) { ! mod_c_dir_config* dir_config = (mod_c_dir_config*) ap_get_module_config( parms->context, &c_module ); dir_config->cookieless = ( on != 0 ); return 0; --- 357,361 ---- static char * EHTMLCookielessDirective( cmd_parms * parms, void *mconfig, int on) { ! mod_c_dir_config* dir_config = c_pconfig(parms); dir_config->cookieless = ( on != 0 ); return 0; *************** *** 329,333 **** else { ! mod_c_dir_config* dir_config = (mod_c_dir_config*) ap_get_module_config( parms->context, &c_module ); dir_config->key_size = bytes; return 0; --- 376,380 ---- else { ! mod_c_dir_config* dir_config = c_pconfig(parms); dir_config->key_size = bytes; return 0; *************** *** 337,347 **** command_rec c_commands[] = { ! AP_INIT_TAKE1("LoadEHTML", (void*)LoadEHTMLDirective, NULL, RSRC_CONF, "Arguments: a valid absolute path to an ehtml file. If you change the ehtml file in time the server is running, you will have to restart the server for changes to take effect." ), ! AP_INIT_TAKE1("LoadEHTMLSessionDriver", (void*)LoadEHTMLSessionDriver, NULL, RSRC_CONF, "Arguments: a valid absolute path to a session driver file." ), ! AP_INIT_FLAG("EHTMLSessions", (void*)EHTMLSessionsDirective, NULL, OR_LIMIT, "< on | off > - 'on' enables sessions while 'off' disables them." ), ! AP_INIT_TAKE1("EHTMLSessionDuration", (void*)EHTMLSessionDurationDirective, NULL, OR_LIMIT, "Specify the number of minutes, default is 30 minutes." ), ! AP_INIT_TAKE12("EHTMLSessionType", (void*)EHTMLSessionTypeDirective, NULL, OR_LIMIT, "< type > [ arguments ] - the first parameter is mandatory, while the second one is needed only if the selected type of session management needs it." ), ! AP_INIT_FLAG("EHTMLCookieless", (void*)EHTMLCookielessDirective, NULL, OR_LIMIT, "< on | off > - 'on' disables cookies while 'off' enables them." ), ! AP_INIT_TAKE1("EHTMLSessionIdSize", (void*)EHTMLSessionIdSizeDirective, NULL, OR_LIMIT, "The number of bytes" ), { NULL } }; --- 384,427 ---- command_rec c_commands[] = { ! AP_INIT_TAKE1("LoadEHTML", (void*)LoadEHTMLDirective, NULL, RSRC_CONF, ! "Arguments: a valid absolute path to an ehtml file. " ! "If you change the ehtml file in time the server is running, " ! "you will have to restart the server for changes to take effect." ), ! ! AP_INIT_FLAG("EHTMLAllowOnDemand", (void*)EHTMLSetAllowOnDemand, NULL, ! RSRC_CONF, "Argument: on|off. If set to 'on', EHTML applications " ! "are loaded on demand."), ! ! AP_INIT_FLAG("EHTMLCacheAutoRefresh", (void*)EHTMLSetCacheAutoRefresh, ! NULL, RSRC_CONF, ! "Argument: on|off. If set to 'on', EHTML cached applications will " ! "be checked on each request. If the file is modified, it will be " ! "reloaded."), ! ! // Session directives ! AP_INIT_TAKE1("LoadEHTMLSessionDriver", (void*)LoadEHTMLSessionDriver, ! NULL, RSRC_CONF, ! "Arguments: a valid absolute path to a session driver file." ), ! ! AP_INIT_FLAG("EHTMLSessions", (void*)EHTMLSessionsDirective, NULL, ! OR_LIMIT, "< on | off > - 'on' enables sessions while 'off' " ! "disables them." ), ! ! AP_INIT_TAKE1("EHTMLSessionDuration", (void*)EHTMLSessionDurationDirective, ! NULL, OR_LIMIT, "Specify the number of minutes, default is 30 " ! "minutes." ), ! ! AP_INIT_TAKE12("EHTMLSessionType", (void*)EHTMLSessionTypeDirective, NULL, ! OR_LIMIT, "< type > [ arguments ] - the first parameter is " ! "mandatory, while the second one is needed only if the selected " ! "type of session management needs it." ), ! ! AP_INIT_FLAG("EHTMLCookieless", (void*)EHTMLCookielessDirective, NULL, ! OR_LIMIT, "< on | off > - 'on' disables cookies while 'off' " ! "enables them." ), ! ! AP_INIT_TAKE1("EHTMLSessionIdSize", (void*)EHTMLSessionIdSizeDirective, ! NULL, OR_LIMIT, "The number of bytes" ), ! { NULL } }; *************** *** 357,358 **** --- 437,439 ---- CRegisterHooks }; + Index: lib_cache.h =================================================================== RCS file: /cvsroot/mod-c/mod_c/src/lib_cache.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** lib_cache.h 23 Aug 2006 10:43:38 -0000 1.3 --- lib_cache.h 25 Aug 2006 13:27:41 -0000 1.4 *************** *** 25,28 **** --- 25,29 ---- extern "C" { + #include "mod_c.h" #endif *************** *** 44,49 **** * @param lib_filename * The name of the EHTML file to load. */ ! int PutEHTMLIntoCache( void * map, const char * lib_filename); /** --- 45,53 ---- * @param lib_filename * The name of the EHTML file to load. + * + * @param e_rec + * <rec>ehtml_rec*</code> structure describing ehtml handle. */ ! int PutEHTMLIntoCache( void * map, const char * lib_filename, ehtml_rec* e_rec); /** *************** *** 57,75 **** * @param lib_filename * The name of the EHTML file to lookup. */ ! void* GetEHTMLEntry( void * map, const char * lib_filename); /** ! * Removes a loaded EHTML file from the map (the cache). * ! * @param map ! * The map that was created with and returned by ! * <code>CreateEHTMLCache</code>. * ! * @param lib_filename ! * The name of the EHTML file to remove. */ ! void ReleaseEHTMLEntry( void * map, const char * lib_filename); #ifdef __cplusplus } --- 61,117 ---- * @param lib_filename * The name of the EHTML file to lookup. + * + * @param e_rec + * <rec>ehtml_rec*</code> structure describing ehtml handle. */ ! int GetEHTMLEntry( void * map, const char * lib_filename, ehtml_rec* e_rec); /** ! * Removes a cached EHTML entry. ! * Returns 0 if it was successfully erased. * ! * @param cache ! * The map that should have the entry. * ! * @param ehtml ! * filename that contains the application to unload. */ ! int ReleaseCachedEHTML(void* cache, const char* ehtml); ! ! /** ! * Loads the EHTML application in the file specified in <code>ehtml</code>. ! * Return <code>null</code>. ! * ! * @param ehtml ! * The filename containing the EHTML application. ! * ! * @param e_rec ! * The application handler. ! */ ! int LoadEHTMLFile(const char* ehtml, ehtml_rec* e_rec); ! ! /** ! * Loads and cache the EHTML application in the file specified ! * in <code>ehtml</code>. ! * Return <code>null</code>. ! * ! * @param cache ! * The EHTML application cache. ! * ! * @param ehtml ! * The filename containing the EHTML application. ! * ! * @param e_rec ! * The application handler. ! */ ! const char* LoadAndCacheEHTML(void* cache, const char* ehtml, ehtml_rec* e); + /** + * Closes the EHTML application handler. + * + * @param e_rec + * The handle to close. + */ + void ehtml_close(ehtml_rec* e_rec); #ifdef __cplusplus } |
From: Gonzalo A. <ga...@us...> - 2006-08-23 16:22:55
|
Update of /cvsroot/mod-c/ehtml In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv4634 Modified Files: Makefile.am Log Message: doxygen support for automatic documentation. Index: Makefile.am =================================================================== RCS file: /cvsroot/mod-c/ehtml/Makefile.am,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Makefile.am 22 Aug 2006 18:36:19 -0000 1.3 --- Makefile.am 23 Aug 2006 16:22:36 -0000 1.4 *************** *** 1,3 **** ! SUBDIRS = src include samples --- 1,3 ---- ! SUBDIRS = src include samples $(DOXYGEN_SUBDIR) |
From: Gonzalo A. <ga...@us...> - 2006-08-23 16:22:03
|
Update of /cvsroot/mod-c/mod_c/doc In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv4241/doc Added Files: Makefile.am mod_c.doxy Log Message: doxygen support for automatic documentation. --- NEW FILE: mod_c.doxy --- # Doxyfile 1.4.2 # $Id: mod_c.doxy,v 1.1 2006/08/23 16:21:58 garana Exp $ # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded [...1181 lines suppressed...] # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO --- NEW FILE: Makefile.am --- # $Id: Makefile.am,v 1.1 2006/08/23 16:21:58 garana Exp $ all-local: $(DOXYGEN) mod_c.doxy clean-local: rm -rf html latex #dist-hook: # |
From: Gonzalo A. <ga...@us...> - 2006-08-23 16:22:03
|
Update of /cvsroot/mod-c/mod_c In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv4241 Modified Files: configure.ac Makefile.am Log Message: doxygen support for automatic documentation. Index: configure.ac =================================================================== RCS file: /cvsroot/mod-c/mod_c/configure.ac,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** configure.ac 23 Aug 2006 16:13:38 -0000 1.6 --- configure.ac 23 Aug 2006 16:21:58 -0000 1.7 *************** *** 25,28 **** --- 25,53 ---- ############################################################################## + AC_ARG_WITH([doxygen], AS_HELP_STRING([--with-doxygen],[enable documentation build via doxygen]),[ + DOXYGEN= + DOXYGEN_SUBDIR= + DOXYGEN_SEARCH="${withval} /usr/bin/doxygen" + AC_MSG_CHECKING([for doxygen in '${DOXYGEN_SEARCH}']) + for i in ${DOXYGEN_SEARCH}; do + if test -x $i; then + DOXYGEN=$i + fi + done + if test -z "${DOXYGEN}"; then + AC_MSG_ERROR([Could not find doxygen in $withval /usr/bin/doxygen]) + fi + AC_MSG_RESULT([${DOXYGEN}]) + DOXYGEN_SUBDIR=doc + ],[ + DOXYGEN= + DOXYGEN_SUBDIR= + ]) + + AC_SUBST(DOXYGEN) + AC_SUBST(DOXYGEN_SUBDIR) + + ############################################################################## + # check for --with-apxs AC_MSG_CHECKING(for 'apxs') *************** *** 120,122 **** AC_SUBST(APXS) ! AC_OUTPUT([Makefile src/Makefile include/Makefile src/dss_tool/Makefile]) --- 145,152 ---- AC_SUBST(APXS) ! AC_OUTPUT([Makefile ! src/Makefile ! include/Makefile ! src/dss_tool/Makefile ! doc/Makefile]) ! Index: Makefile.am =================================================================== RCS file: /cvsroot/mod-c/mod_c/Makefile.am,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Makefile.am 22 Jan 2006 10:56:00 -0000 1.2 --- Makefile.am 23 Aug 2006 16:21:58 -0000 1.3 *************** *** 1 **** ! SUBDIRS = src include --- 1 ---- ! SUBDIRS = src include $(DOXYGEN_SUBDIR) |
From: Gonzalo A. <ga...@us...> - 2006-08-23 16:21:23
|
Update of /cvsroot/mod-c/mod_c/doc In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv4197/doc Log Message: Directory /cvsroot/mod-c/mod_c/doc added to the repository |