Diff for /parser3/src/classes/file.C between versions 1.88.2.1 and 1.92

version 1.88.2.1, 2002/06/20 16:31:07 version 1.92, 2002/08/01 11:41:12
Line 3 Line 3
   
         Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
   
         $Id$  
 */  */
   
   static const char* IDENT_FILE_C="$Date$";
   
 #include "pa_config_includes.h"  #include "pa_config_includes.h"
   
 #include "pcre.h"  #include "pcre.h"
Line 25 Line 25
 // defines  // defines
   
 #define TEXT_MODE_NAME "text"  #define TEXT_MODE_NAME "text"
   #define STDIN_EXEC_PARAM_NAME "stdin"
   
 // consts  // consts
   
Line 87  public: Line 88  public:
   
 };  };
   
 // consts  
   
 const int FIND_MONKEY_MAX_HOPS=10;  
   
 // methods  // methods
   
 static void _save(Request& r, const String&, MethodParams *params) {  static void _save(Request& r, const String&, MethodParams *params) {
Line 119  static void _move(Request& r, const Stri Line 116  static void _move(Request& r, const Stri
                 r.absolute(vto_file_name.as_string()));                  r.absolute(vto_file_name.as_string()));
 }  }
   
 static void _find(Request& r, const String& method_name, MethodParams *params) {  
         Pool& pool=r.pool();  
         Value& vfile_name=params->as_no_junction(0, "file name must not be code");  
   
         const String &lfile_name=vfile_name.as_string();  
   
         // passed file name simply exists in current dir  
         if(file_readable(r.absolute(lfile_name))) {  
                 r.write_no_lang(lfile_name);  
                 return;  
         }  
   
         // scan .. dirs for result  
         for(int i=0; i<FIND_MONKEY_MAX_HOPS; i++) {  
                 String local_test_name(pool);  
                 for(int j=0; j<i; j++)  
                         local_test_name.APPEND_CONST("../");  
                 local_test_name.append(lfile_name, String::UL_CLEAN);  
                 if(file_readable(r.absolute(local_test_name))) {  
                         r.write_no_lang(*new(pool) String(local_test_name));  
                         return;  
                 }  
         }  
   
         // not found  
         if(params->size()==2) {  
                 Value& not_found_code=params->as_junction(1, "not-found param must be code");  
                 r.write_pass_lang(r.process(not_found_code));  
         }  
 }  
   
 static void _load(Request& r, const String& method_name, MethodParams *params) {  static void _load(Request& r, const String& method_name, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
         Value& vmode_name=params-> as_no_junction(0, "mode must not be code");          Value& vmode_name=params-> as_no_junction(0, "mode must not be code");
Line 200  static bool is_safe_env_key(const char * Line 166  static bool is_safe_env_key(const char *
         }          }
         return false;          return false;
 }  }
   #ifndef DOXYGEN
   struct Append_env_pair_info {
           Hash* hash;
           const String* sstdin;
   };
   #endif
 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);          Append_env_pair_info& pi=*static_cast<Append_env_pair_info *>(info);
         if(!is_safe_env_key(key.cstr()))          const String& svalue=static_cast<Value *>(value)->as_string();
                 throw Exception("parser.runtime",  
                         &key,          if(key==STDIN_EXEC_PARAM_NAME) {
                         "not safe environment variable");                  pi.sstdin=&svalue;
         hash.put(key, &static_cast<Value *>(value)->as_string());          } else {
                   if(!is_safe_env_key(key.cstr()))
                           throw Exception("parser.runtime",
                                   &key,
                                   "not safe environment variable");
                   pi.hash->put(key, &svalue);
           }
 }  }
 static void pass_cgi_header_attribute(Array::Item *value, void *info) {  static void pass_cgi_header_attribute(Array::Item *value, void *info) {
         String& string=*static_cast<String *>(value);          String& string=*static_cast<String *>(value);
Line 216  static void pass_cgi_header_attribute(Ar Line 194  static void pass_cgi_header_attribute(Ar
                 hash.put(string.mid(0, colon_pos),                   hash.put(string.mid(0, colon_pos), 
                 new(string.pool()) VString(string.mid(colon_pos+1, string.size())));                  new(string.pool()) VString(string.mid(colon_pos+1, string.size())));
 }  }
 /** @todo fix `` in perl - they produced flipping consoles and no output to perl  /// @todo fix `` in perl - they produced flipping consoles and no output to perl
 */  
 static void _exec_cgi(Request& r, const String& method_name, MethodParams *params,  static void _exec_cgi(Request& r, const String& method_name, MethodParams *params,
                                           bool cgi) {                                            bool cgi) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
Line 261  static void _exec_cgi(Request& r, const Line 238  static void _exec_cgi(Request& r, const
         env.put(*new(pool) String(pool, "SCRIPT_NAME"), &script_name);          env.put(*new(pool) String(pool, "SCRIPT_NAME"), &script_name);
         //env.put(*new(pool) String(pool, "SCRIPT_FILENAME"), ??&script_name);          //env.put(*new(pool) String(pool, "SCRIPT_FILENAME"), ??&script_name);
   
           // environment & stdin from param
           String in(pool);
         if(params->size()>1) {          if(params->size()>1) {
                 Value& venv=params->as_no_junction(1, "env must not be code");                  Value& venv=params->as_no_junction(1, "env must not be code");
                 if(Hash *user_env=venv.get_hash(&method_name))                  if(Hash *user_env=venv.get_hash(&method_name)) {
                         user_env->for_each(append_env_pair, &env);                          Append_env_pair_info info={&env};
                           user_env->for_each(append_env_pair, &info);
                           if(info.sstdin)
                                   in.append(*info.sstdin, String::UL_CLEAN, true);
                   }
         }          }
   
           // argv from params
         Array *argv=0;          Array *argv=0;
         if(params->size()>2) {          if(params->size()>2) {
                 argv=new(pool) Array(pool, params->size()-2);                  argv=new(pool) Array(pool, params->size()-2);
Line 274  static void _exec_cgi(Request& r, const Line 258  static void _exec_cgi(Request& r, const
                         *argv+=&params->as_string(i, "parameter must be string");                          *argv+=&params->as_string(i, "parameter must be string");
         }          }
   
         String in(pool);          // passing POST data
         in.APPEND(r.post_data, r.post_size, String::UL_CLEAN, "passing post data", 0);          if(in.is_empty()) // if $.stdin[...] not specified 
                   in.APPEND(r.post_data, r.post_size, String::UL_CLEAN, "POST data (passed)", 0);
   
           // exec!
         String out(pool);          String out(pool);
         //out.APPEND_CONST("content-type:text/plain\nheader:test-header\n\ntest-body");  
         //out<<in;  
         String& err=*new(pool) String(pool);          String& err=*new(pool) String(pool);
         int status=pa_exec(false/*forced_allow*/, script_name, &env, argv, in, out, err);          int status=pa_exec(false/*forced_allow*/, script_name, &env, argv, in, out, err);
   
Line 298  static void _exec_cgi(Request& r, const Line 283  static void _exec_cgi(Request& r, const
                         delim_size=0; // calm down, compiler                          delim_size=0; // calm down, compiler
                         throw Exception(0,                          throw Exception(0,
                                 &method_name,                                  &method_name,
                                 "output does not contain CGI header; exit status=%d; stdoutsize=%u; stdout: \"%s\"; stderrsize=%u; stderr: \"%s\"",                                   "output does not contain CGI header; "
                                   "exit status=%d; stdoutsize=%u; stdout: \"%s\"; stderrsize=%u; stderr: \"%s\"", 
                                         status,                                           status, 
                                         (uint)out.size(), out.cstr(),                                          (uint)out.size(), out.cstr(),
                                         (uint)err.size(), err.cstr());                                          (uint)err.size(), err.cstr());
Line 447  static int lastposafter(const String& s, Line 433  static int lastposafter(const String& s,
         return after;          return after;
 }  }
   
   static void _find(Request& r, const String& method_name, MethodParams *params) {
           Pool& pool=r.pool();
           const String &file_name=params->as_no_junction(0, "file name must not be code").as_string();
           const String *file_spec;
           if(file_name.first_char()=='/')
                   file_spec=&file_name;
           else 
                   file_spec=&r.relative(r.info.uri, file_name);
   
           // easy way
           if(file_readable(r.absolute(*file_spec))) {
                   r.write_no_lang(*file_spec);
                   return;
           }
   
           // monkey way
           int after_base_slash=lastposafter(*file_spec, 0, "/", 1);
           const String *dirname=&file_spec->mid(0, after_base_slash);
           const String& basename=file_spec->mid(after_base_slash, file_spec->size());
   
           int after_monkey_slash;
           while((after_monkey_slash=lastposafter(*dirname, 0, "/", 1, true))>0) {
                   String local_test_name(pool);
                   local_test_name<<*(dirname=&dirname->mid(0, after_monkey_slash));
                   local_test_name<<basename;
                   if(file_readable(r.absolute(local_test_name))) {
                           r.write_no_lang(*new(pool) String(local_test_name));
                           return;
                   }
           }
   
           // no way, not found
           if(params->size()==2) {
                   Value& not_found_code=params->as_junction(1, "not-found param must be code");
                   r.write_pass_lang(r.process(not_found_code));
           }
   }
   
 static void _dirname(Request& r, const String& method_name, MethodParams *params) {  static void _dirname(Request& r, const String& method_name, MethodParams *params) {
         Pool& pool=r.pool();          Pool& pool=r.pool();
         const String& file_spec=params->as_string(0, "file name must be string");          const String& file_spec=params->as_string(0, "file name must be string");
Line 494  MFile::MFile(Pool& apool) : Methoded(apo Line 518  MFile::MFile(Pool& apool) : Methoded(apo
         // ^move[from-file-name;to-file-name]          // ^move[from-file-name;to-file-name]
         add_native_method("move", Method::CT_STATIC, _move, 2, 2);          add_native_method("move", Method::CT_STATIC, _move, 2, 2);
   
         // ^find[file-name]  
         // ^find[file-name]{when-not-found}  
         add_native_method("find", Method::CT_STATIC, _find, 1, 2);  
   
         // ^load[mode;disk-name]          // ^load[mode;disk-name]
         // ^load[mode;disk-name;user-name]          // ^load[mode;disk-name;user-name]
         add_native_method("load", Method::CT_DYNAMIC, _load, 2, 3);          add_native_method("load", Method::CT_DYNAMIC, _load, 2, 3);
Line 522  MFile::MFile(Pool& apool) : Methoded(apo Line 542  MFile::MFile(Pool& apool) : Methoded(apo
         // ^file:lock[path]{code}          // ^file:lock[path]{code}
         add_native_method("lock", Method::CT_STATIC, _lock, 2, 2);          add_native_method("lock", Method::CT_STATIC, _lock, 2, 2);
   
           // ^find[file-name]
           // ^find[file-name]{when-not-found}
           add_native_method("find", Method::CT_STATIC, _find, 1, 2);
   
     // ^file:dirname[/a/some.tar.gz]=/a      // ^file:dirname[/a/some.tar.gz]=/a
         // ^file:dirname[/a/b/]=/a          // ^file:dirname[/a/b/]=/a
         add_native_method("dirname", Method::CT_STATIC, _dirname, 1, 1);          add_native_method("dirname", Method::CT_STATIC, _dirname, 1, 1);

Removed from v.1.88.2.1  
changed lines
  Added in v.1.92


E-mail: