Diff for /parser3/src/classes/file.C between versions 1.22 and 1.38

version 1.22, 2001/04/09 13:21:08 version 1.38, 2001/06/28 07:44:17
Line 7 Line 7
   
         $Id$          $Id$
 */  */
   static const char *RCSId="$Id$"; 
   
   #include "classes.h"
 #include "pa_request.h"  #include "pa_request.h"
 #include "_file.h"  
 #include "pa_vfile.h"  #include "pa_vfile.h"
 #include "pa_table.h"  #include "pa_table.h"
 #include "pa_vint.h"  #include "pa_vint.h"
   #include "pa_exec.h"
   
 // consts  // consts
   
 const int FIND_MONKEY_MAX_HOPS=10;  // defines
   
   #define FILE_CLASS_NAME "file"
   
   // class
   
   class MFile : public Methoded {
   public: // VStateless_class
           
           Value *create_new_value(Pool& pool) { return new(pool) VFile(pool); }
   
 // global var  public: // Methoded
           bool used_directly() { return true; }
   
 VStateless_class *file_class;  public:
           MFile(Pool& pool);
   
   };
   
   // consts
   
   const int FIND_MONKEY_MAX_HOPS=10;
   
 // methods  // methods
   
 static void _save(Request& r, const String& method_name, Array *params) {  static void _save(Request& r, const String&, MethodParams *params) {
         Pool& pool=r.pool();          Value& vfile_name=params->get_no_junction(0, "file name must not be code");
         Value& vfile_name=*static_cast<Value *>(params->get(0));  
         // forcing  
         // ^save[this body type]  
         r.fail_if_junction_(true, vfile_name,   
                 method_name, "file name must not be code");  
   
         // save          // save
         static_cast<VFile *>(r.self)->save(r.absolute(vfile_name.as_string()));          static_cast<VFile *>(r.self)->save(r.absolute(vfile_name.as_string()));
 }  }
   
 static void _delete(Request& r, const String& method_name, Array *params) {  static void _delete(Request& r, const String&, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
         Value& vfile_name=*static_cast<Value *>(params->get(0));          Value& vfile_name=params->get_no_junction(0, "file name must not be code");
         // forcing  
         // ^delete[this body type]  
         r.fail_if_junction_(true, vfile_name,   
                 method_name, "file name must not be code");  
   
         // unlink          // unlink
         file_delete(pool, r.absolute(vfile_name.as_string()));          file_delete(pool, r.absolute(vfile_name.as_string()));
 }  }
   
 static void _find(Request& r, const String& method_name, Array *params) {  static void _find(Request& r, const String& method_name, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
         Value& vfile_name=*static_cast<Value *>(params->get(0));          Value& vfile_name=params->get_no_junction(0, "file name must not be code");
         // forcing  
         // ^delete[this body type]  
         r.fail_if_junction_(true, vfile_name,   
                 method_name, "file name must not be code");  
   
         const String &lfile_name=vfile_name.as_string();          const String &lfile_name=vfile_name.as_string();
   
Line 78  static void _find(Request& r, const Stri Line 84  static void _find(Request& r, const Stri
   
         // not found          // not found
         if(params->size()==2) {          if(params->size()==2) {
                 // forcing ..{this body type}                  Value& not_found_code=params->get_junction(1, "not-found param must be code");
                 Value& not_found_code=*static_cast<Value *>(params->get(1));  
                 r.fail_if_junction_(false, not_found_code,   
                         method_name, "not-found param must be code");  
                 r.write_pass_lang(r.process(not_found_code));                  r.write_pass_lang(r.process(not_found_code));
         }          }
 }  }
   
 static void _load(Request& r, const String& method_name, Array *params) {  static void _load(Request& r, const String& method_name, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
         Value& vfile_name=*static_cast<Value *>(params->get(0));          Value& vfile_name=params->get_no_junction(0, "file name must not be code");
   
         // forcing ^load[this body type]  
         r.fail_if_junction_(true, vfile_name,   
                 method_name, "file name must not be code");  
   
         const String& lfile_name=vfile_name.as_string();          const String& lfile_name=vfile_name.as_string();
   
Line 100  static void _load(Request& r, const Stri Line 99  static void _load(Request& r, const Stri
         file_read(pool, r.absolute(lfile_name), data, size, false/*binary*/);          file_read(pool, r.absolute(lfile_name), data, size, false/*binary*/);
   
         char *user_file_name=params->size()==1?lfile_name.cstr(String::UL_FILE_NAME)          char *user_file_name=params->size()==1?lfile_name.cstr(String::UL_FILE_NAME)
                 :static_cast<Value *>(params->get(1))->as_string().cstr();                  :params->get(1).as_string().cstr();
                   
         static_cast<VFile *>(r.self)->set(true/*tainted*/, data, size,           static_cast<VFile *>(r.self)->set(true/*tainted*/, data, size, 
                 user_file_name, &r.mime_type_of(user_file_name));                  user_file_name, &r.mime_type_of(user_file_name));
 }  }
   
   static void _stat(Request& r, const String& method_name, MethodParams *params) {
           Pool& pool=r.pool();
           Value& vfile_name=params->get_no_junction(0, "file name must not be code");
   
           const String& lfile_name=vfile_name.as_string();
   
           size_t size=file_size(r.absolute(lfile_name));
           
           static_cast<VFile *>(r.self)->set(true/*tainted*/, 0/*no bytes*/, size);
   }
   
 static void append_env_pair(const Hash::Key& key, Hash::Val *value, void *info) {  static void append_env_pair(const Hash::Key& key, Hash::Val *value, void *info) {
         Hash& hash=*static_cast<Hash *>(info);          Hash& hash=*static_cast<Hash *>(info);
         hash.put(key, &static_cast<Value *>(value)->as_string());          hash.put(key, &static_cast<Value *>(value)->as_string());
 }  }
 /// ^exec[file-name]  
 /// ^exec[file-name;env hash]  static void pass_cgi_header_attribute(Array::Item *value, void *info) {
 /// ^exec[file-name;env hash;cmd;line;arg;s]          String& string=*static_cast<String *>(value);
 /// @test header to $fields. waits for header '\' tricks          Hash& hash=*static_cast<Hash *>(info);
 static void _cgi(Request& r, const String& method_name, Array *params) {          int colon_pos=string.pos(":", 1);
           if(colon_pos>0)
                   hash.put(string.mid(0, colon_pos), 
                   new(string.pool()) VString(string.mid(colon_pos+1, string.size())));
   }
   /// @todo fix `` in perl - they produced flipping consoles and no output to perl
   static void _cgi(Request& r, const String& method_name, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
   
         Value& vfile_name=*static_cast<Value *>(params->get(0));          Value& vfile_name=params->get_no_junction(0, "file name must not be code");
         // forcing [this param type]  
         r.fail_if_junction_(true, vfile_name,           const String& script_name=r.absolute(vfile_name.as_string());
                 method_name, "file name must not be code");  
           Hash env(pool);
           #define PASS(key) \
                   String key(pool); \
                   if(const char *value=SAPI::get_env(pool, #key)) { \
                           key.APPEND_CONST(value); \
                           env.put(String(pool, #key), &key); \
                   }
           #define INFO(key, value) \
                   String value(pool); \
                   if(r.info.value) { \
                           value.APPEND_CONST(r.info.value); \
                           env.put(String(pool, key), &value); \
                   }
   
           // const
           String gateway_interface(pool, "CGI/1.1");
           env.put(String(pool, "GATEWAY_INTERFACE"), &gateway_interface);
           // from Request.info
           INFO("DOCUMENT_ROOT", document_root);
           INFO("PATH_TRANSLATED", path_translated);
           INFO("SERVER_PROTOCOL", method);
           INFO("QUERY_STRING", query_string);
           INFO("REQUEST_URI", uri);
           INFO("CONTENT_TYPE", content_type);
           char content_length_cstr[MAX_NUMBER];  
           snprintf(content_length_cstr, MAX_NUMBER, "%u", r.info.content_length);
           String content_length(pool, content_length_cstr);
           env.put(String(pool, "CONTENT_LENGTH"), &content_length);
           INFO("HTTP_COOKIE", cookie);
           INFO("HTTP_USER_AGENT", user_agent);
           // passing some SAPI:get_env-s
           PASS(SERVER_NAME);
           PASS(SERVER_PORT);
           PASS(HTTP_REFERER);
           PASS(REMOTE_ADDR);
           PASS(REMOTE_HOST);
           PASS(REMOTE_USER);
           // SCRIPT_NAME
           env.put(String(pool, "SCRIPT_NAME"), &script_name);
   #ifdef WIN32
           // WIN32 shell
           PASS(COMSPEC);
   #endif
   
         Hash *env=0;   
         if(params->size()>1) {          if(params->size()>1) {
                 Value& venv=*static_cast<Value *>(params->get(1));                  Value& venv=params->get_no_junction(1, "env must not be code");
                 // forcing [this param type]                  if(Hash *user_env=venv.get_hash())
                 r.fail_if_junction_(true, venv,                           user_env->for_each(append_env_pair, &env);
                         method_name, "env must not be code");                  else
                 if(Hash *user_env=venv.get_hash()) {  
                         env=new(pool) Hash(pool);  
                         user_env->for_each(append_env_pair, env);  
                 } else  
                         PTHROW(0, 0,                          PTHROW(0, 0,
                                 &method_name,                                  &method_name,
                                 "env must be hash");                                  "env must be hash");
Line 141  static void _cgi(Request& r, const Strin Line 195  static void _cgi(Request& r, const Strin
         if(params->size()>2) {          if(params->size()>2) {
                 argv=new(pool) Array(pool, params->size()-2);                  argv=new(pool) Array(pool, params->size()-2);
                 for(int i=2; i<params->size(); i++)                  for(int i=2; i<params->size(); i++)
                         *argv+=&static_cast<Value *>(params->get(i))->as_string();                          *argv+=&params->get(i).as_string();
         }          }
   
         const String in(pool, r.post_data, r.post_size);          const String in(pool, r.post_data, r.post_size);
         String out(pool);          String out(pool);
         String err(pool);          //out.APPEND_CONST("content-type:text/plain\nheader:test-header\n\ntest-body");
         int exit_code=SAPI::execute(r.absolute(vfile_name.as_string()), env, argv,          //out<<in;
                 in, out, err);          String& err=*new(pool) String(pool);
           int exit_code=pa_exec(script_name, &env, argv, in, out, err);
   
         VFile& self=*static_cast<VFile *>(r.self);          VFile& self=*static_cast<VFile *>(r.self);
         // construct with 'out' body and header          // construct with 'out' body and header
         int delim_size;          int delim_size;
         int pos=out.pos("\n\n", delim_size=2);          const char *eol_marker="\r\n"; size_t eol_marker_size=2;
         if(pos<0)          int pos=out.pos("\r\n\r\n", delim_size=4);
                 pos=out.pos("\r\n\r\n", delim_size=4);          if(pos<0) {
                   eol_marker="\n"; eol_marker_size=1;
                   pos=out.pos("\n\n", delim_size=2);
           }
         if(pos<0) {          if(pos<0) {
                 delim_size=0; // calm down, compiler                  delim_size=0; // calm down, compiler
                 PTHROW(0, 0,                  PTHROW(0, 0,
                         &method_name,                          &method_name,
                         "output does not contain CGI header");                          "output does not contain CGI header; exit code=%d; size=%u; text: \"%s\"", 
                                   exit_code, (uint)out.size(), out.cstr());
         }          }
   
         const String& header=out.mid(0, pos);          const String& header=out.mid(0, pos);
Line 169  static void _cgi(Request& r, const Strin Line 228  static void _cgi(Request& r, const Strin
         // body          // body
         self.set(false/*not tainted*/, body.cstr(String::UL_AS_IS), body.size());          self.set(false/*not tainted*/, body.cstr(String::UL_AS_IS), body.size());
   
         // todo header to $fields. waits for header '\' tricks          // header to $fields
           {
                   Array rows(pool);
                   header.split(rows, 0, eol_marker, eol_marker_size, String::UL_CLEAN);
                   rows.for_each(pass_cgi_header_attribute, &self.fields());
           }
   
         // $exit-code          // $exit-code
         self.fields().put(          self.fields().put(
Line 186  static void _cgi(Request& r, const Strin Line 250  static void _cgi(Request& r, const Strin
         }          }
 }  }
   
 // initialize  // constructor
   
   MFile::MFile(Pool& apool) : Methoded(apool) {
           set_name(*NEW String(pool(), FILE_CLASS_NAME));
   
   
 void initialize_file_class(Pool& pool, VStateless_class& vclass) {  
         // ^save[file-name]          // ^save[file-name]
         vclass.add_native_method("save", Method::CT_DYNAMIC, _save, 1, 1);          add_native_method("save", Method::CT_DYNAMIC, _save, 1, 1);
   
         // ^delete[file-name]          // ^delete[file-name]
         vclass.add_native_method("delete", Method::CT_STATIC, _delete, 1, 1);          add_native_method("delete", Method::CT_STATIC, _delete, 1, 1);
   
         // ^find[file-name]          // ^find[file-name]
         // ^find[file-name]{when-not-found}          // ^find[file-name]{when-not-found}
         vclass.add_native_method("find", Method::CT_STATIC, _find, 1, 2);          add_native_method("find", Method::CT_STATIC, _find, 1, 2);
   
         // ^load[disk-name]          // ^load[disk-name]
         // ^load[disk-name;user-name]          // ^load[disk-name;user-name]
         vclass.add_native_method("load", Method::CT_DYNAMIC, _load, 1, 2);          add_native_method("load", Method::CT_DYNAMIC, _load, 1, 2);
   
           // ^stat[disk-name]
           add_native_method("stat", Method::CT_DYNAMIC, _stat, 1, 1);
   
           // ^cgi[file-name]
           // ^cgi[file-name;env hash]
           // ^cgi[file-name;env hash;1cmd;2line;3ar;4g;5s]
           add_native_method("cgi", Method::CT_DYNAMIC, _cgi, 1, 2+5);
   }
   
   // global variable
   
   Methoded *file_class;
   
   // creator
   
         // ^exec[file-name]  Methoded *MFile_create(Pool& pool) {
         // ^exec[file-name;env hash]          return file_class=new(pool) MFile(pool);
         // ^exec[file-name;env hash;1cmd;2line;3ar;4g;5s]  
         vclass.add_native_method("cgi", Method::CT_DYNAMIC, _cgi, 1, 2+5);  
 }  }

Removed from v.1.22  
changed lines
  Added in v.1.38


E-mail: