go to post Alexey Maslov · Jul 5, 2018 Agree, it's trivial in most cases, except that one, when there is a series of commands depending on previous ones, e.g. (not from the production code))):set rc=$zf(-1,"[ -f /etc/environment ] && . /etc/environment && export TZ")$zf(-1) allows to execute such series at the whole, while $zf(-100) needs to split it into parts, moving checkup logic to COS code. It's trivial as well, but ruins the idea of (semi-)formal substitution of $zf(-1) calls with $zf(-100) ones.
go to post Alexey Maslov · Jul 5, 2018 It seems that the docs is ambiguous here as it's not clear when one can use "" as a <null> value: in comma separated options list only, or in options array as well.As to possible ways to exploit $zf(-1), there is some clue in ISC's announcement. It can be compromised if its arguments come from user input. Similar vulnerabilities are usually associated with dynamic SQL, not only in Caché. Other (Caché specific) samples: Xecute, $Xecute, argument indirection. This stuff is well-known, is it a secret for anybody?It seems that if we never use such coding style, we are safe enough. As to our company's code base, we rarely use $zf(-1), and all its usage is encapsulated in a couple of class methods.We'll follow ISC's security recommendations, as we always do, while I don't feel myself comfortable when I don't understand the reasons of doing something. "Don't repair, if it works", as it was said by some wise man. Does it need any comment?
go to post Alexey Maslov · Jul 5, 2018 Using a comma-delimited list of arguments works fine, even with a null argNull arg is not the same as an empty string arg (""), as usual in COS. Therefore the settings ofset options(1)=""made your first argument an empty string, and the whole command behaved asdir "" e:\nbupg\webserver\Didn't check your *nix version, just noticed that "NUL" should be spelled as "/dev/null".P.S. May I ask you in turn :):Why did you undertake this task, changing of $zf(-1) to $zf(-100), at all? Do you clearly understand the kind of treat you try to eliminate?
go to post Alexey Maslov · Jun 16, 2018 The solution I've found is rather simple than smart: to start a dejournalizer as a JOB with an 'answer file' specified as a principal-input device. The code prototype looks like this: set fin=$zu(12)_"Temp\fin.txt" set fout=$zu(12)_"Temp\fout.txt" open fin:("NW"):1 if '$t {write "not opened!",! quit} use fin write "N",!,"N",!,"Y",! close fin job jrnrest^ztestFF("20180614.006"):(::fin:fout):1 if '$t { w "not started!" q} Its execution resulted in "fout.txt" file like this: 20180614.006 to 20180614.006; c:\intersystems\cache\mgr\user\ => c:\intersystems\cache\mgr\test\ Do you want to rename your journal filter? o Do you want to delete your journal filter? o c:\intersystems\cache\mgr\journal\20180614.006 8.88% 14.29% 15.26% 16.79% 18.08% 19.31% 20.35% 21.32% .... ***Journal file finished at 16:39:36 Do you want to rename your journal filter? es Journal filter ZJRNFILT renamed to XJRNFILT [journal operation completed] "o" and "es" were provided by the auto-completion of "N" and "Y" answers. Cons of this approach is that ISC can change the ^JRNRESTO dialog in some future version.Pros: no need in reverse engineering of ^JRNREST stuff to derive a non-interactive journal restore utility. Hope my writing will be useful for somebody besides myself. Happy coding!
go to post Alexey Maslov · May 28, 2018 As a remedy, you can process compilation in a separated job, something like this:- Create environment { }- JOB ImportAndCompileStuff- Wait for the job completion- Destroy environment { }
go to post Alexey Maslov · May 8, 2018 Thank you, Dima.Could I reproduce, I'd call WRC.Ther were some errors stipulated by the fact that the class was not compiled. Posting them in another comment.
go to post Alexey Maslov · May 7, 2018 Hi Joan,It seems that the right way to perform this task would be using MemberStatusList query of the class SYS.Mirror. See Documatic for details.HTH.
go to post Alexey Maslov · Mar 15, 2018 C:\Users\%USERNAME%\AppData\Local\Application Data\Temp\InterSystems\
go to post Alexey Maslov · Mar 13, 2018 It seems that you are to write a couple of lines anyway, because nobody will do it but yourself. As you certainly know, it's possible to do it using shell scripting without going inside Caché, e.g.: #!/bin/sh csession cacheuc1 << EOF write ##class(%SYSTEM.Version).GetVersion(),! halt EOF
go to post Alexey Maslov · Dec 6, 2017 Just 2c to add. If a "national" locale is effective, e.g. %SYS>zw ^%SYS("LOCALE","CURRENT") ^%SYS("LOCALE","CURRENT")="yruw" and the setting was done before Caché restart: %SYS>set ^SYS("NLS","Config","LocaleFormat")=1 you will get your national day name if don't forget to set localeopt=0, e.g. USER>f localeopt=0,1 w localeopt," ",$ZD($h,12,,,,,,,,localeopt),! 0 Среда 1 Wednesday It's also possible to achieve the same overriding format defaults for the current process (see $ZDATE description for details). I emphasized the need in Caché restart just because didn't find it in docs.
go to post Alexey Maslov · Nov 30, 2017 Yes, I did.It did not seem working, STOP / START of the System Monitor didn't help.I lost my interest to Callback functionality because of its absence in newer Caché version, so I would not investigate it anymore.
go to post Alexey Maslov · Oct 2, 2017 It all depends.Attempts to connect a port or even to connect a super-server using potentially wrong password spoil Cache Audit with nasty records, so if they are done frequently those records can easilly overfill the Audit.Several years ago I faced the similar problem in opposite direction: how to let load balancer recognize Cache instances which are no longer alive to remove them from its list. Load balancer was to distribute super-server connections as well as web based ones. The idea of polling 1972/tcp was dropped as soon as I recognized its impact on auditting. So I used a web app which allowed unauthenticated access for the simple reason that if 57772/tcp port had reasonably answered, 1972/tcp should be accessible as well. There were no firewall(s) between the load balancer and application servers, therefore I was sure that there were no external "forces" that could prevent them from answering. The solution was deployed on a couple of different load balancers and showed its robustness on a farm of 4-7 application servers and 1000-3000 concurrent users.
go to post Alexey Maslov · Sep 6, 2017 We have a TASKMGR's task that purges such kind of globals daily. (Sub)globals are cleaned using the following criteria:Global has a structure of @name@(PID)Global is listed in predefined "known globals" listCaché process identified with PID is not running.
go to post Alexey Maslov · Jun 16, 2017 Via SSH (putty, etc), am I right that you need to call csession <instance> to enter the Caché terminal? If so, there is no talk about SSH all. Caché has got embedded libssh2.dll/.so ages ago. Why not implement internal SSH server which can be a reasonable replacement for outdated (and Windows only) telnet one? It seems that some other projects (besides Web terminal) would take advantage from it.
go to post Alexey Maslov · Jun 1, 2017 Another option is to use a classmethod %SYS.ProcessQuery::ExamStackByPid().
go to post Alexey Maslov · May 19, 2017 Routines can't be named as "%zu2f%zt" because only the first letter of routine name can be "%". Maybe such "name" occured due to some encoding, having in mind that $char($zhex("2F"))="/"? If so, the original could look like:$$zt^%zu/%ztIf so, a macro can be defined as:#define YourMacro(%yourparam) $$zt^%zu/%yourparam
go to post Alexey Maslov · May 17, 2017 During Cache backup it appears that all the available memory on the server is being used.It's usually not a problem as the more memory is used for buffering the quicker file i/o operates. Only free memory is used for this purpose, so memory allocated by users' or system processes should not be swapped. Please add more details, why it turned to be a problem in your case?PS. Double check in console log whether Cache allocates its shared memory segment using large pages as it guaranties that it is totally allocated at Cache startup and will neither be expanded nor swapped afterwards.
go to post Alexey Maslov · Apr 21, 2017 ... and second thing is to insert a Close command before the correspondent Open, e.g. ..c resfile o resfile:"NWK\CP874\" even if you are quite sure that the file is closed at the moment of opening. The reason is to avoid the cases when your program have failed with error without closing the file, so its open parameters (at least, the translation table setting) keep unchanged despite of subsequent Open command. Such cases often happen during development / debugging, when the error trap code is completely switched off or greatly simplified.
go to post Alexey Maslov · Apr 20, 2017 Eduard, can you explain the main difference between Sagun's method of translation table setting: open file:"RSK\CP874\" and yours in this very case? The latter is a piece of code of %Stream.FileCharacter.cls which actually sets a table: If (table'=0) && (i%CurrFile'="") { Set io=$io Use i%CurrFile $$$SETIO(table) ; -> Do $zutil(96,18,2,table) Use io } It seems that it's some other problem, perhaps a bug. Sagun, if you provide us with a small piece of your code where you open the file, use it, and write it, it would be easier to say something.
go to post Alexey Maslov · Apr 19, 2017 Hello Eduard,Following your 1st link I've failed to find any info on 7-zip usage. It was about Libre Office stuff.No problems with 7-zip for Windows (its native OS), not worth to mention that 7z format compression method(s) of its last versions can be unsupported (and uncompressed) with old ones. If using zip format (even with 7-zip), your are quite safe.p7zip, its Linux branch, which I tried several years ago, performed very poor as it was not multi-threaded (as 7-zip was for years). So we decided to drop it mostly for this reason.One little hint about 7-zip for Windows: we use its 7za.exe build in our deployment and update procedures as it doesn't need installation and can be just dropped in any place before usage.