Wrapping program with TclApp causes smtp package to stop working properly? - tcl

So I'm getting a strange issue when trying to send an email from my company's local mail server using Tcl. The problem is I've written code that works, but it doesn't work as soon as I wrap it with TclApp. I believe I've included all the necessary packages.
Code:
package require smtp;
package require mime;
package require tls;
set body "Hello World, I am sending an email! Hear me roar.";
#mime info
set token [mime::initialize -canonical text/plain -string $body];
#mail options
set opts {};
#MAIL SERVER + PORT
lappend opts -servers "my_server";
lappend opts -ports 25;
tls::init -tls1 1;
lappend opts -username "someEmail#example.com";
lappend opts -password "somePasswordExample";
#SUBJECT + FROM + TO
lappend opts -header [list "Subject" "This is a test e-mail, beware!!"];
lappend opts -header [list "From" "theFromEmail#example.com"];
lappend opts -header [list "To" "theToEmail#yahoo.com"];
if {[catch {
smtp::sendmessage $token \
{*}$opts \
-queue false \
-atleastone false \
-usetls false \
-debug 1;
mime::finalize $token;
} msg]} {
set out [open "error_log.txt" w];
puts $out $msg;
close $out;
}
puts "Hit enter to continue...";
gets stdin;
exit;
This works when I run it and I successfully get the email sent.
But when I wrap it, it doesn't. Here's the output after wrapping and executing the program:
For whatever reason, wrapping with TclApp makes my program fail to authenticate.
*Update: I've decided to try to wrap the script with Freewrap to see if I get the same problem and amazingly I do not. Script works if not wrapped or if wrapped by Freewrap, but not TclApp; is this a bug in TclApp or am I simply missing something obvious?
It seems that this is an old problem (last post): https://community.activestate.com/forum/wrapping-package-tls151

Investigate whether the wrapped version has the same .dll
dependencies as in the article you linked.
Check in the TCL Wiki to see whether this is a known issue ( TCL
Wiki ).
Are you initializing your environment properly when wrapped ( TCL
App Initialization )?

I've found the solution to my problem and solved it! Hopefully this answer will help anyone else who ran into the same issue.
I contacted ActiveState and they were able to point me in the right direction - this link to a thread on the ActiveState forums goes over a similar issue.
I've decided to run the prefix file I've been using to wrap my programs in TclApp - I am using base-tk8.6-thread-win32-ix86. Running this opens up a console/Tcl interpreter which allowed me to try sourcing my Tcl e-mail script manually and I found that the prefix file/interpreter by itself was completely unaware of the location of any package on my system and that I needed to lappend to the auto_path the location of the packages I wanted. Moreover I found from the thread that the email script I was using required other dependencies I had not wrapped in. Namely sha1, SASL, and otp among their own dependencies. When I got these dependencies my script worked through the base-tk8.6-thread-win32-ix86 interpreter and subsequantly through my wrapped program.
Another clue that these dependencies were necessary after doing some research was that my script would give me a 530: 5.5.1 Authentication Required. I later learned SASL fixed this - but I don't know anything about networking so I wouldn't have guessed it.
The other thing I learned was there is a distinct difference between teacup get and teacup install which is why I wasn't installing Tcl packages correctly and TclApp was unaware of SASL, sha1, or otp.
What I don't understand, and perhaps someone with more in depth knowledge about these programs can tell me, how does Wish86 know about a script's package dependencies and know where to find them?? It wasn't until I tried looking for the packages in TclApp that I realized I didn't even have sha1, SASL, etc. on my system nor did I included their package require commands at the top of my script, yet Wish86 could execute my script perfectly. The frustrating thing about this is it is difficult to know whether or not you've met all dependency requirements for systems that don't have a magical Wish86 interpreter that just makes everything work (lol.)
After looking through the end of the thread, I found there is a discussion on the depth TclApp goes to look for hard and soft dependencies in projects.
EDIT: Added more information.

Related

Extracting the outputs/results from an executed .pexe file

My goal is to convert a C++ program in to a .pexe file in order to execute it later on a remote computer. The .pexe file will contain some mathematical formulas or functions to be calculated on a remote computer, so I’ll be basically using the computational power of the remote computer. For all this I’ll be using the nacl_sdk with the Pepper library and I will be grateful if someone could clarify some things for me:
Is it possible to save the outputs of the executed .pexe file on the remote computer in to a file, if it’s possible then how? Which file formats are supported?
Is it possible to send the outputs of the executed .pexe file on the remote computer automatically to the host computer, if it’s possible then how?
Do I have to install anything for that to work on the remote computer?
Any suggestion will be appreciated.
From what I've tried it seems like you can't capture the stuff that your pexe writes to stdout - it just goes to the stdout of the browser (it took me hours to realize that it does go somewhere - I followed a bad tutorial that had me believe the pexes stdout was going to be posted to the javascript side and was wondering why it "did nothing").
I currently work on porting my stuff to .pexe also, and it turned out to be quite simple, but that has to do with the way I write my programs:
I write my (C++) programs such that all code-parts read inputs only from an std::istream object and write their outputs to some std::ostream object. Then I just pass std::cin and std::cout to the top-level call and can use the program interactively in the shell. But then I can easily swap out the top-level call to use an std::ifstream and std::ofstream to use the program for batch-processing (without pipes from cat and redirecting to files, which can be troublesome under some circumstances).
Since I write my programs like that, I can just implement the message handler like
class foo : public pp::Instance {
... ctor, dtor,...
virtual void HandleMessage(const pp::Var& msg) override {
std::stringstream i, o;
i << msg.AsString();
toplevelCall(i,o);
PostMessage(o.str());
}
};
so the data I get from the browser is put into a stringstream, which the rest of the code can use for inputs. It gets another stringstream where the rest of the code can write its outputs to. And then I just send that output back to the browser. (Downside is you have to wait for the program to finish before you get to see the result - you could derive a class from ostream and have the << operator post to the browser directly... nacl should come with a class that does that - I don't know if it actually does...)
On the html/js side, you can then have a textarea and a pre (which I like to call stdin and stdout ;-) ) and a button which posts the content of the textarea to the pexe - And have an eventhandler that writes the messages from the pexe to the pre like this
<embed id='pnacl' type='application/x-pnacl' src='manifest.nmf' width='0' height='0'/>
<textarea id="stdin">Type your input here...</textarea>
<pre id='stdout' width='80' height='25'></pre>
<script>
var pnacl = document.getElementById('pnacl');
var stdout = document.getElementById('stdout');
var stdin = document.getElementById('stdin');
pnacl.addEventListener('message', function(ev){stdout.textContent += ev.data;});
</script>
<button onclick="pnacl.postMessage(stdin.value);">Submit</button>
Congratulations! Your program now runs in the browser!
I am not through with porting my compilers, but it seems like this would even work for stuff that uses flex & bison (you only have to copy FlexLexer.h to the include directory of the pnacl sdk and ignore the warnings about the "register" storage location specifier :-)
Are you using the .pexe in a browser? That's the usual case.
I recommend using nacl_io to emulate POSIX in the browser (also look at file_io. This will allow you to save files locally, retrieve them, in any format you fancy.
To send the output use the browser's usual capabilities such as XMLHttpRequest. You need PNaCl to talk to JavaScript for this, you may want to look at some of the examples.
A regular web server will do, it really depends on what you're doing.

Exit code from powershell script when terminating from subfunction

I have a Powershell script running which calls a function from a dot-sourced .ps1 file.
Inside this function I do an exit 1 which terminates the whole script (as intended).
When I now look at $? and $LASTEXITCODE it says True and 0.
Shouldn't there be False and 1?
Is there anything I don't see?
Example:
main script:
Log-Error -Error "some error" -exit $True
in function.ps1:
Function Log-Finish {
[CmdletBinding()]
Param ([Parameter(Mandatory=$false)][boolean]$Exit)
Process {
" error "
# If $Exit is $true, end calling script
If(($Exit) -or ($Exit -eq $True)) {
Exit 1
}
}
}
You will found an explanation to your "issue" in this post http://blogs.technet.com/b/heyscriptingguy/archive/2011/05/12/powershell-error-handling-and-why-you-should-care.aspx
Also, remember that when external command or script is run, $? will
not always tell you a true story. Let’s see why. Create a script that
has nothing but one line—our favorite error generating command:
Get-Item afilethatdoesntexist.txt
Now run the script and see the output. You will notice that the host
shows you the error. You will also notice that $error contains the
error object that was generated by the command in the script. But $?
Is set to TRUE! Oh, and don’t try this in the order I mentioned
because it will skew the results of $?.
So can you tell me why $? Is set to True? Because your script ran
successfully as far as Windows PowerShell is concerned. Every step in
script was executed—whether it resulted in an error or not. And that
was successful in doing what the script told Windows PowerShell to do.
It doesn’t necessarily mean that the commands within script didn’t
generate any error. See how quickly it gets confusing? And we haven’t
started to go deep yet!

Expect: Can I set a permanent pattern - action pair for multiple expect command

I work with an embedded system which I can access through a serial debug port for debugging. I want to use it's cli interface that can be accessed with telnet localhost in debug console (even before the system is fully up) through expect. The problem is, the cli interface kicks me out at random times with Connection closed by foreign host. near startup (this behavior cannot be changed in the system).
This is the background, my question is that is there any method or trick in expect with which I can set a pattern-action pair permanently for all expect command (in some specific scope)? I would like to setup something like this:
expect "Connection closed by foreign host." { error "cli closed" }
And use this in all the expect command in all my tcl proc that handles cli stuff, then I would call my proc with catch from the main program, and could handle the disconnection. If I can't set this pattern-action pair permanently, I have to include this in all my expect command, which would be really tedious (or use some kind of state instead of multiple expect command, which would be even more tedious..)
Any other idea to work around this is welcome too!
There's an expect_before command: The patterns and actions defined in expect_before are "imported" into every subsequest expect command. So, you want:
expect_before "Connection closed by foreign host." { error "cli closed" }

PackageMaker "Result of Script" requirement never passes

I am trying to use the "Result of Script" Requirement to check if a particular process is running, so that I can message the user before installation begins.
My script is a shell script that returns 1 for failure and 0 for success. The problem I'm having is that, regardless of my return value, the installer flow is interpreting it as failure. I am not using an incredibly simple script:
#!/bin/bash
echo "script starting">> /tmp/myfile
true
(the echo is to assure myself that the script is, in fact, running). I've tried replacing the last line with a lot of things (exit 0, exit 1, "true", "TRUE") but nothing results in the test passing.
I also discovered the following JavaScript code that gets added to distribution.dist when I activate this requirement.
<installation-check script="pm_install_check();"/>
<script>function pm_install_check() {
if(!(system.run('path/to/script/myscript.sh') == true)) {
my.result.title = 'Title';
my.result.message = 'Message';
my.result.type = 'Fatal';
return false;
}
return true;
}
</script>
as far as i can tell, the expression in the if statement will never evaluate to true. So, I'm assuming this is my problem. I don't know how to get around it, though, because this code is generated by PackageMaker.
Update
I've decided to work under the impression that this is a bug in PackageMaker, and am close to a workaround. Rather than using the "Result of Script" requirement, I used the "Result of Javascript" requirement, and built a Javascript function the looks like
function my_check() {
code = system.run('path/to/script/myscript.sh');
return code == 0;
}
Now my only problem is that this will only work when I point to my script via an absolute path. Obviously this poses a problem for an installer.
It's probably too late for you but I feel like this should be documented somewhere.
I'd been looking around for an answer for this for most of this morning. Long story short I ended up looking at generic bash scripting and I found some info about returning values from a script called by a script. Here's how it can be done:
Anywhere you'd be using exit 0 (for success) use $(exit 1).
As you'd expect exit 1 should be replaced by $(exit 0).
I realize that it's backwards and I don't really get the reasoning behind it but after some experimentation that's what I found.
Well, this isn't exactly an answer to the question, but it did end up being a solution to my problem. This freeware packaging utility called Packages supports the "Result of Script" functionality and handles the path correctly. Unfortunately the packages it creates are only compatible with OS 10.5 and later. To support 10.4, I'm building a separate installer using PackageMaker but skipping the "Result of Script" requirement.

Run common TCL script on Windows and Linux

I am new to TCL. How can I run a common tcl script across Windows and Linux? I'd like to check platform type first and then call appropriate tcl proc.
Yup that worked, Jackson. Basically, I wanted to know what OS my script is running on, for example,
set OS [lindex $tcl_platform(os) 0]
if { $OS == "Windows" } {
perform this ...
} else {
perform that ...
}
You can start by looking at the tcl_platform array. On my (windows) machine this reports the following:
% parray tcl_platform
tcl_platform(byteOrder) = littleEndian
tcl_platform(machine) = intel
tcl_platform(os) = Windows NT
tcl_platform(osVersion) = 5.1
tcl_platform(platform) = windows
tcl_platform(threaded) = 1
tcl_platform(tip,268) = 1
tcl_platform(tip,280) = 1
tcl_platform(user) = username
tcl_platform(wordSize) = 4
On a Unix system the os and osVersion will be the values reported by uname -s and uname -r respectivley. If you need something more sophisticated then the platform package may be the way to go!
Most things in Tcl work the same on Windows and Unix; the vast majority of details where there differences are hidden. To handle the rest:
Use file join instead of concatenating with / in between.
Use file nativename to make filenames to hand off to subprocesses.
Be careful with load; what it does is not at all portable.
The info command has some useful things, such as the name of the Tcl interpreter (info nameofexecutable) so you can start up interpreters in subprocesses portably and easily.
Some things just aren't portable (e.g., access to the Windows registry).
There are some subtle differences too, but you'll have to guide us with what you're doing with your program so that we can know what bits matter (e.g., Windows locks executables when they're running while Unix doesn't; sometimes that changes things).