|
|
| version 1.137, 2002/12/05 12:53:48 | version 1.141, 2003/01/16 08:44:19 |
|---|---|
| Line 29 static const char* IDENT_COMMON_C="$Date | Line 29 static const char* IDENT_COMMON_C="$Date |
| # define _O_BINARY 0 | # define _O_BINARY 0 |
| #endif | #endif |
| #ifdef HAVE_FTRUNCATE | |
| # define PA_O_TRUNC 0 | |
| #else | |
| # ifdef _O_TRUNC | |
| # define PA_O_TRUNC _O_TRUNC | |
| # else | |
| # error you must have either ftruncate function or _O_TRUNC bit declared | |
| # endif | |
| #endif | |
| // locking constants | // locking constants |
| #ifdef HAVE_FLOCK | #ifdef HAVE_FLOCK |
| Line 78 static int unlock(int fd) { FLOCK(F_TLOC | Line 88 static int unlock(int fd) { FLOCK(F_TLOC |
| void fix_line_breaks(char* buf, size_t& size) { | void fix_line_breaks(char* buf, size_t& size) { |
| if(size==0) | |
| return; | |
| //_asm int 3; | //_asm int 3; |
| const char* const eob=buf+size; | const char* const eob=buf+size; |
| char* dest=buf; | char* dest=buf; |
| Line 127 static bool set_addr(struct sockaddr_in | Line 140 static bool set_addr(struct sockaddr_in |
| } | } |
| static void http_read_response(String& response, int sock){ | static void http_read_response(String& response, int sock){ |
| bool check_status=true; | |
| ssize_t EOLat=0; | ssize_t EOLat=0; |
| while(true) { | while(true) { |
| char *buf=(char *)response.pool().malloc(MAX_STRING); | char *buf=(char *)response.pool().malloc(MAX_STRING); |
| Line 135 static void http_read_response(String& r | Line 147 static void http_read_response(String& r |
| if(size<=0) | if(size<=0) |
| break; | break; |
| response.APPEND_TAINTED(buf, size, "remote HTTP server response", 0); | response.APPEND_TAINTED(buf, size, "remote HTTP server response", 0); |
| if(check_status && (EOLat=response.pos("\r\n", 2))>=0) { // checking status in first response | |
| check_status=false; | |
| const String& status_line=response.mid(0, (size_t)EOLat); | |
| Array astatus(response.pool()); | |
| size_t pos_after_ref=0; status_line.split(astatus, &pos_after_ref, " ", 1); | |
| const String* status_code=astatus.get_string(1); | |
| if(!status_code || *status_code!="200") | |
| throw Exception("http.status", | |
| status_code, | |
| "invalid HTTP response status"); | |
| } | |
| } | } |
| if(check_status) | |
| throw Exception("http.response", | |
| 0, | |
| "bad response from host - no status found (size=%lu)", response.size()); | |
| } | } |
| /* ********************** request *************************** */ | /* ********************** request *************************** */ |
| Line 333 static void file_read_http(Pool& pool, c | Line 328 static void file_read_http(Pool& pool, c |
| //processing status code | //processing status code |
| const String *status_line=aheaders.get_string(0); | const String *status_line=aheaders.get_string(0); |
| if(!status_line){ | Array astatus(pool); |
| throw Exception("http.response", | pos_after_ref=0; |
| &connect_string, | status_line->split(astatus, &pos_after_ref, " ", 1); |
| "bad response from host - no status line "); | const String *status_code=astatus.get_string(1); |
| } | |
| //processing headers | //processing headers |
| for(int i=1;i<aheaders.size();i++) { | for(int i=1;i<aheaders.size();i++) { |
| if(const String *line=aheaders.get_string(i)) { | if(const String *line=aheaders.get_string(i)) { |
| Line 358 static void file_read_http(Pool& pool, c | Line 353 static void file_read_http(Pool& pool, c |
| // output response | // output response |
| data=body.cstr(); data_size=body.size(); | data=body.cstr(); data_size=body.size(); |
| if(out_fields) | if(out_fields) { |
| headers.put(*file_status_name, new(pool) VString(*status_code)); | |
| *out_fields=&headers; | *out_fields=&headers; |
| } | |
| } | } |
| #ifndef DOXYGEN | #ifndef DOXYGEN |
| Line 457 bool file_read_action_under_lock(Pool& p | Line 454 bool file_read_action_under_lock(Pool& p |
| "stat failed: %s (%d), actual filename '%s'", | "stat failed: %s (%d), actual filename '%s'", |
| strerror(errno), errno, fname); | strerror(errno), errno, fname); |
| #ifdef NO_FOREIGN_GROUP_FILES | #ifdef PA_SAFE_MODE |
| if(finfo.st_gid/*foreign?*/!=getegid()) | if(finfo.st_uid/*foreign?*/!=geteuid() |
| && finfo.st_gid/*foreign?*/!=getegid()) | |
| throw Exception("parser.runtime", | throw Exception("parser.runtime", |
| &file_spec, | &file_spec, |
| "parser reading files of foreign group disabled [recompile parser without --disable-foreign-group-files configure option], actual filename '%s'", | "parser is in safe mode: reading files of foreign group and user disabled [recompile parser with --disable-safe-mode configure option], actual filename '%s'", |
| fname); | fname); |
| #endif | #endif |
| Line 509 bool file_write_action_under_lock( | Line 507 bool file_write_action_under_lock( |
| if((f=open(fname, | if((f=open(fname, |
| O_CREAT|O_RDWR | O_CREAT|O_RDWR |
| |(as_text?_O_TEXT:_O_BINARY) | |(as_text?_O_TEXT:_O_BINARY) |
| |(do_append?O_APPEND:0), 0664))>=0) { | |(do_append?O_APPEND:PA_O_TRUNC), 0664))>=0) { |
| if((do_block?lock_exclusive_blocking(f):lock_exclusive_nonblocking(f))!=0) { | if((do_block?lock_exclusive_blocking(f):lock_exclusive_nonblocking(f))!=0) { |
| Exception e("file.lock", | Exception e("file.lock", |
| &file_spec, | &file_spec, |
| Line 524 bool file_write_action_under_lock( | Line 522 bool file_write_action_under_lock( |
| try { | try { |
| action(f, context); | action(f, context); |
| } catch(...) { | } catch(...) { |
| #ifdef HAVE_FTRUNCATE | |
| if(!do_append) | if(!do_append) |
| ftruncate(f, lseek(f, 0, SEEK_CUR)); // one can not use O_TRUNC, read lower | ftruncate(f, lseek(f, 0, SEEK_CUR)); // one can not use O_TRUNC, read lower |
| #endif | |
| unlock(f);close(f); | unlock(f);close(f); |
| /*re*/throw; | /*re*/throw; |
| } | } |
| #ifdef HAVE_FTRUNCATE | |
| if(!do_append) | if(!do_append) |
| ftruncate(f, lseek(f, 0, SEEK_CUR)); // O_TRUNC truncates even exclusevely write-locked file [thanks to Igor Milyakov <virtan@rotabanner.com> for discovering] | ftruncate(f, lseek(f, 0, SEEK_CUR)); // O_TRUNC truncates even exclusevely write-locked file [thanks to Igor Milyakov <virtan@rotabanner.com> for discovering] |
| #endif | |
| unlock(f);close(f); | unlock(f);close(f); |
| return true; | return true; |
| } else | } else |