--- parser3/src/classes/file.C 2006/10/31 17:16:10 1.145 +++ parser3/src/classes/file.C 2006/11/14 17:26:00 1.147 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_FILE_C="$Date: 2006/10/31 17:16:10 $"; +static const char * const IDENT_FILE_C="$Date: 2006/11/14 17:26:00 $"; #include "pa_config_includes.h" @@ -25,6 +25,7 @@ static const char * const IDENT_FILE_C=" #include "pa_charset.h" #include "pa_charsets.h" #include "pa_sql_connection.h" +#include "pa_md5.h" // defines @@ -811,37 +812,120 @@ static void _base64(Request& r, MethodPa } } +static void _crc32(Request& r, MethodParams& params) { + unsigned long crc32 = 0; + if(&r.get_self() == file_class) { + // ^file:crc32[file-name] + if(params.count()) { + const String& file_spec=params.as_string(0, "file name must be string"); + crc32=pa_crc32(r.absolute(file_spec)); + } else { + throw Exception("parser.runtime", + 0, + "file name must be defined"); + } + } else { + // ^file.crc32[] + VFile& self=GET_SELF(r, VFile); + crc32=pa_crc32(self.value_ptr(), self.value_size()); + } + r.write_no_lang(*new VInt(crc32)); +} + + +static void file_md5_file_action( + struct stat& finfo, + int f, + const String& , const char* /*fname*/, bool, + void *context) +{ + PA_MD5_CTX& md5context=*static_cast(context); + if(finfo.st_size) { + size_t nCount=0; + do { + unsigned char buffer[FILE_BUFFER_SIZE]; + nCount = read(f, buffer, sizeof(buffer)); + if ( nCount ){ + pa_MD5Update(&md5context, (const unsigned char*)buffer, nCount); + } + } while(nCount); + } +} + +const char* pa_md5(const String& file_spec) +{ + PA_MD5_CTX context; + unsigned char digest[16]; + pa_MD5Init(&context); + file_read_action_under_lock(file_spec, "md5", file_md5_file_action, &context); + pa_MD5Final(digest, &context); + + return hex_string(digest, sizeof(digest), false); +} + +const char* pa_md5(const char *in, size_t in_size) +{ + PA_MD5_CTX context; + unsigned char digest[16]; + pa_MD5Init(&context); + pa_MD5Update(&context, (const unsigned char*)in, in_size); + pa_MD5Final(digest, &context); + + return hex_string(digest, sizeof(digest), false); +} + +static void _md5(Request& r, MethodParams& params) { + const char* md5; + if(&r.get_self() == file_class) { + // ^file:md5[file-name] + if(params.count()) { + const String& file_spec=params.as_string(0, "file name must be string"); + md5=pa_md5(r.absolute(file_spec)); + } else { + throw Exception("parser.runtime", + 0, + "file name must be defined"); + } + } else { + // ^file.md5[] + VFile& self=GET_SELF(r, VFile); + md5=pa_md5(self.value_ptr(), self.value_size()); + + } + r.write_no_lang(*new String(md5)); +} + // constructor MFile::MFile(): Methoded("file") { - // ^create[text;user-name;string] - // ^create[binary;user-name;SOMEDAY SOMETHING] + // ^file::create[text;user-name;string] + // ^file::create[binary;user-name;SOMEDAY SOMETHING] add_native_method("create", Method::CT_DYNAMIC, _create, 3, 3); - // ^save[mode;file-name] + // ^file.save[mode;file-name] add_native_method("save", Method::CT_DYNAMIC, _save, 2, 2); - // ^delete[file-name] + // ^file:delete[file-name] add_native_method("delete", Method::CT_STATIC, _delete, 1, 1); - // ^move[from-file-name;to-file-name] + // ^file:move[from-file-name;to-file-name] add_native_method("move", Method::CT_STATIC, _move, 2, 2); - // ^load[mode;disk-name] - // ^load[mode;disk-name;user-name] + // ^file::load[mode;disk-name] + // ^file::load[mode;disk-name;user-name] add_native_method("load", Method::CT_DYNAMIC, _load, 2, 3); - // ^stat[disk-name] + // ^file::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] + // ^file::cgi[file-name] + // ^file::cgi[file-name;env hash] + // ^file::cgi[file-name;env hash;1cmd;2line;3ar;4g;5s] add_native_method("cgi", Method::CT_DYNAMIC, _cgi, 1, 2+50); - // ^exec[file-name] - // ^exec[file-name;env hash] - // ^exec[file-name;env hash;1cmd;2line;3ar;4g;5s] + // ^file::exec[file-name] + // ^file::exec[file-name;env hash] + // ^file::exec[file-name;env hash;1cmd;2line;3ar;4g;5s] add_native_method("exec", Method::CT_DYNAMIC, _exec, 1, 2+50); // ^file:list[path] @@ -851,8 +935,8 @@ MFile::MFile(): Methoded("file") { // ^file:lock[path]{code} add_native_method("lock", Method::CT_STATIC, _lock, 2, 2); - // ^find[file-name] - // ^find[file-name]{when-not-found} + // ^file:find[file-name] + // ^file:find[file-name]{when-not-found} add_native_method("find", Method::CT_STATIC, _find, 1, 2); // ^file:dirname[/a/some.tar.gz]=/a @@ -873,7 +957,16 @@ MFile::MFile(): Methoded("file") { // ^file::sql[[alt_name]]{} add_native_method("sql", Method::CT_DYNAMIC, _sql, 1, 2); - // ^file.base64[] << encode // ^file::base64[string] << decode + // ^file.base64[] << encode add_native_method("base64", Method::CT_DYNAMIC, _base64, 0, 1); + + // ^file.crc32[] + // ^file:crc32[file-name] + add_native_method("crc32", Method::CT_ANY, _crc32, 0, 1); + + // ^file.md5[] + // ^file:md5[file-name] + add_native_method("md5", Method::CT_ANY, _md5, 0, 1); + }