home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 25 / CDROM25.iso / Share / linux / apache / contrib / modules / probably_obsolete / mod_cern_meta.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-11  |  10.2 KB  |  333 lines

  1. /* ====================================================================
  2.  * Copyright (c) 1995 The Apache Group.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer. 
  10.  *
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in
  13.  *    the documentation and/or other materials provided with the
  14.  *    distribution.
  15.  *
  16.  * 3. All advertising materials mentioning features or use of this
  17.  *    software must display the following acknowledgment:
  18.  *    "This product includes software developed by the Apache Group
  19.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  20.  *
  21.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  22.  *    endorse or promote products derived from this software without
  23.  *    prior written permission.
  24.  *
  25.  * 5. Redistributions of any form whatsoever must retain the following
  26.  *    acknowledgment:
  27.  *    "This product includes software developed by the Apache Group
  28.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  29.  *
  30.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  31.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  33.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  34.  * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  41.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  42.  * ====================================================================
  43.  *
  44.  * This software consists of voluntary contributions made by many
  45.  * individuals on behalf of the Apache Group and was originally based
  46.  * on public domain software written at the National Center for
  47.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  48.  * For more information on the Apache Group and the Apache HTTP server
  49.  * project, please see <http://www.apache.org/>.
  50.  *
  51.  */
  52.  
  53. /*
  54.  * mod_cern_meta.c
  55.  * version 0.0.7
  56.  * status beta
  57.  * 
  58.  * Andrew Wilson <Andrew.Wilson@cm.cf.ac.uk> 25.Jan.96
  59.  *
  60.  * Emulate the CERN HTTPD Meta file semantics.  Meta files are HTTP
  61.  * headers that can be output in addition to the normal range of
  62.  * headers for each file accessed.  They appear rather like the Apache
  63.  * .asis files, and are able to provide a crude way of influencing
  64.  * the Expires: header, as well as providing other curiosities.
  65.  * There are many ways to manage meta information, this one was
  66.  * chosen because there is already a large number of CERN users
  67.  * who can exploit this module.  It should be noted that there are probably
  68.  * more sensitive ways of managing the Expires: header specifically.
  69.  *
  70.  * The module obeys the following directives, which can only appear 
  71.  * in the server's .conf files and not in any .htaccess file.
  72.  *
  73.  *  MetaDir <directory name>
  74.  *      
  75.  *    specifies the name of the directory in which Apache can find
  76.  *    meta information files.  The directory is usually a 'hidden'
  77.  *    subdirectory of the directory that contains the file being
  78.  *    accessed.  eg:
  79.  *
  80.  *        # .meta files are in the *same* directory as the 
  81.  *        # file being accessed
  82.  *        MetaDir .
  83.  *
  84.  *    the default is to look in a '.web' subdirectory. This is the
  85.  *    same as for CERN 3.+ webservers and behaviour is the same as 
  86.  *    for the directive:
  87.  *
  88.  *        MetaDir .web
  89.  *
  90.  *  MetaSuffix <meta file suffix>
  91.  *
  92.  *    specifies the file name suffix for the file containing the
  93.  *    meta information.  eg:
  94.  *
  95.  *       # our meta files are suffixed with '.cern_meta'
  96.  *       MetaSuffix .cern_meta
  97.  *
  98.  *    the default is to look for files with the suffix '.meta'.  This
  99.  *    behaviour is the same as for the directive:
  100.  *
  101.  *       MetaSuffix .meta
  102.  *
  103.  * When accessing the file
  104.  *
  105.  *   DOCUMENT_ROOT/somedir/index.html
  106.  *
  107.  * this module will look for the file
  108.  *
  109.  *   DOCUMENT_ROOT/somedir/.web/index.html.meta
  110.  *
  111.  * and will use its contents to generate additional MIME header 
  112.  * information.
  113.  *
  114.  * For more information on the CERN Meta file semantics see:
  115.  *
  116.  *   http://www.w3.org/hypertext/WWW/Daemon/User/Config/General.html#MetaDir
  117.  *
  118.  * Change-log:
  119.  * 29.Jan.96 pfopen/pfclose instead of fopen/fclose
  120.  *           DECLINE when real file not found, we may be checking each
  121.  *           of the index.html/index.shtml/index.htm variants and don't
  122.  *           need to report missing ones as spurious errors. 
  123.  * 31.Jan.96 log_error reports about a malformed .meta file, rather
  124.  *           than a script error.
  125.  * 21.Feb.96 This version (0.0.7) reverses assumptions made in 0.0.6
  126.  *           about star/star handlers.  Reverting to 0.0.5 behaviour.
  127.  *
  128.  */
  129.  
  130. #include "httpd.h"
  131. #include "http_config.h"
  132. #include <sys/types.h>
  133. #include <sys/stat.h>
  134. #include "util_script.h"
  135. #include "http_log.h"
  136.  
  137. #define DEFAULT_METADIR        ".web"
  138. #define DEFAULT_METASUFFIX    ".meta"
  139.  
  140. module cern_meta_module;
  141.  
  142. typedef struct {
  143.     char *metadir;
  144.     char *metasuffix;
  145. } cern_meta_config;
  146.  
  147. void *create_cern_meta_config (pool *p, server_rec *dummy)
  148. {
  149.     cern_meta_config *new =
  150.       (cern_meta_config *) palloc (p, sizeof(cern_meta_config)); 
  151.  
  152.     new->metadir = DEFAULT_METADIR;
  153.     new->metasuffix = DEFAULT_METASUFFIX;
  154.     
  155.     return new;
  156. }   
  157.  
  158. char *set_metadir (cmd_parms *parms, void *dummy, char *arg)
  159. {       
  160.     cern_meta_config *cmc ;
  161.  
  162.     cmc = get_module_config (parms->server->module_config,
  163.                            &cern_meta_module); 
  164.     cmc->metadir = arg;
  165.     return NULL;
  166. }
  167.  
  168. char *set_metasuffix (cmd_parms *parms, void *dummy, char *arg)
  169. {       
  170.     cern_meta_config *cmc ;
  171.  
  172.     cmc = get_module_config (parms->server->module_config,
  173.                            &cern_meta_module); 
  174.     cmc->metasuffix = arg;
  175.     return NULL;
  176. }
  177.  
  178. command_rec cern_meta_cmds[] = {
  179. { "MetaDir", set_metadir, NULL, RSRC_CONF, TAKE1,
  180.     "the name of the directory containing meta files"},
  181. { "MetaSuffix", set_metasuffix, NULL, RSRC_CONF, TAKE1,
  182.     "the filename suffix for meta files"},
  183. { NULL }
  184. };  
  185.  
  186. int scan_meta_file(request_rec *r, FILE *f)
  187. {
  188.     char w[MAX_STRING_LEN];
  189.     char *l;
  190.     int p;
  191.  
  192.     while( fgets(w, MAX_STRING_LEN-1, f) != NULL ) {
  193.  
  194.     /* Delete terminal (CR?)LF */
  195.     
  196.     p = strlen(w);
  197.     if (p > 0 && w[p-1] == '\n')
  198.     {
  199.         if (p > 1 && w[p-2] == '\015') w[p-2] = '\0';
  200.         else w[p-1] = '\0';
  201.     }
  202.  
  203.         if(w[0] == '\0') {
  204.         return OK;
  205.     }
  206.                                    
  207.     /* if we see a bogus header don't ignore it. Shout and scream */
  208.     
  209.         if(!(l = strchr(w,':'))) {
  210.         log_reason ("malformed header in meta file", r->filename, r);
  211.         return SERVER_ERROR;
  212.         }
  213.  
  214.         *l++ = '\0';
  215.     while (*l && isspace (*l)) ++l;
  216.     
  217.         if(!strcasecmp(w,"Content-type")) {
  218.  
  219.         /* Nuke trailing whitespace */
  220.         
  221.         char *endp = l + strlen(l) - 1;
  222.         while (endp > l && isspace(*endp)) *endp-- = '\0';
  223.         
  224.         r->content_type = pstrdup (r->pool, l);
  225.     }
  226.         else if(!strcasecmp(w,"Status")) {
  227.             sscanf(l, "%d", &r->status);
  228.             r->status_line = pstrdup(r->pool, l);
  229.         }
  230.         else {
  231.         table_set (r->headers_out, w, l);
  232.         }
  233.     }
  234.     return OK;
  235. }
  236.  
  237. int add_cern_meta_data(request_rec *r)
  238. {
  239.     char *metafilename;
  240.     char *last_slash;
  241.     char *real_file;
  242.     char *scrap_book;
  243.     struct stat meta_stat;
  244.     FILE *f;   
  245.     cern_meta_config *cmc ;
  246.     int rv;
  247.  
  248.     cmc = get_module_config (r->server->module_config,
  249.                            &cern_meta_module); 
  250.  
  251.     /* if ./.web/$1.meta exists then output 'asis' */
  252.  
  253.     if (r->finfo.st_mode == 0) {
  254.     return DECLINED;
  255.     };
  256.  
  257.     /* does uri end in a trailing slash? */
  258.     if ( r->uri[strlen(r->uri) - 1] == '/' ) {
  259.     return DECLINED;
  260.     };
  261.  
  262.     /* what directory is this file in? */
  263.     scrap_book = pstrdup( r->pool, r->filename );
  264.     /* skip leading slash, recovered in later processing */
  265.     scrap_book++;
  266.     last_slash = rindex( scrap_book, '/' );
  267.     if ( last_slash != NULL ) {
  268.     /* skip over last slash */
  269.     real_file = last_slash;
  270.     real_file++;
  271.     *last_slash = '\0';
  272.     } else {
  273.     /* no last slash, buh?! */
  274.         log_reason("internal error in mod_cern_meta", r->filename, r);
  275.     /* should really barf, but hey, let's be friends... */
  276.     return DECLINED;
  277.     };
  278.  
  279.     metafilename = pstrcat(r->pool, "/", scrap_book, "/", cmc->metadir, "/", real_file, cmc->metasuffix, NULL);
  280.  
  281.     /*
  282.      * stat can legitimately fail for a bewildering number of reasons,
  283.      * only one of which implies the file isn't there.  A hardened
  284.      * version of this module should test for all conditions, but later...
  285.      */
  286.     if (stat(metafilename, &meta_stat) == -1) {
  287.     /* stat failed, possibly file missing */
  288.     return DECLINED;
  289.     };
  290.  
  291.     /*
  292.      * this check is to be found in other Jan/96 Apache code, I've
  293.      * not been able to find any corroboration in the man pages but
  294.      * I've been wrong before so I'll put it in anyway.  Never
  295.      * admit to being clueless...
  296.      */
  297.     if ( meta_stat.st_mode == 0 ) {
  298.     /* stat failed, definately file missing */
  299.     return DECLINED;
  300.     };
  301.  
  302.     f = pfopen (r->pool, metafilename, "r");
  303.     
  304.     if (f == NULL) {
  305.         log_reason("meta file permissions deny server access", metafilename, r);
  306.         return FORBIDDEN;
  307.     };
  308.  
  309.     /* read the headers in */
  310.     rv = scan_meta_file(r, f);
  311.     pfclose( r->pool, f );
  312.  
  313.     return rv;
  314. }
  315.  
  316. module cern_meta_module = {
  317.    STANDARD_MODULE_STUFF,
  318.    NULL,            /* initializer */
  319.    NULL,            /* dir config creater */
  320.    NULL,            /* dir merger --- default is to override */
  321.    create_cern_meta_config,    /* server config */
  322.    NULL,            /* merge server configs */
  323.    cern_meta_cmds,        /* command table */
  324.    NULL,            /* handlers */
  325.    NULL,            /* filename translation */
  326.    NULL,            /* check_user_id */
  327.    NULL,            /* check auth */
  328.    NULL,            /* check access */
  329.    NULL,            /* type_checker */
  330.    add_cern_meta_data,        /* fixups */
  331.    NULL,            /* logger */
  332. };
  333.