mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Dec 2002
Posts: 252
T
Talon Offline OP
Fjord artisan
OP Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 252
If you've ever used IRC with linux, you prolly used X-Chat if you were a gui user, or something like irssi, bitchx, weechat, etc.. several linux clients have something to output console commands to the active window, in xchat its /exec and /exec -o.

I'm a die hard mIRC fan and wanted /exec for mIRC so here goes a little perl snippet to make mIRC have exec capabilities.

Perl script goes in $mircdir (which for me is ~/.wine/drive_c/Program Files/mIRC)
make a new file called pexec, chmod it 755 and make its content read as following:
(your bash line for perl may vary but this is generally the right one, you may have it in /usr/local/bin/perl)
Code:
#!/usr/bin/perl
my $cmd = join(" ",@ARGV);
chomp($cmd);
my @exec = `$cmd`; 
open (OUT,">pexec.txt");
print OUT @exec;
close(OUT);


mIRC Code:
Code:
alias exec {
  if ($timer(chkexec)) { .timer -m 1 50 exec $1- }
  else { run $nofile($mircexe) $+ pexec $iif($1 = -o,$2-,$1-) | chkexec $iif($active = status window,-s,$v1) $iif($1 = -o,$1) }
}
alias chkexec {
  if ($exists(pexec.txt)) { var %x = 0 
    while (%x < $lines(pexec.txt)) { inc %x | if ($read(pexec.txt,%x)) { var %out = $v1 | $iif($2 = -o,msg $1,echo $1) %out } }
    .remove pexec.txt
  }
  else { .timerchkexec -m 1 50 chkexec $1- }
}



To Use:
/exec (command here) will echo the output if any.
/exec -o (command here) will /msg to the active window the output if any.

Examples:
/exec uname -r
2.6.32-5-686

/exec cat /etc/issue
Debian GNU/Linux 6.0 \n \l

In a channel:
/exec -o uname -a
[16:58] <Talon> Linux debian 2.6.32-5-686 #1 SMP Wed Jan 12 04:01:41 UTC 2011 i686 GNU/Linux

Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Note that there is already exec.dll which pipes in/out from shell and provides this /exec and $exec command. However I'm not sure if it works in 7.x.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Dec 2002
Posts: 252
T
Talon Offline OP
Fjord artisan
OP Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 252
I downloaded and tested that exec.dll and I could not get it to execute any unix commands with mIRC under wine. Maybe I'm using it wrong? by documentation its /exec <mirc command> <shell command> so i tried /exec echo uname -r but only got that text returned in my active window.

This solution I posted was meant for linux users who emulate mIRC with wine and would like to output the results of unix commands to the active window just like XChat. Thanks for the idea but it seems as if this dll is a windows-only thing.

Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Under wine you need to specify the full path to the unix (or linux) executable you want to execute. I've successfully used this on my install of wine, so I can confirm it is not Windows only. This is probably why /exec ls won't "just work", though, and the dll may seem broken (but is not).

exec.dll initializes cmd.exe to run commands-- this is slightly unlike /run, which uses CreateProcess() directly. This is equivalent to running `wine cmd` to open a cmd.exe shell.

For instance, to run a shell script, you'd need to directly call "\bin\sh" (/bin/sh won't work because of cmd.exe's handling of path separators). You can see this in wine cmd as well.

Anyway, try:

Code:
/exec \bin\sh -c "ps auxww | grep ^`whoami`"


It looks ugly, but you can wrap this up in a clean alias:

Code:
alias wexec exec \bin\sh -c $qt($1-)


And then you can use commands like:

Code:
/wexec ls -la | grep \.exe$


Note that you can also set the %COMSPEC% environment variable in wine to point to some script (and not cmd.exe). exec.dll uses this variable to spawn the process in CreateProcess. You could theoretically set this to a perl or shell script that ran code. You can't use \bin\sh directly because exec.dll passes '/c', not '-c', as an argument before the actual command, so you'd have to write a wrapper script to filter it out. Perhaps it might be wiser to have exec.dll just call CreateProcess with $1- and let the .mrc file insert cmd /c, that way users could more easily modify this for wine systems, but unfortunately I'd need to release a new version for that.

In any case, you can set %COMSPEC% to "/path/to/myscript.sh" (use `winepath` to get this path) with an executable script that looks like:

Code:
#!/bin/sh
shift # remove '/c' argument
$*    # run commands


And you should be able to /exec without modification to aliases.



- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Dec 2002
Posts: 252
T
Talon Offline OP
Fjord artisan
OP Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 252
well thats cool, so that makes two alternate methods.. Personally I chose not to use a dll if I don't need it, but maybe others would opt the dll route even tho it appears a lot more work.

Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
I'm not sure how you're qualifying "a lot more" work. To run exec.dll under wine, you don't even *need* to add an alias, you just need to call the correct command-- this is quite similar to your script prefixing /run commands with a perl script, if not equivalent. The alternate methods (using an env var, adding the alias) are optional-- it's really just:

Code:
/exec \bin\sh -c "COMMAND HERE"


Yours is:

Code:
/run perlscript COMMAND HERE


Of course they're both hidden inside of neat little aliases that also look the same.

To me, creating that alias doesn't seem much more complicated than setting up a perl script (installing, chmodding). But in any case, since your script can't run more than one command at a time, the "extra work" adds a lot more functionality and removes a lot of moving parts like timers, filesystem polling, etc..


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Dec 2002
Posts: 252
T
Talon Offline OP
Fjord artisan
OP Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 252
how do you figure it can't run more than one command? "cat /var/log/Xorg.0.log | grep nVidia" <== grep isn't part of cat, its a seperate command, and does work fine, also, why such the force for a dll when its totally un-necessary?

Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Originally Posted By: Talon
"cat /var/log/Xorg.0.log | grep nVidia" <== grep isn't part of cat, its a seperate command


That is a single "command" in the eyes of your script:

Code:
/exec -o cat /var/log/Xorg.0.log | grep nVidia


I'm not talking about number of executables, I'm talking about number of mIRC commands. Also note that the shell command above runs commands in sequence, not in parallel. My statement was that you cannot run more than one command *at once* (in parallel), not in sequence. For instance:

Code:
//exec -o cat /var/log/Xorg.0.log | /exec -o cat /etc/passwd


With your script, it looks like these two commands will get queued. In exec.dll, they will run simultaneously (replace -o with -a for async calls). This *can* be important functionality.

Also realize that a timer executing in 50ms intervals might seem fast, but if commands finish in <1ms you will be "blocking" for ~49ms. That's a big deal if you're relying on /exec many times in a larger script. A loop from 1-10 would spend half a second idling. That matters even more since for that 49ms you can't execute other commands-- since you have a bottleneck on the pexec.txt file. Again, ~50ms + ~50ms + ~50ms adds up to quite a noticeable delay, really fast. exec.dll reads immediately as data comes in, which will yield much better performance. You can benchmark your script against exec.dll to quantify the difference, if you'd like.

Originally Posted By: Talon
why such the force for a dll when its totally un-necessary?


There is no "force" for a dll. I'm simply pointing out that there are more powerful alternatives than shelling out to a perl script, and that your script has a few efficiency limitations (noted above). In some cases, this efficiency *is* necessary. FWIW there is also an "stdcatch" script written by Collective floating around that implements stdin/out piping (what exec.dll does) without needing a dll (uses COM instead). Not sure if that works in wine, but it might. I'd even recommend using that, if you don't want a DLL.

Let me flip it back on you: why such "force" against a dll?



- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
FYI, I've just released a new version of exec.dll that no longer runs cmd.exe. This simplifies a bunch of the plumbing and improves wine compat. I added a -c and -o switch, so it looks like yours:

Code:
/exec -co ls -la | grep \.exe


Note that -c spawns a cmd shell. You can now edit this, however, to run \bin\sh -c instead. Change line 142. If mIRC ever exposes a way to detect wine, I can autodetect this and switch to \bin\sh automatically, but in the meantime it's not a huge change.

Without -c you could just do:

Code:
/exec \bin\sh -c ls -la | grep \.exe


Again, not that different.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Dec 2002
Posts: 252
T
Talon Offline OP
Fjord artisan
OP Offline
Fjord artisan
T
Joined: Dec 2002
Posts: 252
I didn't say I had anything against dlls, I just prefer not to use them when you don't need them. mSL is a very unique and fun language, I also like to test how far it can be pushed, I've done all kinds of stressful tests like 3D rendering for example just to see what mSL can do and I like sticking purely in the limitations of the scripting engine itself rather than breaking out of its environment and using some com object or dll to do the dirty work.

I love mIRC for what it is, and try to be as creative as possible within the language itself, if I need a dll to do it than I probably don't need to do what i'm doing with mIRC. mIRC is a fun toy and not my primary choice of a coding language, its definately NOT the best tool for all projects but it is a break from the usual and a hobby I quite enjoy.

Sticking to these boundaries also helps me come up with what I feel would be useful feature suggestions. DLL's are frowned upon on a lot of mIRC fan based sites for general addons you'd like to release to the public. Users are also cautious about DLLs and tend to not want to use them without the source, and chose not to even with the source because they themselves don't have the compiler to generate the dll and don't want to chance the "pre-compiled" one included in the package. The source may be legit but the provided one might also be malicious. Some people may also use alternate compilers such as borland, microsoft visual studio, mingw, etc.. theres no garuntee that the structure of a dll written for visual studio may compile in their favorite of borland, so now you have issues of porting from one to the other.

I myself use windows in a virtual environment (where it belongs) and keep a backup of my virtual drive incase of virii or data corruption, etc... for anyone who doesn't use windows as a virtual machine, I'd call you stupid if you blindingly trusted a pre-compiled dll included with the supposed "source" as you're just asking for trouble.

Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
First off, I didn't want this to turn into a debate on the validity of DLLs. We're talking about a very specific DLL here, exec.dll. You're the one turning this into a philosophical debate about mIRC script "purity", but I *will* bite.

Originally Posted By: Talon
I didn't say I had anything against dlls,


According to the rest of your post it certainly sounds like you do have some serious ideological issues with using dlls.

Originally Posted By: Talon
if I need a dll to do it than I probably don't need to do what i'm doing with mIRC.


This is ironic, since you are using Perl to do something because it can't be done in mIRC. exec.dll is an example of a situation where you definitely need the power of a dll to do things that mIRC just isn't designed to do within the scripting language. There are *MANY* such examples, but the "dll-isn't-scripting" debate is old and boring-- and irrelevant. It comes down to this: your script isn't capable of doing what exec.dll is. mIRC [scripting] isn't capable of doing what exec.dll is. I guess according to the above quote, you are saying that you don't need to run 2 or more programs efficiently and simultaneously with mIRC.

Originally Posted By: Talon
DLL's are frowned upon on a lot of mIRC fan based sites for general addons you'd like to release to the public.


This sounds anecdotal to me. In fact, of the popular scripts I know, nearly all of them include (or *are*) dlls. Looking at mircscripts.org shows a healthy number of downloads for every dll, often surpassing downloads for a similar sampling of addons/snippets. In short, the data seems to disprove your statement.

Originally Posted By: Talon
Users are also cautious about DLLs and tend to not want to use them without the source, and chose not to even with the source because they themselves don't have the compiler to generate the dll and don't want to chance the "pre-compiled" one included in the package.


Again, anecdotal. The download counts posted on sites like mircscripts.org prove otherwise-- there is no significant difference in user behaviour. If your statement was accurate, DLLs would see much lower download counts than all other scripts. This is simply not true. Secondly, most script sites require source to be posted and reviewed. If you don't trust the site in question, that's a personal issue that you need to deal with-- it's not a question about DLL safety.

We're talking about exec.dll, though, not "dlls in general". exec.dll publishes the source code; it's in the package that you downloaded. Are you saying that you don't trust *my* source? Are you saying that the dll I've provided is malicious? These are some pretty serious claims, if that's what you're alluding to. If you're talking about dlls in general, well, that's just tangential to this topic.

FYI it's just as easy to write a malicious mIRC script as it is to write a malicious dll. Having the source code is not security. Trusting the people who write the code you're running is the important part. There have been undetected vulnerabilities and even malicious exploits in production level open source code (linux kernel, openbsd, exim, etc.) that have stuck around for years without people seeing them.

Originally Posted By: Talon
I'd call you stupid if you blindingly trusted a pre-compiled dll included with the supposed "source" as you're just asking for trouble.


I guess you're calling every mIRC user, including Khaled, stupid. Somehow I don't think this is true. You're running mIRC without any source code provided. You must be asking for trouble, too. This is such a slippery slope argument. There's a difference between running untrusted code and running code that's been peer reviewed by community members that you know. If we can't agree to that, we have a problem (more likely you have a problem with computing).

Finally:

Originally Posted By: Talon
I myself use windows in a virtual environment


I hope you realize that wine is not a virtual environment. Perhaps you're running wine inside of a VM on your OS-- but if you're just running wine on your host OS, I'm afraid you're deluding yourself into a false sense of security. I noticed you were previously (on IRC) calling wine an "emulator", and it is neither an emulator nor a virtualized environment. Perhaps you are confused about what you're really using?


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
argv0 is right about users trusting DLLs that are included in packages from trusted sources. Invision is one of the more popular "full" scripts out there and has been downloaded by a LOT of people. It includes a DLL that has often been flagged by antivirus software because one time, that DLL was included in a virus. With a little explanation to anyone who asks, people trust that it's not a virus (it isn't) and they use it without a problem. This issues crops up every so often as certain antivirus software adds and removes it from their definition files multiple times. They seem to forget that they removed it for a reason and it gets put back in. If users trust us enough to use it even if their AV software says it is bad, then they are not going to have problems using other DLLs that don't get flagged by AV as long as they trust the source.

It's fine if you don't like DLLs. I tend to avoid them except when necessary as well. But something like exec.dll is going to be so much better than a scripted method that it's worth using it.


Invision Support
#Invision on irc.irchighway.net
Joined: Sep 2006
Posts: 59
R
Babel fish
Offline
Babel fish
R
Joined: Sep 2006
Posts: 59
I have a quick question about this dll, is there anyway to use it asynchronously without a callback? i.e. $exec(-a ipconfig,echo -s )

Would be good if it could do this, if it can already then just ignore this.. Also I've noticed it cannot use commands like ver or dir on windows (I know these are pretty much possible through mIRC anyway)

Last edited by Rewtor; 23/02/11 11:48 AM.
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Rewtor:

You can use ver and dir from exec.dll, but in the new version you have to specify -c. These commands are not "programs", but shell commands of cmd.exe. You can exec them with:

Code:
/exec cmd /c ver


or the new shorthand form for creating a cmd shell:

Code:
/exec -co ver


I removed the forced running of cmd /c for all commands from exec.dll because it was unnecessary and confusing to launch programs within cmd.exe. If you did not need it, you could not opt out. An opt-in system works better, so if you need special shell style support, you can use cmd directly as shown above. This includes commands that have piping (command1 | command2) or shell redirection (command1 > outfile.txt). You would include -c for those. In short, /exec should have the same behaviour as the familiar /run, now, which should make things more intuitive.

In older versions of exec.dll the -c is not necessary. Note that I have a version of the mrc script that removes the need for putting -o with -c, I will update the release with this script soon.

As far as asynchronous identifiers go, this doesn't really make sense in the context of mIRC. An $identifier will by definition return immediately, and cannot be asynchronous-- or at least, any result that $exec would give would be of little use. This is why /exec is recommended. That said, /exec and $exec are just wrappers for /dll and $dll (and $dllcall). If you really need an asynchronous call via identifier, you can write your own alias that uses $dllcall($exec.dll, execA, ...) (you can check the exact syntax in the mrc file). But perhaps you can explain what you're trying to do and I can let you know of a better way to do it.

edit: I've just updated exec.dll to 1.11, and -o is no longer required with -c. You can now just use /exec -c ver. To hide output, use -k noop or /.exec.

Last edited by argv0; 23/02/11 08:45 PM.

- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"

Link Copied to Clipboard