Changeset 506

Show
Ignore:
Timestamp:
08/08/2005 10:00:24 AM (3 years ago)
Author:
moo
Message:

include_shell option support in configuration

Location:
trunk
Files:
2 added
11 modified

Legend:

Unmodified
Added
Removed
  • trunk/doc/configuration.txt

    r404 r506  
    3636  <array>  : "(" [ <string> "=>" ] <value> [, [ <string> "=>" ] <value> ]* ")" 
    3737  INCLUDE  : "include" VALUE 
     38  INCLUDE_SHELL : "include_shell" STRING_VALUE 
    3839   
    3940Example 
     
    5758  # include, relative to dirname of main config file 
    5859  include "mime.types.conf" 
     60 
     61  # read configuration from output of a command 
     62  include_shell "/usr/local/bin/confmimetype /etc/mime.types" 
    5963 
    6064 
  • trunk/doc/lighttpd.conf

    r373 r506  
    299299## same as above if you run: "lighttpd -f /etc/lighttpd/lighttpd.conf" 
    300300#include "lighttpd-inc.conf" 
     301 
     302#### include_shell 
     303#include_shell "echo var.a=1" 
     304## the above is same as: 
     305#var.a=1 
  • trunk/src/.cvsignore

    r323 r506  
    1010.libs 
    1111array 
     12proc_open 
     13regex 
    1214mod_ssi_exprparser.c 
    1315mod_ssi_exprparser.h 
  • trunk/src/Makefile.am

    r298 r506  
    1 noinst_PROGRAMS=array lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license 
     1noinst_PROGRAMS=array proc_open lemon # simple-fcgi #graphic evalo bench ajp ssl error_test adserver gen-license 
    22sbin_PROGRAMS=lighttpd  
    33bin_PROGRAMS=spawn-fcgi 
     
    4343      network_freebsd_sendfile.c network_writev.c \ 
    4444      network_solaris_sendfilev.c network_openssl.c \ 
    45       network_send.c network-glue.c fdevent-glue.c 
     45      network_send.c network-glue.c fdevent-glue.c \ 
     46      proc_open.c 
    4647 
    4748src = server.c response.c connections.c configfile.c configparser.c \ 
     
    226227      sys-mmap.h sys-socket.h file_descr.h \ 
    227228      file_cache_funcs.h file_descr_funcs.h \ 
    228       chunk_funcs.h 
     229      chunk_funcs.h proc_open.h 
    229230       
    230231 
     
    238239array_CPPFLAGS= -DDEBUG_ARRAY 
    239240 
     241proc_open_SOURCES = proc_open.c buffer.c 
     242proc_open_CPPFLAGS= -DDEBUG_PROC_OPEN 
     243 
    240244#gen_license_SOURCES = license.c md5.c buffer.c gen_license.c 
    241245 
  • trunk/src/configfile.c

    r340 r506  
    2020#include "configparser.h" 
    2121#include "configfile.h" 
     22#include "proc_open.h" 
    2223 
    2324 
     
    292293} 
    293294#undef PATCH 
     295 
    294296typedef struct { 
    295297        int foo; 
    296298        int bar; 
    297299         
    298         buffer *file; 
    299         stream s; 
     300        const buffer *source; 
    300301        const char *input; 
    301302        size_t offset; 
     
    309310        int in_cond; 
    310311} tokenizer_t; 
    311  
    312 static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) { 
    313         if (buffer_is_empty(basedir) && 
    314                         (fn[0] == '/' || fn[0] == '\\') && 
    315                         (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) { 
    316                 t->file = buffer_init_string(fn); 
    317         } 
    318         else { 
    319                 t->file = buffer_init_buffer(basedir); 
    320                 buffer_append_string(t->file, fn); 
    321         } 
    322  
    323         if (0 != stream_open(&(t->s), t->file)) { 
    324                 log_error_write(srv, __FILE__, __LINE__, "sbss",  
    325                                 "opening configfile ", t->file, "failed:", strerror(errno)); 
    326                 buffer_free(t->file); 
    327                 return -1; 
    328         } 
    329  
    330         t->input = t->s.start; 
    331         t->offset = 0; 
    332         t->size = t->s.size; 
    333         t->line = 1; 
    334         t->line_pos = 1; 
    335          
    336         t->in_key = 1; 
    337         t->in_brace = 0; 
    338         t->in_cond = 0; 
    339         return 0; 
    340 } 
    341  
    342 static int tokenizer_close(server *srv, tokenizer_t *t) { 
    343         UNUSED(srv); 
    344  
    345         buffer_free(t->file); 
    346         return stream_close(&(t->s)); 
    347 } 
    348312 
    349313static int config_skip_newline(tokenizer_t *t) { 
     
    387351                                } else { 
    388352                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
    389                                                         "file:", t->file, 
     353                                                        "source:", t->source, 
    390354                                                        "line:", t->line, "pos:", t->line_pos,  
    391355                                                        "use => for assignments in arrays"); 
     
    407371                                } else { 
    408372                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
    409                                                         "file:", t->file, 
     373                                                        "source:", t->source, 
    410374                                                        "line:", t->line, "pos:", t->line_pos,  
    411375                                                        "only =~ and == are allow in the condition"); 
     
    423387                        } else { 
    424388                                log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
    425                                                 "file:", t->file, 
     389                                                "source:", t->source, 
    426390                                                "line:", t->line, "pos:", t->line_pos,  
    427391                                                "unexpected equal-sign: ="); 
     
    446410                                } else { 
    447411                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
    448                                                         "file:", t->file, 
     412                                                        "source:", t->source, 
    449413                                                        "line:", t->line, "pos:", t->line_pos,  
    450414                                                        "only !~ and != are allow in the condition"); 
     
    455419                        } else { 
    456420                                log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
    457                                                 "file:", t->file, 
     421                                                "source:", t->source, 
    458422                                                "line:", t->line, "pos:", t->line_pos,  
    459423                                                "unexpected exclamation-marks: !"); 
     
    545509                                 
    546510                                log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
    547                                                 "file:", t->file, 
     511                                                "source:", t->source, 
    548512                                                "line:", t->line, "pos:", t->line_pos,  
    549513                                                "missing closing quote"); 
     
    588552                                buffer_copy_string(token, "+="); 
    589553                                tid = TK_APPEND; 
    590                         } 
    591                         else { 
     554                        } else { 
    592555                                t->offset++; 
    593556                                tid = TK_PLUS; 
     
    650613                                        /* ERROR */ 
    651614                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
    652                                                         "file:", t->file, 
     615                                                        "source:", t->source, 
    653616                                                        "line:", t->line, "pos:", t->line_pos,  
    654617                                                        "invalid character in condition"); 
     
    670633                                        /* ERROR */ 
    671634                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
    672                                                         "file:", t->file, 
     635                                                        "source:", t->source, 
    673636                                                        "line:", t->line, "pos:", t->line_pos,  
    674637                                                        "unexpected EOF"); 
     
    676639                                        return -1; 
    677640                                } 
    678                         } 
    679                         else { 
     641                        } else { 
    680642                                /* the key might consist of [-.0-9a-z] */ 
    681643                                for (i = 0; t->input[t->offset + i] &&  
     
    690652                                        if (strcmp(token->ptr, "include") == 0) { 
    691653                                                tid = TK_INCLUDE; 
    692                                         } 
    693                                         else if (strcmp(token->ptr, "else") == 0) { 
     654                                        } else if (strcmp(token->ptr, "include_shell") == 0) { 
     655                                                tid = TK_INCLUDE_SHELL; 
     656                                        } else if (strcmp(token->ptr, "else") == 0) { 
    694657                                                tid = TK_ELSE; 
    695                                         } 
    696                                         else { 
     658                                        } else { 
    697659                                                tid = TK_LKEY; 
    698660                                        } 
     
    703665                                        /* ERROR */ 
    704666                                        log_error_write(srv, __FILE__, __LINE__, "sbsdsds",  
    705                                                         "file:", t->file, 
     667                                                        "source:", t->source, 
    706668                                                        "line:", t->line, "pos:", t->line_pos,  
    707669                                                        "invalid character in variable name"); 
     
    717679#if 0 
    718680                log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd",  
    719                                 "file:", t->file, 
     681                                "source:", t->source, 
    720682                                "line:", t->line, "pos:", t->line_pos, 
    721683                                token, token->used - 1, tid); 
     
    731693} 
    732694 
    733 int config_parse_file(server *srv, config_t *context, const char *fn) { 
    734         tokenizer_t t; 
     695static int config_parse(server *srv, config_t *context, tokenizer_t *t) { 
    735696        void *pParser; 
    736697        int token_id; 
     
    738699        int ret; 
    739700 
    740         if (tokenizer_open(srv, &t, context->basedir, fn) == -1) { 
    741                 return -1; 
    742         } 
    743          
    744701        pParser = configparserAlloc( malloc ); 
    745702        lasttoken = buffer_init(); 
    746703        token = buffer_init(); 
    747         while((1 == (ret = config_tokenizer(srv, &t, &token_id, token))) && context->ok) { 
     704        while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) { 
    748705                buffer_copy_string_buffer(lasttoken, token); 
    749706                configparser(pParser, token_id, token, context); 
     
    765722                log_error_write(srv, __FILE__, __LINE__, "sb",  
    766723                                "configfile parser failed:", lasttoken); 
    767         } 
    768         else if (context->ok == 0) { 
     724        } else if (context->ok == 0) { 
    769725                log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb",  
    770                                 "file:", t.file, 
    771                                 "line:", t.line, "pos:", t.line_pos,  
     726                                "source:", t->source, 
     727                                "line:", t->line, "pos:", t->line_pos,  
    772728                                "parser failed somehow near here:", lasttoken); 
    773729                ret = -1; 
     
    775731        buffer_free(lasttoken); 
    776732 
    777         tokenizer_close(srv, &t); 
    778733        return ret == -1 ? -1 : 0; 
     734} 
     735 
     736static int tokenizer_init(tokenizer_t *t, const buffer *source, const char *input, size_t size) { 
     737 
     738        t->source = source; 
     739        t->input = input; 
     740        t->size = size; 
     741        t->offset = 0; 
     742        t->line = 1; 
     743        t->line_pos = 1; 
     744         
     745        t->in_key = 1; 
     746        t->in_brace = 0; 
     747        t->in_cond = 0; 
     748        return 0; 
     749} 
     750 
     751int config_parse_file(server *srv, config_t *context, const char *fn) { 
     752        tokenizer_t t; 
     753        stream s; 
     754        int ret; 
     755        buffer *filename; 
     756 
     757        if (buffer_is_empty(context->basedir) && 
     758                        (fn[0] == '/' || fn[0] == '\\') && 
     759                        (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) { 
     760                filename = buffer_init_string(fn); 
     761        } else { 
     762                filename = buffer_init_buffer(context->basedir); 
     763                buffer_append_string(filename, fn); 
     764        } 
     765 
     766        if (0 != stream_open(&s, filename)) { 
     767                log_error_write(srv, __FILE__, __LINE__, "sbss",  
     768                                "opening configfile ", filename, "failed:", strerror(errno)); 
     769                ret = -1; 
     770        } else { 
     771                tokenizer_init(&t, filename, s.start, s.size); 
     772                ret = config_parse(srv, context, &t); 
     773        } 
     774 
     775        stream_close(&s); 
     776        buffer_free(filename); 
     777        return ret; 
     778} 
     779 
     780int config_parse_cmd(server *srv, config_t *context, const char *cmd) { 
     781        proc_handler_t proc; 
     782        tokenizer_t t; 
     783        int ret; 
     784        buffer *source; 
     785        buffer *out; 
     786        char oldpwd[PATH_MAX]; 
     787 
     788        if (NULL == getcwd(oldpwd, sizeof(oldpwd))) { 
     789                log_error_write(srv, __FILE__, __LINE__, "s",  
     790                                "cannot get cwd", strerror(errno)); 
     791                return -1; 
     792        } 
     793 
     794        source = buffer_init_string(cmd); 
     795        out = buffer_init(); 
     796 
     797        if (!buffer_is_empty(context->basedir)) { 
     798                chdir(context->basedir->ptr); 
     799        } 
     800 
     801        if (0 != proc_open_buffer(&proc, cmd, NULL, out, NULL)) { 
     802                log_error_write(srv, __FILE__, __LINE__, "sbss",  
     803                                "opening", source, "failed:", strerror(errno)); 
     804                ret = -1; 
     805        } else { 
     806                tokenizer_init(&t, source, out->ptr, out->used); 
     807                ret = config_parse(srv, context, &t); 
     808        } 
     809 
     810        buffer_free(source); 
     811        buffer_free(out); 
     812        chdir(oldpwd); 
     813        return ret; 
    779814} 
    780815 
  • trunk/src/configfile.h

    r307 r506  
    1919void configparser(void *yyp, int yymajor, buffer *yyminor, config_t *ctx); 
    2020int config_parse_file(server *srv, config_t *context, const char *fn); 
     21int config_parse_cmd(server *srv, config_t *context, const char *cmd); 
    2122 
    2223#endif 
  • trunk/src/configparser.y

    r420 r506  
    132132metaline ::= condlines(A) EOL. { A = NULL; } 
    133133metaline ::= include. 
     134metaline ::= include_shell. 
    134135metaline ::= EOL. 
    135136 
     
    142143%type       array                  {array *} 
    143144%type       key                    {buffer *} 
     145%type       stringop               {buffer *} 
    144146 
    145147%type       cond                   {config_cond_t } 
     
    151153%destructor array                  { array_free($$); } 
    152154%destructor key                    { buffer_free($$); } 
     155%destructor stringop               { buffer_free($$); } 
    153156 
    154157%token_type                        {buffer *} 
     
    346349  default: 
    347350    assert(0); 
    348     break; 
     351    return; 
    349352  } 
    350353 
     
    469472} 
    470473 
    471 include ::= INCLUDE expression(A). { 
     474stringop(A) ::= expression(B). { 
     475  A = NULL; 
    472476  if (ctx->ok) { 
    473     if (A->type != TYPE_STRING) { 
    474       fprintf(stderr, "file must be string"); 
     477    if (B->type != TYPE_STRING) { 
     478      fprintf(stderr, "operand must be string"); 
    475479      ctx->ok = 0; 
    476480    } else { 
    477       buffer *file = ((data_string*)A)->value; 
    478       if (0 != config_parse_file(ctx->srv, ctx, file->ptr)) { 
    479         ctx->ok = 0; 
    480       } 
    481     } 
    482   } 
    483   A->free(A); 
    484   A = NULL; 
    485 } 
     481      A = buffer_init_buffer(((data_string*)B)->value); 
     482    } 
     483  } 
     484  B->free(B); 
     485  B = NULL; 
     486} 
     487 
     488include ::= INCLUDE stringop(A). { 
     489  if (ctx->ok) { 
     490    if (0 != config_parse_file(ctx->srv, ctx, A->ptr)) { 
     491      ctx->ok = 0; 
     492    } 
     493    buffer_free(A); 
     494    A = NULL; 
     495  } 
     496} 
     497 
     498include_shell ::= INCLUDE_SHELL stringop(A). { 
     499  if (ctx->ok) { 
     500    if (0 != config_parse_cmd(ctx->srv, ctx, A->ptr)) { 
     501      ctx->ok = 0; 
     502    } 
     503    buffer_free(A); 
     504    A = NULL; 
     505  } 
     506} 
  • trunk/src/plugin.c

    r284 r506  
    6262        if (p->name) buffer_free(p->name); 
    6363#ifdef HAVE_VALGRIND_VALGRIND_H 
    64         if (RUNNING_ON_VALGRIND) use_dlclose = 0; 
     64        /*if (RUNNING_ON_VALGRIND) use_dlclose = 0;*/ 
    6565#endif 
    6666 
  • trunk/src/plugin.h

    r339 r506  
    8888int config_patch_connection(server *srv, connection *con, comp_key_t comp); 
    8989int config_check_cond(server *srv, connection *con, data_config *dc); 
     90int config_append_cond_match_buffer(connection *con, data_config *dc, buffer *buf, int n); 
    9091 
    9192#endif 
  • trunk/tests/core-var-include.t

    r341 r506  
    33use strict; 
    44use IO::Socket; 
    5 use Test::More tests => 15; 
     5use Test::More tests => 16; 
    66 
    77my $basedir = (defined $ENV{'top_builddir'} ? $ENV{'top_builddir'} : '..'); 
     
    194194        @request  = ( "GET /index.html HTTP/1.0\r\nHost: www.example.org\r\n" ); 
    195195        @response = ( { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 301, 'Location' => "/redirect" } ); 
    196     skip "redirect is not working as expected", 12 if handle_http != 0;  
     196    skip "redirect is not working as expected", 13 if handle_http != 0;  
    197197        my $myvar = "good"; 
    198198        my $server_name = "test.example.org"; 
     
    213213                "array_append"   => "/good_array_append", 
    214214                "string_append"  => "/good_" . $mystr, 
    215                 "number_append"  => "/good_" . "2" 
     215                "number_append"  => "/good_" . "2", 
     216 
     217                "include_shell"  => "/good_include_shell_" . "456" 
    216218        }; 
    217219        foreach my $test (keys %{ $tests }) { 
  • trunk/tests/var-include-sub.conf

    r341 r506  
    2626                        "^/number_append$" => "/good_" + one, 
    2727                        ) 
     28 
     29        cmd = "echo cmd_ok=456" 
     30        include_shell cmd 
     31        url.redirect += ( 
     32                        "^/include_shell$" => "/good_include_shell_" + cmd_ok, 
     33                        ) 
    2834}