--- parser3/src/classes/file.C 2003/02/17 07:18:56 1.107.2.11 +++ parser3/src/classes/file.C 2003/03/21 13:42:26 1.107.2.16.2.5 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_FILE_C="$Date: 2003/02/17 07:18:56 $"; +static const char* IDENT_FILE_C="$Date: 2003/03/21 13:42:26 $"; #include "pa_config_includes.h" @@ -31,10 +31,10 @@ static const char* IDENT_FILE_C="$Date: // class -class MFile : public Methoded { +class MFile: public Methoded { public: // VStateless_class - ValuePtr create_new_value() { return ValuePtr(new VFile()); } + Value* create_new_value() { return Value*(new VFile()); } public: // Methoded bool used_directly() { return true; } @@ -46,7 +46,7 @@ public: // global variable -MethodedPtr file_class(new MFile); +DECLARE_CLASS_VAR(file, new MFile, 0); // consts @@ -96,39 +96,36 @@ static const char* suexec_safe_env_lst[] // statics -static StringPtr adate_name(new String("adate")); -static StringPtr mdate_name(new String("mdate")); -static StringPtr cdate_name(new String("cdate")); +static const String& adate_name(new String("adate")); +static const String& mdate_name(new String("mdate")); +static const String& cdate_name(new String("cdate")); // methods -static void _save(Request& r, StringPtr /*method_name*/, MethodParams& params) { - Pool& pool=r.pool(); - ValuePtr vmode_name=params. as_no_junction(0, "mode must not be code"); - ValuePtr vfile_name=params.as_no_junction(1, "file name must not be code"); +static void _save(Request& r, const String& /*method_name*/, MethodParams* params) { + Value* vmode_name=params-> as_no_junction(0, "mode must not be code"); + Value* vfile_name=params->as_no_junction(1, "file name must not be code"); // save - GET_SELF(r, VFile).save(r.absolute(vfile_name->as_string(&pool)), - *vmode_name->as_string(&pool)==TEXT_MODE_NAME); + GET_SELF(r, VFile).save(r.absolute(vfile_name->as_string()), + *vmode_name->as_string()==TEXT_MODE_NAME); } -static void _delete(Request& r, StringPtr /*method_name*/, MethodParams& params) { - Pool& pool=r.pool(); - ValuePtr vfile_name=params.as_no_junction(0, "file name must not be code"); +static void _delete(Request& r, const String& /*method_name*/, MethodParams* params) { + Value* vfile_name=params->as_no_junction(0, "file name must not be code"); // unlink - file_delete(r.absolute(vfile_name->as_string(&pool))); + file_delete(r.absolute(vfile_name->as_string())); } -static void _move(Request& r, StringPtr /*method_name*/, MethodParams& params) { - Pool& pool=r.pool(); - ValuePtr vfrom_file_name=params.as_no_junction(0, "from file name must not be code"); - ValuePtr vto_file_name=params.as_no_junction(1, "to file name must not be code"); +static void _move(Request& r, const String& /*method_name*/, MethodParams* params) { + Value* vfrom_file_name=params->as_no_junction(0, "from file name must not be code"); + Value* vto_file_name=params->as_no_junction(1, "to file name must not be code"); // move file_move( - r.absolute(vfrom_file_name->as_string(&pool)), - r.absolute(vto_file_name->as_string(&pool))); + r.absolute(vfrom_file_name->as_string()), + r.absolute(vto_file_name->as_string())); } static void _load_pass_param( @@ -137,43 +134,41 @@ static void _load_pass_param( HashStringValue *dest) { dest->put(key, value); } -static void _load(Request& r, StringPtr method_name, MethodParams& params) { - Pool& pool=r.pool(); - ValuePtr vmode_name=params. as_no_junction(0, "mode must not be code"); - StringPtr lfile_name=r.absolute(params.as_no_junction(1, "file name must not be code")->as_string(&pool)); - ValuePtr third_param=params.count()>2?params.as_no_junction(2, "filename or options must not be code") - :ValuePtr(0); +static void _load(Request& r, const String& method_name, MethodParams* params) { + Value* vmode_name=params-> as_no_junction(0, "mode must not be code"); + const String& lfile_name=r.absolute(params->as_no_junction(1, "file name must not be code")->as_string()); + Value* third_param=params->count()>2?params->as_no_junction(2, "filename or options must not be code") + :0; HashStringValue* third_param_hash=third_param?third_param->get_hash(method_name):0; int alt_filename_param_index=2; if(third_param_hash) alt_filename_param_index++; - File_read_result file=file_read(pool, r.charsets.source(), lfile_name, - *vmode_name->as_string(&pool)==TEXT_MODE_NAME, + File_read_result file=file_read(r.charsets.source(), lfile_name, + *vmode_name->as_string()==TEXT_MODE_NAME, third_param_hash ); - char *user_file_name=params.count()>alt_filename_param_index? - params.as_string(alt_filename_param_index, "filename must be string")->cstr(pool) - :lfile_name->cstr(pool, String::UL_FILE_SPEC); + char *user_file_name=params->count()>alt_filename_param_index? + params->as_string(alt_filename_param_index, "filename must be string")->cstr() + :lfile_name->cstr(String::L_FILE_SPEC); - ValuePtr vcontent_type(0); + Value* vcontent_type(0); if(file.headers) vcontent_type=file.headers->get(content_type_name); if(!vcontent_type) - vcontent_type=ValuePtr(new VString(r.mime_type_of(user_file_name))); + vcontent_type=Value*(new VString(r.mime_type_of(user_file_name))); VFile& self=GET_SELF(r, VFile); - self.set(pool, true/*tainted*/, file.data, file.size, user_file_name, vcontent_type); + self.set(true/*tainted*/, file.data, file.size, user_file_name, vcontent_type); if(file.headers) file.headers->for_each(_load_pass_param, &self.fields()); } -static void _stat(Request& r, StringPtr method_name, MethodParams& params) { - Pool& pool=r.pool(); - ValuePtr vfile_name=params.as_no_junction(0, "file name must not be code"); +static void _stat(Request& r, const String& method_name, MethodParams* params) { + Value* vfile_name=params->as_no_junction(0, "file name must not be code"); - StringPtr lfile_name=vfile_name->as_string(&pool); + const String& lfile_name=vfile_name->as_string(); size_t size; time_t atime, mtime, ctime; @@ -182,15 +177,15 @@ static void _stat(Request& r, StringPtr atime, mtime, ctime); VFile& self=GET_SELF(r, VFile); - self.set(pool, true/*tainted*/, 0/*no bytes*/, size); + self.set(true/*tainted*/, 0/*no bytes*/, size); HashStringValue& ff=self.fields(); - ff.put(adate_name, ValuePtr(new VDate(atime))); - ff.put(mdate_name, ValuePtr(new VDate(mtime))); - ff.put(cdate_name, ValuePtr(new VDate(ctime))); - ff.put(content_type_name, ValuePtr(new VString(r.mime_type_of(lfile_name->cstr(String::UL_FILE_SPEC))))); + ff.put(adate_name, Value*(new VDate(atime))); + ff.put(mdate_name, Value*(new VDate(mtime))); + ff.put(cdate_name, Value*(new VDate(ctime))); + ff.put(content_type_name, Value*(new VString(r.mime_type_of(lfile_name->cstr(String::L_FILE_SPEC))))); } -static bool is_safe_env_key(CharPtr key) { +static bool is_safe_env_key(const char* key) { if(strncasecmp(key, "HTTP_", 5)==0) return true; if(strncasecmp(key, "CGI_", 4)==0) @@ -203,9 +198,9 @@ static bool is_safe_env_key(CharPtr key) } #ifndef DOXYGEN struct Append_env_pair_info { - Pool* pool; + ; HashStringString* env; - ValuePtr vstdin; + Value* vstdin; }; #endif static void append_env_pair( @@ -224,10 +219,10 @@ static void append_env_pair( } #ifndef DOXYGEN struct Pass_cgi_header_attribute_info { - Pool* pool; + ; Charset* charset; HashStringValue* fields; - ValuePtr content_type; + Value* content_type; }; #endif static void pass_cgi_header_attribute( @@ -235,36 +230,35 @@ static void pass_cgi_header_attribute( Pass_cgi_header_attribute_info* info) { int colon_pos=astring->pos(":", 1); if(colon_pos>0) { - StringPtr key(astring->mid(0, colon_pos)->change_case( - *info->pool, *info->charset, String::CC_UPPER)); - ValuePtr value(new VString(astring->mid(colon_pos+1, astring->size()))); + const String& key(astring->mid(0, colon_pos)->change_case( + *info->*info->charset, String::CC_UPPER)); + Value* value(new VString(astring->mid(colon_pos+1, astring->length()))); info->fields->put(key, value); if(*key=="CONTENT-TYPE") info->content_type=value; } } /// @todo fix `` in perl - they produced flipping consoles and no output to perl -static void _exec_cgi(Request& r, StringPtr method_name, MethodParams& params, +static void _exec_cgi(Request& r, const String& method_name, MethodParams* params, bool cgi) { - Pool& pool=r.pool(); - ValuePtr vfile_name=params.as_no_junction(0, "file name must not be code"); + Value* vfile_name=params->as_no_junction(0, "file name must not be code"); - StringPtr script_name=r.absolute(vfile_name->as_string(&pool)); + const String& script_name=r.absolute(vfile_name->as_string()); HashStringString env; #define ECSTR(name, value_cstr) \ if(value_cstr) \ env.put( \ - StringPtr(new String(#name)), \ - StringPtr(new String(value_cstr))); \ + String* (new String(#name)), \ + String* (new String(value_cstr))); \ // passing SAPI::environment if(const char* const *pairs=SAPI::environment(r.sapi_info, pool)) { while(const char* pair=*pairs++) if(const char* eq_at=strchr(pair, '=')) env.put( - StringPtr(new String(pair, eq_at-pair)), - StringPtr(new String(eq_at+1))); + String* (new String(pair, eq_at-pair)), + String* (new String(eq_at+1))); } // const @@ -281,14 +275,14 @@ static void _exec_cgi(Request& r, String //String content_length(content_length_cstr); ECSTR(CONTENT_LENGTH, content_length_cstr); // SCRIPT_* - env.put(StringPtr(new String("SCRIPT_NAME")), script_name); - //env.put(*new(pool) String(pool, "SCRIPT_FILENAME"), ??&script_name); + env.put(String* (new String("SCRIPT_NAME")), script_name); + //env.put(*new String("SCRIPT_FILENAME"), ??&script_name); bool stdin_specified=false; // environment & stdin from param String in; - if(params.count()>1) { - ValuePtr venv=params.as_no_junction(1, "env must not be code"); + if(params->count()>1) { + Value* venv=params->as_no_junction(1, "env must not be code"); if(HashStringValue* user_env=venv->get_hash(method_name)) { Append_env_pair_info info; info.pool=&pool; @@ -296,8 +290,8 @@ static void _exec_cgi(Request& r, String user_env->for_each(append_env_pair, &info); if(info.vstdin) { stdin_specified=true; - if(StringPtr sstdin=info.vstdin->get_string(&pool)) { - in.append(*sstdin, String::UL_CLEAN, true); + if(const String& sstdin=info.vstdin->get_string()) { + in.append(*sstdin, String::L_CLEAN, true); } else if(VFile *vfile=static_cast(info.vstdin->as("file", false))) in.APPEND_TAINTED((const char* )vfile->value_ptr(), vfile->value_size(), @@ -312,26 +306,26 @@ static void _exec_cgi(Request& r, String // argv from params ArrayString argv; - if(params.count()>2) { - for(int i=2; icount()>2) { + for(int i=2; icount(); i++) + argv+=params->as_string(i, "parameter must be string"); } // passing POST data if(!stdin_specified) // if $.stdin[...] not specified - in.APPEND(r.request_info.post_data, r.request_info.post_size, String::UL_CLEAN, + in.APPEND(r.request_info.post_data, r.request_info.post_size, String::L_CLEAN, "POST data (passed)", 0); // exec! PA_exec_result execution= - pa_exec(pool, false/*forced_allow*/, script_name, env, argv, in); + pa_exec(false/*forced_allow*/, script_name, &env, argv, in); VFile& self=GET_SELF(r, VFile); - StringPtr body=execution.out; // ^file:exec - ValuePtr content_type(0); + const String& body=execution.out; // ^file:exec + Value* content_type(0); const char* eol_marker=0; size_t eol_marker_size; - StringPtr header(0); + const String& header(0); if(cgi) { // ^file:cgi // construct with 'out' body and header int dos_pos=execution.out->pos("\r\n\r\n", 4); @@ -355,8 +349,8 @@ static void _exec_cgi(Request& r, String "output does not contain CGI header; " "exit status=%d; stdoutsize=%u; stdout: \"%s\"; stderrsize=%u; stderr: \"%s\"", execution.status, - (uint)execution.out->size(), execution.out->cstr(), - (uint)execution.err->size(), execution.err->cstr()); + (uint)execution.out->length(), execution.out->cstr().get(), + (uint)execution.err->length(), execution.err->cstr().get()); break; //never reached } @@ -370,10 +364,10 @@ static void _exec_cgi(Request& r, String } header=execution.out->mid(0, header_break_pos); - body=execution.out->mid(header_break_pos+eol_marker_size*2, execution.out->size()); + body=execution.out->mid(header_break_pos+eol_marker_size*2, execution.out->length()); } // body - self.set(pool, false/*not tainted*/, body->cstr(), body->size()); + self.set(false/*not tainted*/, body->cstr(), body->length()); // $fields << header if(header && eol_marker) { @@ -389,32 +383,31 @@ static void _exec_cgi(Request& r, String } // $status - self.fields().put(file_status_name, ValuePtr(new VInt(execution.status))); + self.fields().put(file_status_name, Value*(new VInt(execution.status))); // $stderr - if(execution.err->size()) + if(execution.err->length()) self.fields().put( - StringPtr(new String("stderr")), - ValuePtr(new VString(execution.err))); + String* (new String("stderr")), + Value*(new VString(execution.err))); } -static void _exec(Request& r, StringPtr method_name, MethodParams& params) { +static void _exec(Request& r, const String& method_name, MethodParams* params) { _exec_cgi(r, method_name, params, false); } -static void _cgi(Request& r, StringPtr method_name, MethodParams& params) { +static void _cgi(Request& r, const String& method_name, MethodParams* params) { _exec_cgi(r, method_name, params, true); } -static void _list(Request& r, StringPtr method_name, MethodParams& params) { - Pool& pool=r.pool(); +static void _list(Request& r, const String& method_name, MethodParams* params) { - ValuePtr relative_path=params.as_no_junction(0, "path must not be code"); + Value* relative_path=params->as_no_junction(0, "path must not be code"); - StringPtr regexp; + const String& regexp; pcre *regexp_code; const int ovecsize=(1/*match*/)*3; int ovector[ovecsize]; - if(params.count()>1) { - regexp=params.as_no_junction(1, "regexp must not be code")->as_string(&pool); + if(params->count()>1) { + regexp=params->as_no_junction(1, "regexp must not be code")->as_string(); const char* pattern=regexp->cstr(); const char* errptr; @@ -425,18 +418,18 @@ static void _list(Request& r, StringPtr if(!regexp_code) throw Exception(0, - regexp->mid(erroffset, regexp->size()), + regexp->mid(erroffset, regexp->length()), "regular expression syntax error - %s", errptr); } else regexp_code=0; - CharPtr absolute_path_cstr=r.absolute(relative_path->as_string(&pool))-> - cstr(String::UL_FILE_SPEC); + const char* absolute_path_cstr=r.absolute(relative_path->as_string())-> + cstr(String::L_FILE_SPEC); Table::columns_type columns(new ArrayString); - *columns+=StringPtr(new String("name")); - TablePtr table(new Table(method_name, columns)); + *columns+=String* (new String("name")); + Table* table(new Table(method_name, columns)); LOAD_DIR(absolute_path_cstr, const char* file_name_cstr=ffblk.ff_name; @@ -459,7 +452,7 @@ static void _list(Request& r, StringPtr } if(suits) { - StringPtr file_name(new String); + const String& file_name(new String); file_name->APPEND_TAINTED(pool.copy(file_name_cstr, file_name_size), file_name_size, method_name->origin().file, method_name->origin().line); @@ -473,13 +466,13 @@ static void _list(Request& r, StringPtr pcre_free(regexp_code); // write out result - r.write_no_lang(ValuePtr(new VTable(table))); + r.write_no_lang(Value*(new VTable(table))); } #ifndef DOXYGEN struct Lock_execute_body_info { Request* r; - ValuePtr body_code; + Value* body_code; }; #endif static void lock_execute_body(int , void *ainfo) { @@ -487,11 +480,11 @@ static void lock_execute_body(int , void // execute body info.r->write_assign_lang(info.r->process(info.body_code)); }; -static void _lock(Request& r, StringPtr method_name, MethodParams& params) { +static void _lock(Request& r, const String& method_name, MethodParams* params) { Lock_execute_body_info info; info.r=&r; - StringPtr file_spec=r.absolute(params.as_string(0, "file name must be string")); - info.body_code=params.as_junction(1, "body must be code"); + const String& file_spec=r.absolute(params->as_string(0, "file name must be string")); + info.body_code=params->as_junction(1, "body must be code"); file_write_action_under_lock(file_spec, "lock", lock_execute_body, &info); } @@ -499,7 +492,7 @@ static void _lock(Request& r, StringPtr static int lastposafter(const String& s, int after, const char* substr, size_t substr_size, bool beforelast=false) { size_t size; if(beforelast) - size=s.size(); + size=s.length(); int at; while((at=s.pos(substr, substr_size, after))>=0) { size_t newafter=at+substr_size/*skip substr*/; @@ -511,10 +504,9 @@ static int lastposafter(const String& s, return after; } -static void _find(Request& r, StringPtr method_name, MethodParams& params) { - Pool& pool=r.pool(); - StringPtr file_name=params.as_no_junction(0, "file name must not be code")->as_string(&pool); - StringPtr file_spec; +static void _find(Request& r, const String& method_name, MethodParams* params) { + 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 @@ -528,12 +520,12 @@ static void _find(Request& r, StringPtr // monkey way int after_base_slash=lastposafter(*file_spec, 0, "/", 1); - StringPtr dirname=file_spec->mid(0, after_base_slash); - StringPtr basename=file_spec->mid(after_base_slash, file_spec->size()); + const String& dirname=file_spec->mid(0, after_base_slash); + const String& basename=file_spec->mid(after_base_slash, file_spec->length()); int after_monkey_slash; while((after_monkey_slash=lastposafter(*dirname, 0, "/", 1, true))>0) { - StringPtr test_name(new String); + const String& test_name(new String); *test_name<<*(dirname=dirname->mid(0, after_monkey_slash)); *test_name<count()==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, StringPtr method_name, MethodParams& params) { - StringPtr file_spec=params.as_string(0, "file name must be string"); +static void _dirname(Request& r, const String& method_name, MethodParams* params) { + const String& file_spec=params->as_string(0, "file name must be string"); // /a/some.tar.gz > /a // /a/b/ > /a int afterslash=lastposafter(*file_spec, 0, "/", 1, true); @@ -560,36 +552,36 @@ static void _dirname(Request& r, StringP r.write_assign_lang(String(".", 1)); } -static void _basename(Request& r, StringPtr method_name, MethodParams& params) { - StringPtr file_spec=params.as_string(0, "file name must be string"); +static void _basename(Request& r, const String& method_name, MethodParams* params) { + const String& file_spec=params->as_string(0, "file name must be string"); // /a/some.tar.gz > some.tar.gz int afterslash=lastposafter(*file_spec, 0, "/", 1); - r.write_assign_lang(*file_spec->mid(afterslash, file_spec->size())); + r.write_assign_lang(*file_spec->mid(afterslash, file_spec->length())); } -static void _justname(Request& r, StringPtr method_name, MethodParams& params) { - StringPtr file_spec=params.as_string(0, "file name must be string"); +static void _justname(Request& r, const String& method_name, MethodParams* params) { + const String& file_spec=params->as_string(0, "file name must be string"); // /a/some.tar.gz > some.tar int afterslash=lastposafter(*file_spec, 0, "/", 1); int afterdot=lastposafter(*file_spec, afterslash, ".", 1); - r.write_assign_lang(*file_spec->mid(afterslash, afterdot!=afterslash?afterdot-1:file_spec->size())); + r.write_assign_lang(*file_spec->mid(afterslash, afterdot!=afterslash?afterdot-1:file_spec->length())); } -static void _justext(Request& r, StringPtr method_name, MethodParams& params) { - StringPtr file_spec=params.as_string(0, "file name must be string"); +static void _justext(Request& r, const String& method_name, MethodParams* params) { + const String& file_spec=params->as_string(0, "file name must be string"); // /a/some.tar.gz > gz int afterdot=lastposafter(*file_spec, 0, ".", 1); if(afterdot>0) - r.write_assign_lang(*file_spec->mid(afterdot, file_spec->size())); + r.write_assign_lang(*file_spec->mid(afterdot, file_spec->length())); } -static void _fullpath(Request& r, StringPtr method_name, MethodParams& params) { - StringPtr file_spec=params.as_string(0, "file name must be string"); - StringPtr result(new String); +static void _fullpath(Request& r, const String& method_name, MethodParams* params) { + const String& file_spec=params->as_string(0, "file name must be string"); + const String& result(new String); if(file_spec->first_char()=='/') result=file_spec; else { // /some/page.html: ^file:fullpath[a.gif] => /some/a.gif - StringPtr full_disk_path=r.absolute(file_spec); + const String& full_disk_path=r.absolute(file_spec); size_t document_root_length=strlen(r.request_info.document_root); if(document_root_length>0) { @@ -597,7 +589,7 @@ static void _fullpath(Request& r, String if(last_char == '/' || last_char == '\\') --document_root_length; } - result=full_disk_path->mid(document_root_length, full_disk_path->size()); + result=full_disk_path->mid(document_root_length, full_disk_path->length()); } r.write_assign_lang(*result); }