--- parser3/src/targets/cgi/parser3.C 2024/08/25 16:24:03 1.352 +++ parser3/src/targets/cgi/parser3.C 2024/08/26 20:47:06 1.355 @@ -5,7 +5,7 @@ Authors: Konstantin Morshnev , Alexandr Petrosian */ -volatile const char * IDENT_PARSER3_C="$Id: parser3.C,v 1.352 2024/08/25 16:24:03 moko Exp $"; +volatile const char * IDENT_PARSER3_C="$Id: parser3.C,v 1.355 2024/08/26 20:47:06 moko Exp $"; #include "pa_config_includes.h" @@ -58,13 +58,12 @@ static THREAD_LOCAL Request_info *reques static const char* filespec_4log = NULL; // null only if system-wide auto.p used template static T *dir_pos(T *fname){ - T *pos=fname; T *result=NULL; - while (pos=strpbrk(pos, "/\\")){ - result=pos; - pos++; + while (fname=strpbrk(fname, "/\\")){ + result=fname; + fname++; } - return !result || (result==fname+1 && *fname=='.') ? NULL : result; + return result; } // SAPI @@ -89,7 +88,7 @@ static void pa_log(const char* fmt, va_l char log_spec[MAX_STRING + 12 /* '/parser3.log' */]; pa_strncpy(log_spec, filespec_4log, MAX_STRING); - if(char *log_dir_pos=dir_pos(log_spec)){ + if(char* log_dir_pos=dir_pos(log_spec)){ strcpy(log_dir_pos, "/parser3.log"); } else { // no path, just filename @@ -175,7 +174,7 @@ const char* const *SAPI::Env::get(SAPI_I return info.get_env(); } -size_t SAPI::read_post(SAPI_Info& info, char *buf, size_t max_bytes) { +size_t SAPI::read_post(SAPI_Info& info, char* buf, size_t max_bytes) { return info.read_post(buf, max_bytes); } @@ -191,8 +190,8 @@ size_t SAPI::send_body(SAPI_Info& info, return info.send_body(buf, size); } -static const char *full_disk_path(const char* file_name = "") { - char *result; +static const char* full_disk_path(const char* file_name = "") { + char* result; if(file_name[0]=='/' #ifdef WIN32 || file_name[0] && file_name[1]==':' @@ -229,19 +228,28 @@ static void SIGPIPE_handler(int /*sig*/) #endif // requires pa_thread_request() in entry_exists() under Windows -static const char *locate_config(const char *config_filespec_option, const char *executable_path){ +static const char* locate_config(const char* config_filespec_option, const char* executable_path){ filespec_4log=config_filespec_option; if(!filespec_4log) filespec_4log=getenv(PARSER_CONFIG_ENV_NAME); if(!filespec_4log) filespec_4log=getenv(REDIRECT_PREFIX PARSER_CONFIG_ENV_NAME); if(!filespec_4log){ - // next to the executable - const char *exec_dir_pos = dir_pos(executable_path); - filespec_4log = exec_dir_pos ? pa_strcat(pa_strdup(executable_path, exec_dir_pos - executable_path), "/" AUTO_FILE_NAME) : full_disk_path(AUTO_FILE_NAME); - if(entry_exists(filespec_4log)) - return filespec_4log; + const char* exec_dir_pos = dir_pos(executable_path); +#ifdef SYSTEM_CONFIG_FILE + if(exec_dir_pos){ +#endif + // next to the executable + if(!exec_dir_pos || (exec_dir_pos==executable_path+1 && *executable_path=='.')){ + // when just parser3 or ./parser3 full path should be used to avoid "parser already configured" + filespec_4log=full_disk_path(AUTO_FILE_NAME); + } else { + filespec_4log=pa_strcat(pa_strdup(executable_path, exec_dir_pos - executable_path), "/" AUTO_FILE_NAME); + } + if(entry_exists(filespec_4log)) + return filespec_4log; #ifdef SYSTEM_CONFIG_FILE + } if(entry_exists(SYSTEM_CONFIG_FILE)){ filespec_4log=NULL; return SYSTEM_CONFIG_FILE; @@ -253,7 +261,7 @@ static const char *locate_config(const c } #ifdef WIN32 -const char* maybe_reconstruct_IIS_status_in_qs(const char* original) { +static const char* maybe_reconstruct_IIS_status_in_qs(const char* original) { // 404;http://servername/page[?param=value...] // ';' should be urlencoded by HTTP standard, so we shouldn't get it from browser // and can consider that as an indication that this is IIS way to report errors @@ -285,9 +293,20 @@ const char* maybe_reconstruct_IIS_status return original; } +static const char* maybe_back_slashes_to_slashes(const char* original){ + char *result=pa_strdup(original); + back_slashes_to_slashes(result); + return result; +} + #define MAYBE_RECONSTRUCT_IIS_STATUS_IN_QS(s) maybe_reconstruct_IIS_status_in_qs(s) +#define MAYBE_BACK_SLASHES_TO_SLASHES(s) maybe_back_slashes_to_slashes(s) + #else + #define MAYBE_RECONSTRUCT_IIS_STATUS_IN_QS(s) s +#define MAYBE_BACK_SLASHES_TO_SLASHES(s) s + #endif class RequestController { @@ -355,7 +374,7 @@ static void connection_handler(SAPI_Info r.core(config_filespec, strcasecmp(request_info.method, "HEAD")==0, main_method_name, &httpd_class_name); } catch(const Exception& e) { // exception in connection handling or unhandled exception SAPI::log(info, "%s", e.comment()); - const char *status = info.exception_http_status(e.type()); + const char* status = info.exception_http_status(e.type()); if(*status){ info.clear_response_headers(); SAPI::send_error(info, e.comment(), status); @@ -459,8 +478,6 @@ static void real_parser_handler(bool cgi if(!filespec_to_process) SAPI::die("Parser/%s", PARSER_VERSION); - char document_root_buf[MAX_STRING]; - // global request info Request_info request_info; RequestInfoController ric(&request_info); @@ -604,7 +621,7 @@ int main(int argc, char *argv[]) { log("main: entry"); #endif - parser3_filespec = argc && argv[0] ? argv[0] : "parser3"; + parser3_filespec = argc && argv[0] ? MAYBE_BACK_SLASHES_TO_SLASHES(argv[0]) : "parser3"; umask(2); // were we started as CGI? @@ -615,14 +632,14 @@ int main(int argc, char *argv[]) { signal(SIGPIPE, SIGPIPE_handler); #endif - char *raw_filespec_to_process = NULL; + char* raw_filespec_to_process = NULL; if(cgi) { raw_filespec_to_process=getenv("PATH_TRANSLATED"); argv_extra=argv + 1; } else { int optind=1; while(optind < argc){ - char *carg = argv[optind]; + char* carg = argv[optind]; if(carg[0] != '-') break;