home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 25 / CDROM25.iso / Share / linux / apache / contrib / modules / mod_put / mod_put.c next >
Encoding:
C/C++ Source or Header  |  1998-06-06  |  4.6 KB  |  193 lines

  1. /*
  2.  * mod_put: implements the PUT and DELETE methods
  3.  *
  4.  * Lyonel VINCENT <vincent@hpwww.ec-lyon.fr>
  5.  * 
  6.  * usage:
  7.  *    EnablePut    On|Off
  8.  *        default value:    Off
  9.  *        context:    Directory
  10.  *        effect:        enables (or disables) the PUT method for a
  11.  *                whole directory.
  12.  *
  13.  *    EnableDelete    On|Off
  14.  *        default value:    Off
  15.  *        context:    Directory
  16.  *        effect:        enables (or disables) the DELETE method for a
  17.  *                whole directory.
  18.  *    umask        <octal value>
  19.  *        default value:    007
  20.  *        context:    Directory
  21.  *        effect:        sets the umask for a whole directory (see umask(1)).
  22.  */
  23.  
  24. #include "httpd.h"
  25. #include "http_config.h"
  26. #include "http_core.h"
  27. #include "http_log.h"
  28. #include "http_protocol.h"
  29.  
  30. #define DEF_UMASK (S_IROTH | S_IWOTH | S_IXOTH)
  31.  
  32. typedef struct
  33. {
  34.   int put_enabled;
  35.   int delete_enabled;
  36.   int umask;
  37. } put_config_rec;
  38.  
  39. module put_module;
  40.  
  41. #define BLOCKSIZE 2048
  42.  
  43. const char *put_set_putenabled_flag (cmd_parms *cmd,
  44.     put_config_rec *sec, int arg)
  45. {
  46.   sec->put_enabled=arg;
  47.   return NULL;
  48. }
  49.  
  50. const char *put_set_deleteenabled_flag (cmd_parms *cmd,
  51.     put_config_rec *sec, int arg)
  52. {
  53.   sec->delete_enabled=arg;
  54.   return NULL;
  55. }
  56.  
  57. const char *put_set_umask (cmd_parms *cmd,
  58.     put_config_rec *sec, char * arg)
  59. {
  60.   sec->umask=strtol(arg,(char **)NULL,8);
  61.   return NULL;
  62. }
  63.  
  64. command_rec put_cmds[] = {
  65.     { "EnablePut", put_set_putenabled_flag, NULL, OR_AUTHCFG, FLAG, "Limited to 'on' or 'off'" },
  66.     { "EnableDelete", put_set_deleteenabled_flag, NULL, OR_AUTHCFG, FLAG, "Limited to 'on' or 'off'" },
  67.     { "umask", put_set_umask, NULL, OR_AUTHCFG, TAKE1, "numeric umask" },
  68.     { NULL }
  69. };
  70.  
  71. void *create_put_dir_config (pool *p, char *d)
  72. {
  73.   put_config_rec * sec = (put_config_rec *)pcalloc (p, sizeof(put_config_rec));
  74.  
  75.   if (!sec) return NULL; /* no memory... */
  76.  
  77.   sec -> put_enabled    =0;
  78.   sec -> delete_enabled    =0;
  79.   sec -> umask          =DEF_UMASK;
  80.   return sec;
  81. }
  82.  
  83. void make_dirs(pool * p, const char * filename, int umask)
  84. {
  85.   char * sto = pstrdup(p, filename), * slash=sto, * dirname=sto;
  86.  
  87.   while(slash=strchr(slash+1,'/'))
  88.   {
  89.     *slash='\0';
  90.     *dirname='/';
  91.     mkdir(sto,(S_IRWXU | S_IRWXG | S_IRWXO) & ~umask);
  92.     dirname=slash;
  93.   }
  94. }
  95.  
  96. int do_put(request_rec *r)
  97. {
  98.   put_config_rec *sec =
  99.       (put_config_rec *)get_module_config (r->per_dir_config, &put_module);
  100.   FILE * f;
  101.   int result=OK, len=0;
  102.   mode_t old_umask;
  103.   char * buffer;
  104.  
  105.   if(!sec->put_enabled) return FORBIDDEN;
  106.  
  107.   old_umask = umask(sec->umask);
  108.  
  109.   if(r->path_info)    /* a directory did not exist */
  110.   {
  111.     r->filename = pstrcat(r->pool, r->filename, r->path_info, NULL);
  112.     make_dirs(r->pool,r->filename,sec->umask);
  113.   }
  114.  
  115.   f = pfopen(r->pool, r->filename, "w");
  116.   if(f == NULL)
  117.   {
  118.     log_reason("file permissions deny server write access",r->filename,r);
  119.     umask(old_umask);
  120.     return FORBIDDEN;
  121.   }
  122.  
  123.   if((result=setup_client_block(r,REQUEST_CHUNKED_DECHUNK))==OK)
  124.   {
  125.     if(should_client_block(r))
  126.     {
  127.       buffer = palloc(r->pool, BLOCKSIZE);
  128.       while((len=get_client_block(r,buffer,BLOCKSIZE))>0)
  129.     fwrite(buffer,len,1,f);
  130.     }
  131.     send_http_header(r);
  132.     rprintf(r,"<HTML>File %s created.</HTML>\n",escape_html(r->pool, r->uri));
  133.   }
  134.  
  135.   pfclose(r->pool,f);
  136.   umask(old_umask);
  137.   return result;
  138. }
  139.  
  140. int do_delete(request_rec *r)
  141. {
  142.   put_config_rec *sec =
  143.       (put_config_rec *)get_module_config (r->per_dir_config, &put_module);
  144.  
  145.   if(!sec->delete_enabled) return FORBIDDEN;
  146.   if(r->finfo.st_mode == 0) return NOT_FOUND;
  147.   if(unlink(r->filename))
  148.   {
  149.     log_reason("file permissions deny file deletion",r->filename,r);
  150.     return FORBIDDEN;
  151.   }
  152.  
  153.   send_http_header(r);
  154.  
  155.   rprintf(r,"<HTML>File %s deleted.</HTML>\n",escape_html(r->pool, r->uri));
  156.  
  157.   return OK;
  158. }
  159.  
  160. int put_handler(request_rec *r)
  161. {
  162.   if(r->proxyreq) return DECLINED;
  163.   if(r->method_number == M_PUT) return do_put(r);
  164.   else
  165.   if(r->method_number == M_DELETE) return do_delete(r);
  166.   return DECLINED;
  167. }
  168.  
  169. handler_rec put_handlers[] =
  170. {
  171.     { "*/*", put_handler },
  172.     { NULL }
  173. };
  174.  
  175. module put_module = {
  176.    STANDARD_MODULE_STUFF,
  177.    NULL,            /* initializer */
  178.    create_put_dir_config,    /* dir config creater */
  179.    NULL,            /* dir merger --- default is to override */
  180.    NULL,            /* server config */
  181.    NULL,            /* merge server config */
  182.    put_cmds,            /* command table */
  183.    put_handlers,        /* handlers */
  184.    NULL,            /* filename translation */
  185.    NULL,            /* check_user_id */
  186.    NULL,            /* check access rights */
  187.    NULL,            /* check access */
  188.    NULL,            /* type_checker */
  189.    NULL,            /* fixups */
  190.    NULL,            /* logger */
  191.    NULL                /* header parser */
  192. };
  193.