RIP plugins
Bats- I went back to working on a plugin for my favorite email client, and it is with some sadness that I must announce that plugin development is no longer possible for TB. The published API is now long out of date. API version 1.7 is what's available for download, the the publish date on that is from 2005. The sample code available for download on the ritlabs website is, to my astonishment, a working code stub I wrote some four years ago. It, of course, no longer compiles correctly with Visual Studio 2005. Nor with Bloodshed Dev C++. I made the proper adjustments to allow it to compile, but it no longer works with TB 3.98, quitting the client after calling NeedConfig(). It does work properly with TB 2.12, but it seems rather pointless to develop new plugins for a version no longer in development. Ritlabs: if you're listening here, I would appreciate your pulling my sample code from your website - it reflects badly on me to have sample code that doesn't compile, and when modified to compile doesn't run. -- -Mark Wieder http://www.silverstones.com/thebat/TBUDLInfo.html
Re: RIP plugins
Maxim- Thursday, April 19, 2007, 9:03:19 PM, you wrote: What sample C++ code are you speaking about? Could you please specify? This one: http://www.ritlabs.com/kb/attachment.php?id=3 from http://www.ritlabs.com/kb/idx/0/060/article/ (the MyMacros link doesn't work any more either)... -- -Mark Wieder http://www.silverstones.com/thebat/TBUDLInfo.html
Re: How to send copies
Julian- Wednesday, June 21, 2006, 4:00:51 AM, you wrote: The bad news is that I still can't get The Bat to send copies. A sample output line is: OK - now I had to go and try it for myself. Yep - I can confirm here that %CC doesn't work in the command line. On rereading the help file, my take is that the TO argument specifies one and only one main recipient of the email. The %CC macro is specified to work in a template, as are the other addressee macros. So I would think there are three ways around this, depending on how you're extracting email addresses from the database: the first (if this is really CC you want and not BCC) is to put both emails into the TO argument and separate them by commas. This way does work for me. The second is to make the TO and CC addresses into two separate emails, and the third is to use a template file (the T command) and fiddle with it until you've got something that works with your command line. I'm not really convinced you can pass command line arguments to a template file, so that last one may not work after all. I only need to do this very occasionally - it's always the oddballs that cause the problems.. Ain't it always the case? Us oddballs get no respect these days... Any other suggestions? Regards, Julian Hall prompt popping up and interfering with the data reading, I was opening The Bat first and then creating 'thebat.ipc' from a copy in a Notepad file. However, after saving the Notepad Untitled file as 'thebat.ipc', one needs to leave it open until The Bat has read its contents. Closing Notepad This sounds a bit dangerous to me. I test it by creating and editing the ipc file with a text editor, but not in the tb directory. Then when I've got the text file the way I want it, I copy it into the tb directory and wait for it to be gobbled up. Otherwise, yes, what you're seeing is indeed the opposite of what I would have expected. Windows is full of surprises. -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 4 ...and BTW, before someone jumps on you about this, standard etiquette here on the tb lists is for the first line in your sig to be a cut delimiter of dashdashspacecarriage return so that things get truncated when you reply. http://www.silverstones.com/thebat/TBUDLInfo.html
Re: Access violations
Julian- Wednesday, June 21, 2006, 10:53:31 AM, you wrote: It then reads in some, but not all, of the outgoing messages. The number it reads varies widely, even with the same batch file. I'm emptying the Out and Trash folders each time, but it doesn't help. Results are also unpredictable using 'thebat.ipc' instead of the Run command line. The most puzzling aspect is why it should sometimes work and sometimes (nearly always) not with the same batch file. Don't know about the Access Violations, but here are some WAGs: you're getting a varied amount of messages because of the error - at some point along the way when the error is hit the processing of commands in the batch file stops and you don't get any more. It looks like a timing thing to me: you're trying to stuff one more batch command when tb isn't quite done processing the previous one, and the message threading gets messed up. I don't know how much you're trying to put into that batch file, but possibly cutting its size down and running this in multiple passes would help. -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 4 http://www.silverstones.com/thebat/TBUDLInfo.html
Re: How to send copies
Julian- Hooray! This list is still active! Tuesday, June 20, 2006, 6:19:51 AM, you wrote: although I must say I find the Help menu a bit confusing. Indeed. They are all basically of this type, with several minor variations. It works fine, except for one person to whom I need to send a copy on an alternative email address. In this case, I tried: /MAILU=Julian - Appeals Worldwide;TO=Janis Knox[EMAIL PROTECTED];%CC=Janis Knox[EMAIL PROTECTED];S=AI Case Details;TEXT=C:\CSERVE\WWA.TXT;QUEUE Try leaving off the semicolon before the %CC. You'll want it to be a macro within the TO line, rather than a separate command. Does your command line actually work in other cases? A couple of things here: I think you'll need quotes around the arguments that have embedded spaces. The safest thing is just to quote all the arguments and then you don't have to think about it any more. Unless you have quotes within the arguments, which probably isn't a good idea, but then you have to use single quotes to enclose them. The second thing is that I believe you'll need the %put macro to attach the WWA.TXT file: TEXT=%PUTC:\CSERVE\WWA.TXT, otherwise you'll just end up with the file path as your message text. The ipc file is checked regularly, IIRC, so it's not a problem having TB running already. If necessary you can attempt to launch a second copy of TB and it *should* pass the ipc file to the running copy. -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 4 http://www.silverstones.com/thebat/TBUDLInfo.html
Re: Plugin stub (API draft compliant)
Alexey- Thursday, September 11, 2003, 10:33:38 AM, you wrote: ANV ,- [ TBPlugin.cpp (around Util1.h ] ANV | #ifndef _MSC_VER ANV | #include Unit1.h ANV | #endif ANV `- Oops. I meant to remove the Unit1 reference before posting... ANV So, it became compilable, but still doesn't work, because it still use name ANV decorations which is totally unsupported by The Bat!, unfortunately... So, the ANV TBP_ExecMacro became [EMAIL PROTECTED] and etc. ANV The only way still to use .def file... Then that's a failure of my TBP_EXPORT macro for Visual C++. The object in defining that macro was so the .def file was not necessary - it works that way in both Borland and Metrowerks compilers. There must be some combination of compiler directives in VC++ that will produce the proper name mangling, i.e., give TBP_ExecMacro instead of [EMAIL PROTECTED] -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 2 http://www.silverstones.com/thebat/TBUDLInfo.html
Re: The Bat! Common Plug-in API v1.0
Stefan- I see a few template object indexes which have disappeared from the code stub you posted a while ago. I'm assuming these are gone for a reason, and not just an oversight. Their numeric values have not been subsumed by other indexes. In particular, tpxAttachVCard tpxSingleRe tpxCookieCount tpxRegExpText -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 2 http://www.silverstones.com/thebat/TBUDLInfo.html
Plugin stub (API draft compliant)
Here's the revised edition of my plugin stub, hopefully conforming to the draft API document. Alexey - could you (or anyone else) please try this under Visual C++? I've got it working under the other two compilers and I *think* I've got the VC stuff formatted properly, but I don't have that compiler at hand. If that's working then this now compiles with Metrowerks Codewarrior, Borland C++ Builder, and Visual C++. -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 2 TBPluginStub.zip Description: Zip compressed data http://www.silverstones.com/thebat/TBUDLInfo.html
Re: The Bat! Anti-virus plug-in API
Stefan- Maybe I'm being more dense than normal today, but I'm having trouble understanding the AVC_NotSupported return value. Does this imply that *all* the functions must at least have dummy code that returns a value of AVC_NotSupported? What is the difference in, for example, BAV_StreamChecking() returning AVC_Error vs AVC_NotSupported? My understanding is that I should return AVC_OK if my plugin supports stream checking. If my plugin does not support stream checking then I should return AVC_Error. When would I *ever* want to return a value of AVC_NotSupported? Secondly, the Msg argument to BAV_CheckMemory(), BAV_CureMemory(), BAV_CheckFile(), BAV_CureFile, BAV_CheckStream(), and BAV_CureStream() is specified as never being allowed to exceed 1024 bytes - why is this? Not that I would expect to exceed this value, but I'm worried that there's a buffer in TB itself that would overflow if I passed, say, 4096 bytes as a result. What happens if the message is malformed, ie, not null-terminated? Will this cause TB to crash? The documentation states that for these functions Usually AV software returns a distinguished name of the virus of the message. What does usually mean in this case? What does TB do with the returned string? If I return a string of Please reformat your C: drive immediately will this be displayed verbatim to the user? Lastly (at least for now) what is the difference in the BAV_Curexxx functions between AVC_CantBeCured, AVC_VirusFound, and AVC_Error? If an object is infected with a virus but could not be cured, which of these codes should I return? What is the difference in the way TB processes the result codes? -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 2 BTW - many thanks for the API documentation. I'm looking forward to similar documentation for the macro and anti-spam APIs, but this has already cleared up some details for me such as the return values and the BAV_ComNeeded() function. http://www.silverstones.com/thebat/TBUDLInfo.html
Re: TBP_GetSpamScore do not really work?
Alexey- Thanks for pointing out the critical section stuff. I wasn't aware that TB! would thread its calls asynchronously that way. -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 2 http://www.silverstones.com/thebat/TBUDLInfo.html
Re: Plugin Sample in C++ - IMPORTANT! SERIOUS ERROR!
Alexey- Thanks. Good points. (Mark sheepishly says) No, I didn't test under VC++, I just trusted the code you posted earlier and extrapolated from there. I'll look at changing the header and repost it. This is the first time I've worked at including the macro API and I have to say I find it pretty ugly. One thing I'd like to see is a COM-type query function that would enumerate the macro strings rather than making me catenate them at design time. And Stefan's lack of comments makes TBP_ExecMacro a bit of a joke as example code. Also, tpxTotalPages and tpxTracking both evaluate to 248 and tpxCurrentPage and tpxQuoteStyle both evaluate to 249. This can't possibly be right, can it? ANV This is main and critically serious error. Please, refer to ANV other variants of API (which I ANV referred on the top of the letter) and work more... I warn you about it because ANV giving the wrong headers from the beginning can prefer many from writing such ANV plugins. Again, a very good point. ANV 1. Strictly speaking, the interface is defined as struct. (there is line in the ANV header: #define interface struct. So, I would change your code by using word ANV struct if interface is undefined, and also public: is not necessary in ANV this case. But, repeat, this is only cosmetic. Well, I could have sworn that, strictly speaking, functions were illegal as struct members. However, that syntax seems to pass my compilers without problem, so I have now changed it. Yes, it *is* just cosmetic, but I wouldn't have made it a class if I thought I could have gotten away with a struct. ANV 2. If you write on CPP, why are you using malloc and free? Let use new and ANV delete instead! CPP is not C, and although malloc and free still works, they are ANV deprecated in CPP. Of course, this is also just cosmetic, and somebody who will ANV use it will change it, but anywhere... The main reason that malloc and free are deprecated is that their usage can result in sloppy code that causes memory leaks. I've tried to be very careful to free anything that was allocated and the one case in which a memory block is not explicitly freed is notated in the source (as it is in your source as well). Note that new without a corresponding delete will cause the same memory leak as malloc without a corresponding free. My intention here is 1) to cut down the size of the code and increase execution speed by not instantiating new objects unless absolutely necessary, and 2) to minimize the chances of creating a problem interfacing with Delphi with name mangling and such, since this is a shared library and not a standalone application. Obviously both approaches will work. My idea here was to write as much simple C, not C++, code as possible to minimize the chances of having to modify the code for other compilers (i.e. not using vcl or MFC objects). This is the same reasoning as above in using a struct instead of a class. -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 2 http://www.silverstones.com/thebat/TBUDLInfo.html
Re: Plugin Sample in C++ - IMPORTANT! SERIOUS ERROR!
Alexey- Wednesday, August 20, 2003, 1:18:31 AM, you wrote: ANV | virtual int TBP_EXPORT GetDataByID(int ID, void* B, int BSize) = 0; Making the member functions abstract won't hurt, but I think they will only help debug TB itself, since instantiation isn't done within the DLL. Nonetheless, it seems like good practice here. MW My intention here is 1) to cut down the size of the code and increase MW execution speed by not instantiating new objects unless absolutely MW necessary, and 2) to minimize the chances of creating a problem MW interfacing with Delphi with name mangling and such, since this is a MW shared library and not a standalone application. Obviously both MW approaches will work. ANV Well. I agree with you at this point. My intention is to make most faithful ANV translation from Delphi to CPP, and also to keep the things which is may be not ANV so necessary, but just make more comfort. By this reason, for example, I leave ANV the absolute definitions of enum's members, like: ANV ,- ANV | enum midx { ANV | midxSubject = 1, ANV | midxDate= 2, ANV | midxComment = 3, ANV | midxInReplyTo = 4, ANV | midxMessageID = 5, ANV | midxNewsgroups = 6, ANV `- The only problem here is what happens when ritlabs decides to redo things and insert, for example, midxMessageNumber in between midxMessageID and midxNewsgroups. If you have things hardcoded you will need to renumber everything past entry six. If you just declare the first then you simply insert a line in your source. ANV This is well if there is no Interface definition, because it seems to be pure ANV C++. I more intent in this case to use more code on ISO C++. It has nothing with ANV vcl or mfc - just standard C++ library. For example, if I use CString - woe to ANV me if compiler can't hold it! But if I use std::string - woe to compiler who ANV can't compile it! grin Actually, given struct xyz : public IUnknown { } the line between struct and class is getting very blurred... There's another anomaly in my source: I typedef'd PChar as char* instead of unsigned char* because Codewarrior complained if I didn't explicitly cast the result. It seemed easier just to say char and hope there weren't any repercussions down the line. -- -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 2 http://www.silverstones.com/thebat/TBUDLInfo.html
Plugin Sample in C++
Bats- Here's some plugin sample code that should serve as a starting point for coding in C++. It's working now in Visual C++, Borland C++ Builder 6.0, and Metrowerks Codewarrior 8.0. The compiler-specific parts are at the beginnings of both files. There are two source files in the zip file here, a .h header file and a .cpp stub file. I've also included a project file for C++ Builder. The sample compiles to a plugin DLL that just notifies the user when functions are called. The messagebox calls should be replaced by actual code where appropriate. Note that if you're just implementing spam filters you don't need the macro functions. Likewise if you're writing a plugin that just handles macros you don't need to implement the spam functions. The project options should be set to compile a DLL with an extension of .tbp. You should also make sure that the runtime libraries are bundled with the DLL for distribution. I don't have the gcc compiler (or any other) installed at the moment, so someone else will have to take on that conversion. There's actually very little that's compiler-specific here - it's mostly a matter of getting the TBP_EXPORT macro right. -- -Mark Wieder [EMAIL PROTECTED] Stefan- Some documentation, especially about ITBPDataProvider, would be great... TBPluginStub.zip Description: Zip compressed data http://www.silverstones.com/thebat/TBUDLInfo.html
Re: Plugin Specs?
All- Here's a reply I sent to Bill directly. I had posted this to the list earlier on, but maybe it's time to send it up again. Saturday, August 2, 2003, 8:04:55 PM, you wrote: BM I would like to write DLLs in MinGW32 GCC C. Does anyone have a BM simple example? Here's a stub I wrote using Borland C++ Builder, but it's pretty straightforward C code. You might have to mess with the TBP_EXPORT #define, but I think that should do it. Note that the only API Stefan has published is for spam filtering. If you want to do more, there's nothing available. At least yet. Stefan has promised support for user-defined macros and such, but so far there hasn't been any API or samples. -Mark Wieder [EMAIL PROTECTED] Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 2 -- TBBCCBSpamSample.zip Description: Zip compressed data http://www.silverstones.com/thebat/TBUDLInfo.html
Re: Baesyan filter - WORKING test pre-release
Alexey- I originally had struggled with the name decoration problem, too. I finally solved it by creating a new project, importing my source files, and changing the RTL setting. I think the original project file had gotten corrupted or was somehow keeping some decoration settings that I couldn't change. After moving to a new project file everything has been working. I don't quite know why your DLL has gotten so large, though. I'm well under 200k with no optimization. -Mark Wieder Using The Bat! v1.63 Beta/7 on Windows 2000 5.0 Build 2195 Service Pack 2 -- Current version is 1.62 | Using TBDEV information: http://www.silverstones.com/thebat/TBUDLInfo.html
Re[2]: TBP API - need help!
Petr- Thursday, February 13, 2003, 4:59:33 PM, you wrote: PP As I stated, my comments are based on the AV API. And excellent educated guesses, too. It's actually the other way around... return 0 if there's no configuration option, return non-zero if you *do* provide one. PP If is it so, than the TBP API is different. This is the one case where the boolean return value makes sense to me - return a zero (false) if you don't support a configuration option, return a nonzero (true) if you do. PP Very old bug. Don't hold your breath. :) sigh Actually, I'd be satisfied if TBP_NeedConfig() would just enable the Configure button... PP Anyway, a lack of proper documentation of API is a pet peeve of mine. Or, in this case, a lack of *any* real documentation. Stefan - I take it that the API we're working with here is also going to be valid when the fabled 2.0 release finally rears its head? -Mark Wieder Using The Bat! v1.63 Beta/4 on Windows 2000 5.0 Build 2195 Service Pack 2 -- Current version is 1.62 | Using TBDEV information: http://www.silverstones.com/thebat/TBUDLInfo.html
Re: example caught spam...
tracer- Anything that shows up in my inbox with text like: ...We have contacted you with news about blah Corporation because we thought that the contents of this message would be valuable to you. If you do not wish to receive future newsletters from blah, please click on the link below:... I would be happy to treat as spam. It has many other features of typical spam: superfluous exclamation points, ALL CAPS, PR hyperbole, etc. I can see where you might want to read this one rather than tossing it blindly, but this just makes the case for throwing spam-filtered messages into a folder rather than deleting them sight unseen. What I'd really like for this one is an autoreply that informs the sender that some people really need to learn how to write better press releases... g -Mark Wieder Using The Bat! v1.63 Beta/4 on Windows 2000 5.0 Build 2195 Service Pack 2 -- Current version is 1.62 | Using TBDEV information: http://www.silverstones.com/thebat/TBUDLInfo.html
Re[2]: NetPlug 0.2.0000
t Again: is this plugin working AFTER or before filtering Now THAT's an interesting question. When *does* the anti-spam plugin get called? Stefan? -Mark Wieder Using The Bat! v1.63 Beta/4 on Windows 2000 5.0 Build 2195 Service Pack 2 -- Current version is 1.62 | Using TBDEV information: http://www.silverstones.com/thebat/TBUDLInfo.html
TBP_NeedConfig() and TBP_Setup()
Bats- I fear there's something I'm not missing here - can someone help me out with this? My understanding is the following: TBP_NeedConfig() determines whether or not there is a configuration process to the plugin: returning zero indicates there is not, returning one indicates there is. If TBP_NeedConfig returned a one, then the configuration procedure is contained in TBP_Setup() and will be called when something needs to be configured. TBP_Setup() should return a zero if nothing was changed, or one if something in the configuration did change. What I am finding instead is that if I return a one from TBP_NeedConfig() then TBP_Setup() is called immediately as part of the process of loading the plugin. If TBP_Setup() returns a zero then all is well and the rest of the loading process continues... except that Configure button is never enabled. If, however, I return a one from TBP_Setup() during the plugin load process then the load is aborted (a DLL_PROCESS_DETACH message is issued to the plugin), and the plugin never gets to the TBP_GetName() process. -Mark Wieder Using The Bat! v1.63 Beta/4 on Windows 2000 5.0 Build 2195 Service Pack 2 -- Current version is 1.62 | Using TBDEV information: http://www.silverstones.com/thebat/TBUDLInfo.html
TBP_Initialize()
Stefan- Actually, TBP_Initialize() is called right after the DLL_PROCESS_ATTACH message gets processed, which could allow the user to set things up if necessary. And TBP_Finalize() gets called right after the DLL_PROCESS_ATTACH messages gets processed on deleting the plugin. I have both of them defined as do-nothing stubs right now, just because you never know when you might need something like that. It's true that these things could be handled in a DLLMain() function, but it's nice to have another option as well. Saturday, January 18, 2003, 6:03:26 PM, you wrote: ST Well, they are called when the plugin is loaded/unloaded. If you do ST everything at the DLL entry, you simple should not implement them - ST their absence is not critical. -Mark Wieder Using The Bat! v1.63 Beta/4 on Windows 2000 5.0 Build 2195 Service Pack 2 -- Current version is 1.62 | Using TBDEV information: http://www.silverstones.com/thebat/TBUDLInfo.html
TBP_GetName() etc.
Bats- And now that I have things working, I have to question the logic of calling things like TBP_GetName() or TBP_GetVersion() twice. Why not just call it once, see if the return value is zero, and process it if not? i.e., instead of if (TBP_GetName(NULL, 0) 0) iRet = TBP_GetName(strDest, iSize); else DisplaySomeErrorMessageHereAndExit(); why not just if(0 == TBP_GetName(strDest, iSize)); { DisplaySomeErrorMessageHereAndExit(); } -Mark Wieder Current version is 1.62 | Using TBDEV information: http://www.silverstones.com/thebat/TBUDLInfo.html
Re[4]: TBPtest.dpr
Rob- Friday, January 17, 2003, 9:27:30 PM, you wrote: RR Where is TBP_Initialize defined in the plugin API? I am not using RR such a function. In mingw there is an option RR (--no-export-all-symbols) to prevent exporting all functions. It RR appears that you are exporting more than you should be. Are you RR defining these functions as normal methods or are they members of a RR class? Where is the short coming from? Plugin API? It occurs to me that I'm coming in late to this discussion. Is there an actual published API? The only thing I've seen is Stefan's sample. I found TBP_Initialize() and TBP_Finalize() in Stefan's original dpr code and figured maybe they were significant. I'm explicitly exporting them to see if I can break out of this. The short is an artifact of BCCP's linker. I found a compiler option to get rid of it - the default calling convention was set to C and when I changed it to Pascal things got somewhat better. Even so, I'm still stuck with Addr:004012A0 Ord: 1 (0001h) Name: TBP_Initialize(void) Addr:004012B4 Ord: 2 (0002h) Name: TBP_Finalize(void) Addr:004012C8 Ord: 3 (0003h) Name: TBP_GetName(char*,int) Addr:00401354 Ord: 4 (0004h) Name: TBP_GetVersion(char*,int) Addr:004013CC Ord: 5 (0005h) Name: TBP_GetStatus(void) Addr:004013F0 Ord: 6 (0006h) Name: TBP_NeedConfig(void) Addr:00401414 Ord: 7 (0007h) Name: TBP_NeedCOM(void) Addr:00401438 Ord: 8 (0008h) Name: TBP_Setup(void) Addr:0040145C Ord: 9 (0009h) Name: TBP_GetSpamScore(int,(int,int,char*,int)*,int) I believe now that TB is looking for TBP_GetStatus and it's finding TBP_GetStatus(void) and exiting. I think this is Borland's linker getting in my way... I'll have to play around with the build options some more. -Mark Wieder Using The Bat! v1.61 on Windows 2000 5.0 Build 2195 Service Pack 2 -- Current version is 1.62 | Using TBDEV information: http://www.silverstones.com/thebat/TBUDLInfo.html