From 9541b9d885087474f71c66b272a0a0ae721dcc0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Wed, 29 May 2013 13:46:45 +0200 Subject: [PATCH 1/7] make README a proper formatted README.rst --- README | 2 -- README.rst | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) delete mode 100644 README create mode 100644 README.rst diff --git a/README b/README deleted file mode 100644 index 6919976..0000000 --- a/README +++ /dev/null @@ -1,2 +0,0 @@ - -fcgi-cgi is a FastCGI application to run cgi applications. diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..14825f4 --- /dev/null +++ b/README.rst @@ -0,0 +1,54 @@ +Description +----------- + +:Homepage: + http://redmine.lighttpd.net/projects/fcgi-cgi/wiki + +fcgi-cgi is a FastCGI application to run normal cgi applications. It doesn't +make CGI applications faster, but it allows you to run them on a different +host and with different user permissions (without the need for suexec). + +lighttpd2 won't have a mod_cgi, so you need this FastCGI wrapper to be able +to execute standard cgi applications like mailman and cgit. + +fcgi-cgi is released under the `MIT license `_ + +Usage +----- + +Examples for spawning a fcg-cgi instance with daemontools or runit:: + + #!/bin/sh + # run script + + exec spawn-fcgi -n -s /tmp/fastcgi-cgi.sock -u www-default -U www-data -- /usr/bin/fcgi-cgi + + +Build dependencies +------------------ + +* glib >= 2.16.0 (http://www.gtk.org/) +* libev (http://software.schmorp.de/pkg/libev.html) +* cmake or autotools (for snapshots/releases the autotool generated files are included) + + +Build +----- + +* snapshot/release with autotools:: + + ./configure + make + +* build from git: ``git clone git://git.lighttpd.net/fcgi-cgi.git`` + + * with autotools:: + + ./autogen.sh + ./configure + make + + * with cmake (should work with snapshots/releases too):: + + cmake . + make From 64c505e3c7725b18bc2ee88e1beccf518253de5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sat, 20 Jul 2013 10:30:48 +0200 Subject: [PATCH 2/7] [cmake] improve libev handling --- CMakeLists.txt | 39 ++++-------------- cmake/AddTargetProperties.cmake | 14 +++++++ cmake/FindLibEV.cmake | 71 +++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 32 deletions(-) create mode 100644 cmake/AddTargetProperties.cmake create mode 100644 cmake/FindLibEV.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 076de21..50a7f16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,49 +2,24 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR) cmake_policy(VERSION 2.6.0) +SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + INCLUDE(CheckIncludeFiles) INCLUDE(CheckLibraryExists) INCLUDE(FindPkgConfig) +INCLUDE(AddTargetProperties) -MACRO(ADD_TARGET_PROPERTIES _target _name _properties) - SET(_properties ${ARGV}) - LIST(REMOVE_AT _properties 0) - LIST(REMOVE_AT _properties 0) - GET_TARGET_PROPERTY(_old_properties ${_target} ${_name}) - #MESSAGE("adding property to ${_target} ${_name}: ${_properties}") - IF(NOT _old_properties) - # in case it's NOTFOUND - SET(_old_properties) - ELSE(NOT _old_properties) - SET(_old_properties "${_old_properties} ") - ENDIF(NOT _old_properties) - SET_TARGET_PROPERTIES(${_target} PROPERTIES ${_name} "${_old_properties}${_properties}") -ENDMACRO(ADD_TARGET_PROPERTIES) PROJECT(fcgi-cgi C) SET(PACKAGE_VERSION 0.2.1) + IF("${CMAKE_BUILD_TYPE}" STREQUAL "") SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE) ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") # libev -CHECK_INCLUDE_FILES(ev.h HAVE_EV_H) -IF(HAVE_EV_H) - CHECK_LIBRARY_EXISTS(ev ev_time "" HAVE_LIBEV) - IF(HAVE_LIBEV) - SET(EV_LIBRARIES ev) - SET(EV_STATIC_LIBRARIES ev;m) - CHECK_LIBRARY_EXISTS(rt clock_gettime "" NEED_RT) - IF(NEED_RT) - SET(EV_STATIC_LIBRARIES ${EV_STATIC_LIBRARIES} rt) - ENDIF(NEED_RT) - ELSE(HAVE_LIBEV) - MESSAGE(FATAL_ERROR "Couldn't find lib ev") - ENDIF(HAVE_LIBEV) -ELSE(HAVE_EV_H) - MESSAGE(FATAL_ERROR "Couldn't find ") -ENDIF(HAVE_EV_H) +FIND_PACKAGE(LibEV REQUIRED) # GLIB 2 pkg_check_modules (GLIB2 REQUIRED glib-2.0) @@ -64,12 +39,12 @@ add_executable(fcgi-cgi ${MAIN_SOURCE}) ADD_TARGET_PROPERTIES(fcgi-cgi COMPILE_FLAGS "-std=gnu99 -Wall -g -Wshadow -W -pedantic -fPIC -D_GNU_SOURCE") # libev -TARGET_LINK_LIBRARIES(fcgi-cgi "${EV_LIBRARIES}") +TARGET_LINK_LIBRARIES(fcgi-cgi "${LIBEV_LDFLAGS}") # GLIB 2 TARGET_LINK_LIBRARIES(fcgi-cgi "${GLIB2_LIBRARIES}") ADD_TARGET_PROPERTIES(fcgi-cgi LINK_FLAGS "${GLIB2_LDFLAGS}") -ADD_TARGET_PROPERTIES(fcgi-cgi COMPILE_FLAGS "${GLIB2_CFLAGS_OTHER}") +ADD_TARGET_PROPERTIES(fcgi-cgi COMPILE_FLAGS "${GLIB2_CFLAGS_OTHER}" "${LIBEV_CFLAGS}") INSTALL(TARGETS fcgi-cgi DESTINATION bin) diff --git a/cmake/AddTargetProperties.cmake b/cmake/AddTargetProperties.cmake new file mode 100644 index 0000000..cee7276 --- /dev/null +++ b/cmake/AddTargetProperties.cmake @@ -0,0 +1,14 @@ +MACRO(ADD_TARGET_PROPERTIES _target _name _properties) + SET(_properties ${ARGV}) + LIST(REMOVE_AT _properties 0) + LIST(REMOVE_AT _properties 0) + GET_TARGET_PROPERTY(_old_properties ${_target} ${_name}) + #MESSAGE("adding property to ${_target} ${_name}: ${_properties}") + IF(NOT _old_properties) + # in case it's NOTFOUND + SET(_old_properties) + ELSE(NOT _old_properties) + SET(_old_properties "${_old_properties} ") + ENDIF(NOT _old_properties) + SET_TARGET_PROPERTIES(${_target} PROPERTIES ${_name} "${_old_properties}${_properties}") +ENDMACRO(ADD_TARGET_PROPERTIES) diff --git a/cmake/FindLibEV.cmake b/cmake/FindLibEV.cmake new file mode 100644 index 0000000..29035e3 --- /dev/null +++ b/cmake/FindLibEV.cmake @@ -0,0 +1,71 @@ + +SET(LIBEV_PATH "" CACHE PATH "Base path for include/ev.h and lib/libev*") +SET(LIBEV_INCLUDE_PATH "" CACHE PATH "Include path for ev.h") +SET(LIBEV_LIBDIR "" CACHE PATH "Path containing libev") + +IF(LIBEV_PATH) + SET(LIBEV_INCLUDE_PATH "${LIBEV_PATH}/include" CACHE PATH "Include path for ev.h" FORCE) + SET(LIBEV_LIBDIR "${LIBEV_PATH}/lib" CACHE PATH "Path containing libev" FORCE) +ENDIF(LIBEV_PATH) + +IF(LIBEV_INCLUDE_PATH) + INCLUDE_DIRECTORIES(${LIBEV_INCLUDE_PATH}) +ENDIF(LIBEV_INCLUDE_PATH) + +# Use cached result +IF(NOT LIBEV_FOUND) + UNSET(HAVE_EV_H) + UNSET(HAVE_LIBEV) + UNSET(HAVE_EV_H CACHE) + UNSET(HAVE_LIBEV CACHE) + UNSET(LIBEV_CFLAGS) + UNSET(LIBEV_LDFLAGS) + + IF(LIBEV_INCLUDE_PATH OR LIBEV_LIBDIR) + SET(CMAKE_REQUIRED_INCLUDES ${LIBEV_INCLUDE_PATH}) +# MESSAGE(STATUS "Looking for ev.h in ${CMAKE_REQUIRED_INCLUDES}") + CHECK_INCLUDE_FILES(ev.h HAVE_EV_H) + IF(HAVE_EV_H) +# MESSAGE(STATUS "Looking for lib ev in ${LIBEV_LIBDIR}") + CHECK_LIBRARY_EXISTS(ev ev_time "${LIBEV_LIBDIR}" HAVE_LIBEV) + IF(HAVE_LIBEV) + SET(LIBEV_LIBRARIES ev CACHE INTERNAL "") + SET(LIBEV_CFLAGS "" CACHE INTERNAL "") + SET(LIBEV_LDFLAGS "-L${LIBEV_LIBDIR} -lev" CACHE INTERNAL "") + SET(LIBEV_FOUND TRUE CACHE INTERNAL "Found libev" FORCE) + ELSE(HAVE_LIBEV) + MESSAGE(STATUS "Couldn't find lib ev in ${LIBEV_LIBDIR}") + ENDIF(HAVE_LIBEV) + ELSE(HAVE_EV_H) + MESSAGE(STATUS "Couldn't find in ${LIBEV_INCLUDE_PATH}") + ENDIF(HAVE_EV_H) + ELSE(LIBEV_INCLUDE_PATH OR LIBEV_LIBDIR) + pkg_check_modules(LIBEV libev) + IF(NOT LIBEV_FOUND) +# MESSAGE(STATUS "Looking for ev.h in ${CMAKE_REQUIRED_INCLUDES}") + CHECK_INCLUDE_FILES(ev.h HAVE_EV_H) + IF(HAVE_EV_H) +# MESSAGE(STATUS "Looking for lib ev") + CHECK_LIBRARY_EXISTS(ev ev_time "" HAVE_LIBEV) + IF(HAVE_LIBEV) + SET(LIBEV_CFLAGS "" CACHE INTERNAL "") + SET(LIBEV_LDFLAGS "-lev" CACHE INTERNAL "") + SET(LIBEV_FOUND TRUE CACHE INTERNAL "Found libev" FORCE) + ELSE(HAVE_LIBEV) + MESSAGE(STATUS "Couldn't find lib ev") + ENDIF(HAVE_LIBEV) + ELSE(HAVE_EV_H) + MESSAGE(STATUS "Couldn't find ") + ENDIF(HAVE_EV_H) + ENDIF(NOT LIBEV_FOUND) + ENDIF(LIBEV_INCLUDE_PATH OR LIBEV_LIBDIR) + +ENDIF(NOT LIBEV_FOUND) + +IF(NOT LIBEV_FOUND) + IF(LibEV_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find libev") + ENDIF(LibEV_FIND_REQUIRED) +ENDIF(NOT LIBEV_FOUND) + +MARK_AS_ADVANCED(LIBEV_PATH LIBEV_INCLUDE_PATH LIBEV_LIBDIR) From ef2ff3f59969ef7b7b228ba6f3a0b716554b2586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sat, 20 Jul 2013 10:47:34 +0200 Subject: [PATCH 3/7] [cmake] fix macros, glib2 including and libev cflags --- CMakeLists.txt | 13 ++++++------- cmake/AddTargetProperties.cmake | 15 +++++++-------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50a7f16..18eed2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,7 @@ FIND_PACKAGE(LibEV REQUIRED) # GLIB 2 pkg_check_modules (GLIB2 REQUIRED glib-2.0) -SET(GLIB_INCLUDES ${GLIB2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS}/glib-2.0/ ${GLIB2_INCLUDE_DIRS}/glib-2.0/include/) -INCLUDE_DIRECTORIES(${GLIB_INCLUDES}) +INCLUDE_DIRECTORIES(${GLIB2_INCLUDES_DIRS}) SET(MAIN_SOURCE fastcgi.c fcgi-cgi.c) @@ -36,15 +35,15 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) add_executable(fcgi-cgi ${MAIN_SOURCE}) -ADD_TARGET_PROPERTIES(fcgi-cgi COMPILE_FLAGS "-std=gnu99 -Wall -g -Wshadow -W -pedantic -fPIC -D_GNU_SOURCE") +ADD_TARGET_PROPERTIES(fcgi-cgi COMPILE_FLAGS "-std=gnu99 -Wall -g -Wshadow -W -pedantic -fPIC") # libev -TARGET_LINK_LIBRARIES(fcgi-cgi "${LIBEV_LDFLAGS}") +TARGET_LINK_LIBRARIES(fcgi-cgi ${LIBEV_LDFLAGS}) +ADD_TARGET_PROPERTIES(fcgi-cgi COMPILE_FLAGS ${LIBEV_CFLAGS}) # GLIB 2 -TARGET_LINK_LIBRARIES(fcgi-cgi "${GLIB2_LIBRARIES}") -ADD_TARGET_PROPERTIES(fcgi-cgi LINK_FLAGS "${GLIB2_LDFLAGS}") -ADD_TARGET_PROPERTIES(fcgi-cgi COMPILE_FLAGS "${GLIB2_CFLAGS_OTHER}" "${LIBEV_CFLAGS}") +TARGET_LINK_LIBRARIES(fcgi-cgi ${GLIB2_LDFLAGS}) +ADD_TARGET_PROPERTIES(fcgi-cgi COMPILE_FLAGS ${GLIB2_CFLAGS}) INSTALL(TARGETS fcgi-cgi DESTINATION bin) diff --git a/cmake/AddTargetProperties.cmake b/cmake/AddTargetProperties.cmake index cee7276..17ee774 100644 --- a/cmake/AddTargetProperties.cmake +++ b/cmake/AddTargetProperties.cmake @@ -1,14 +1,13 @@ -MACRO(ADD_TARGET_PROPERTIES _target _name _properties) - SET(_properties ${ARGV}) - LIST(REMOVE_AT _properties 0) - LIST(REMOVE_AT _properties 0) +MACRO(ADD_TARGET_PROPERTIES _target _name) + SET(_properties) + FOREACH(_prop ${ARGN}) + SET(_properties "${_properties} ${_prop}") + ENDFOREACH(_prop) GET_TARGET_PROPERTY(_old_properties ${_target} ${_name}) - #MESSAGE("adding property to ${_target} ${_name}: ${_properties}") + MESSAGE(STATUS "adding property to ${_target} ${_name}:" ${_properties}) IF(NOT _old_properties) # in case it's NOTFOUND SET(_old_properties) - ELSE(NOT _old_properties) - SET(_old_properties "${_old_properties} ") ENDIF(NOT _old_properties) - SET_TARGET_PROPERTIES(${_target} PROPERTIES ${_name} "${_old_properties}${_properties}") + SET_TARGET_PROPERTIES(${_target} PROPERTIES ${_name} "${_old_properties} ${_properties}") ENDMACRO(ADD_TARGET_PROPERTIES) From 15394ede2f0fc87cbcc5a73c7946e278fc5e8df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sat, 20 Jul 2013 10:49:34 +0200 Subject: [PATCH 4/7] fix description in command line help/version --- fcgi-cgi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fcgi-cgi.c b/fcgi-cgi.c index b00188b..a67b865 100644 --- a/fcgi-cgi.c +++ b/fcgi-cgi.c @@ -22,7 +22,7 @@ #define __STR(x) #x #define ERROR(...) g_printerr("fcgi-cgi.c:" G_STRINGIFY(__LINE__) ": " __VA_ARGS__) -#define PACKAGE_DESC (PACKAGE_NAME " v" PACKAGE_VERSION " - forks and watches multiple instances of a program in the same environment") +#define PACKAGE_DESC (PACKAGE_NAME " v" PACKAGE_VERSION " - FastCGI application to run normal cgi applications") struct fcgi_cgi_server; typedef struct fcgi_cgi_server fcgi_cgi_server; From b40d34f0c844a0457f4e816ea447d1b2103c9fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sat, 20 Jul 2013 14:52:57 +0200 Subject: [PATCH 5/7] wait for proper connection close --- fastcgi.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/fastcgi.c b/fastcgi.c index 4091909..f4ad71f 100644 --- a/fastcgi.c +++ b/fastcgi.c @@ -604,7 +604,31 @@ error: static void fastcgi_connection_fd_cb(struct ev_loop *loop, ev_io *w, int revents) { fastcgi_connection *fcon = (fastcgi_connection*) w->data; - UNUSED(loop); + + if (fcon->closing) { + char buf[1024]; + ssize_t r; + + r = read(fcon->fd, buf, sizeof(buf)); + if (r > 0) return; + + if (-1 == r) switch (errno) { + case EINTR: + case EAGAIN: + #if EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: + #endif + return; /* try again later */ + default: + break; + } + + ev_io_stop(loop, w); + close(fcon->fd); + fcon->fd = -1; + ev_prepare_start(fcon->fsrv->loop, &fcon->fsrv->closing_watcher); + return; + } if (revents & EV_READ) { read_queue(fcon); @@ -637,11 +661,6 @@ static fastcgi_connection *fastcgi_connecion_create(fastcgi_server *fsrv, gint f static void fastcgi_connection_free(fastcgi_connection *fcon) { fcon->fsrv->callbacks->cb_reset_connection(fcon); - if (fcon->fd != -1) { - ev_io_stop(fcon->fsrv->loop, &fcon->fd_watcher); - close(fcon->fd); - fcon->fd = -1; - } fastcgi_queue_clear(&fcon->write_queue); fastcgi_connection_environ_clear(fcon); @@ -655,9 +674,7 @@ static void fastcgi_connection_free(fastcgi_connection *fcon) { void fastcgi_connection_close(fastcgi_connection *fcon) { fcon->closing = TRUE; if (fcon->fd != -1) { - ev_io_stop(fcon->fsrv->loop, &fcon->fd_watcher); - close(fcon->fd); - fcon->fd = -1; + shutdown(fcon->fd, SHUT_WR); } fastcgi_queue_clear(&fcon->write_queue); @@ -666,7 +683,9 @@ void fastcgi_connection_close(fastcgi_connection *fcon) { g_byte_array_set_size(fcon->parambuf, 0); fastcgi_connection_environ_clear(fcon); - ev_prepare_start(fcon->fsrv->loop, &fcon->fsrv->closing_watcher); + if (fcon->fd == -1) { + ev_prepare_start(fcon->fsrv->loop, &fcon->fsrv->closing_watcher); + } } static void fastcgi_server_fd_cb(struct ev_loop *loop, ev_io *w, int revents) { @@ -723,7 +742,7 @@ static void fastcgi_cleanup_connections(fastcgi_server *fsrv) { for (i = 0; i < fsrv->connections->len; ) { fastcgi_connection *fcon = g_ptr_array_index(fsrv->connections, i); - if (fcon->closing) { + if (fcon->closing && -1 == fcon->fd) { fastcgi_connection *t_fcon; guint l = fsrv->connections->len-1; t_fcon = g_ptr_array_index(fsrv->connections, i) = g_ptr_array_index(fsrv->connections, l); From c699a147a12ce45790418fddefc8700b74b46d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sat, 20 Jul 2013 15:16:15 +0200 Subject: [PATCH 6/7] copy PATH environment variable --- fcgi-cgi.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/fcgi-cgi.c b/fcgi-cgi.c index a67b865..c85236d 100644 --- a/fcgi-cgi.c +++ b/fcgi-cgi.c @@ -311,6 +311,32 @@ static void fcgi_cgi_child_error(fcgi_cgi_child *cld) { } } +static void copy_env_var(GPtrArray *env, const char *name) { + guint i, namelen = strlen(name); + const char *value; + + for (i = 0; i < env->len; ) { + const char *entry = g_ptr_array_index(env, i); + if (0 == strncmp(entry, name, namelen) && entry[namelen] == '=') { + g_ptr_array_remove_index_fast(env, i); + g_free((char*) entry); + } else { + ++i; + } + } + + value = getenv(name); + if (NULL != value) { + guint valuelen = strlen(value); + char *entry = g_malloc(namelen + valuelen + 2); + memcpy(entry, name, namelen); + entry[namelen] = '='; + memcpy(entry + namelen + 1, value, valuelen); + entry[namelen+valuelen+1] = 0; + g_ptr_array_add(env, entry); + } +} + static void fcgi_cgi_child_start(fcgi_cgi_child *cld, const gchar *path) { int pipes_to[2] = {-1, -1}, pipes_from[2] = {-1, -1}, pipes_err[2] = {-1, -1}; pid_t pid; @@ -353,6 +379,7 @@ static void fcgi_cgi_child_start(fcgi_cgi_child *cld, const gchar *path) { } } + copy_env_var(enva, "PATH"); g_ptr_array_add(enva, NULL); newenv = (char**) g_ptr_array_free(enva, FALSE); execve(path, args, newenv); From 42b7646e96fefc1bf781aeac949b1d9e4fd09464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sun, 21 Jul 2013 13:30:26 +0200 Subject: [PATCH 7/7] Release as 0.2.2 --- CMakeLists.txt | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18eed2f..a6be0a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ INCLUDE(AddTargetProperties) PROJECT(fcgi-cgi C) -SET(PACKAGE_VERSION 0.2.1) +SET(PACKAGE_VERSION 0.2.2) IF("${CMAKE_BUILD_TYPE}" STREQUAL "") SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE) diff --git a/configure.ac b/configure.ac index 17595a0..57a4036 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) -AC_INIT([fcgi-cgi], [0.2.1], [lighttpd@stbuehler.de]) +AC_INIT([fcgi-cgi], [0.2.2], [lighttpd@stbuehler.de]) AC_CONFIG_SRCDIR([fcgi-cgi.c]) AC_CONFIG_HEADERS([config.h])