PDA

View Full Version : EXEC Module commands


Yil
10-13-2011, 09:43 PM
!putlog <string>
Output <string> to ioFTPD.log

!vfs:add <fileMode> <UID>:<GID> <filename>
Create or set file mode (permissions) along with owner and group for the indicated file.

!vfs:chattr <num> "<filename>" "<data>"
Create or set chattr id <num> to <data> for the indicated file.

!change "<userglob>" <what> <value> ...
Same as 'site change'.

!unlock <realpath>
This kicks all users currently transferring files that match the indicated path exactly. Use "\*" on end of a dirpath to match anything in/below.

!newlines [off | on ]
Don't think this does anything anymore.

!prefix [ off | on ]
Prefix lines with command's default numeric prefix. Default is on.

!buffer [off | on ]
If buffering is turned off then data is immediately sent to the client and not buffered until the command finished and sent all at once.

!detach [ 0 | 1 ]
Returns immediately from the command without waiting for the process to finish. 0 indicates success, 1 returns an error/failure.

NOTE: Case matters... "off" must be all lowercase, anything else is considered "on".

Yil
10-13-2011, 09:46 PM
Any EXEC script can return these !commands at the start of a line and ioFTPD will process the command. This gives scripts a simple way to do some common things without having to use the shared memory interface. I know a couple of scripts out there use this feature, but I don't have any practical knowledge.

Soxiz
10-14-2011, 06:36 AM
Thanks Yil, great list.

In the scenario where a command fails i am trying to either return an error code from the exe like 1 or using the !detach 1. In both cases i still get the "200 Command successful." What am I doing wrong? :)

Soxiz
10-15-2011, 04:39 PM
Figured it out, you need to set the environment variable ioerror :)

Yil are there other special environment variables that we should know about? :)

Yil
10-16-2011, 12:06 PM
Environmental variables to scripts are supplied via the etc/ioftpd.env file. You can use any message cookies from doc/Cookies.txt to supply anything you want to EXEC scripts, but just remember not all things are valid all the time, i.e. if you refer to a userfile field and the user hasn't logged in yet the value will be blank, 0, etc.

Environmental variables are a one way thing so I think your setting of ioerror is incorrect. Remember env vars get passed to processes at creation time and the parent won't see any changes to them.

However, the exit() value or the return value from main() of EXEC modules does indicate success/failure for processes that terminate. This is how all the scripts I've played with do things. The only exception would be if you intend the script to run in the background, i.e. you use !detach then that's the way to indicate success/failure. Since !detach 0/1 didn't seem to make a difference in your tests it's either the case that it never worked, was never used (I never saw it used), or I broke it when I re-wrote the whole exec module years ago...

Soxiz
10-16-2011, 02:01 PM
Hi Yil

That makes no sense to me, I tried that and it didn't work. I will try make a sample .net exe which only have a return 1 and test it one more time.

After looking at ioninja i saw that in the TCL it always sets the ioerror when a error occur. Thats why I tried it and it works.

Yil
10-16-2011, 10:50 PM
TCL and EXEC modules are completely different, they share almost nothing in common and you can't compare them.

Please make sure that in your test you don't have the leftover !detach line being output. That specifically tells the server to stop waiting for the program to exit and return immediately which obviously means it can't get access to the program's exit code...

Soxiz
10-20-2011, 04:32 PM
I tested a few things and found out what the issue is.

If i have a .net app that only returns a exit code, io works properly and return command failed. The problem happens when i write out text and then exit with a error. The text is displayed properly but the command don't fail. So it seems there is a problem. Below is a code snippet from c#:

public static void Main(string[] args)
{
Console.WriteLine("Test");
Environment.Exit(15);
}

The above code will do print out:

23:26:12 200-Test
23:26:12 200 Command successful.

If it was changed to only have the exit it would print out:

22:57:36 550 Command failed.

Yil
10-20-2011, 07:11 PM
At first I suppose this looks like an error, but it really isn't...

Your test looks a simple 'site' command (as opposed to pre/post events which are different) and all FTP commands must end in a valid 3 digit response code so the client knows if things succeeded or not. Without any script output the server uses the exit() code of the application and prints out a 200/500 code to signal success/failure.

However, you DID output the word "test" and relied upon ioFTPD to prefix it with a "200-". 200 is the default for site commands indicating success and the "-" means this isn't the final line with the only value that actually matters. After the script ran ioFTPD looked at the buffer, saw the last line was a "ddd-" continuation line and inferred the script result from that. Hence a "200 ..."success line was added so the FTP client would be happy.

For success you don't need to do anything since it will add the generic "200 Command successful." line, but you can use your own "200 Whatever" line at the end if you want a custom success message like "200 Successfully marked item" or whatever. UPDATE: You'll need to !prefix off" to actually enter such a line into the buffer.

For failure the only thing you have to do is make sure the last line ends in a "5xx Whatever" format so use "!prefix off" then output that line. If you output lines before that one you'll get the default prefix (i.e. 200- for site commands) added. If you want all the output to look like errors you'll have to use the "!prefix off" command at the start and then output your own prefixed lines like "550-Couldn't find 'foo'.".

I've been tempted to offer a way to have the server modify all lines to make the prefix numbers match the final output or to make a way to change the prefix before outputting lines, but it's not possible now so you'll have to do it yourself.

Specific response codes are defined in the FTP RFC's but you probably won't care about them as 200/550 works for nearly everything a site script cares about. The default prefix code used by ioFTPD for each type of event/script/etc can be found in /doc/Events.txt. You'll see that it's based upon the most likely response for the type of event. The ioPrefix variable in iTCL contains the default prefix for lines, but EXEC modules don't get that info but you can infer it from Events.txt and what triggered the script.