USER command newbie REVISED

Brian K. White brian at aljex.com
Wed Jun 8 11:48:33 PDT 2005


----- Original Message ----- 
From: "Walter Vaughan" <wvaughan at steelerubber.com>
To: <filepro-list at lists.celestial.com>
Sent: Wednesday, June 08, 2005 11:45 AM
Subject: USER command newbie REVISED


> <reposted to correct typing error. I manually typed in second line 
> incorrectly>
>
> For testing purposes I have in a sample file's input processing table @key
> processing like the following:
>
> @keyT::user phone = /usr/local/bin/ssh ff at facetphone 
> /usr/facetphone_utapi/bin/fp_cid -n -s -u person:
> ::ph = phone:
> ::msgbox ph:
> ::end:
>
> What seems odd to me is
> 1) why cannot the user command be called from a variable?
> 2) why does "ph" only contain data for the first time it is encountered on 
> a
> processing table? Moving record to record, ph is blank every time the user
> command is run. I could see that if I stayed on the same record, but 
> moving from
> record to record?
> 3) If I add in a "close phone" before the end statement the *SECOND* time 
> the user command is encountered I see the following:
> <screen shot from SCO (FreeBSD looks similar)>
>              Multiple -v increases verbosity.
>  -V          Display version number only.
>  -P          Don't allocate a privileged port.
>  -q
>
>
>
>
>
>
>
>              These cause ss  ┌──────────────────┐
>              forward them t  └── Press  Enter   ┘
>
>
>
>
>
>
>
>  -6          Use IPv6 only.─                     ─
>  -o 'option' Process the option as if it was read from a configuration 
> file.
>  -s          Invoke command (mandatory) as SSH2 subsystem.
>  -b addr     Local IP address.
> </screen shot>
> ... which appears to me as if it trys to rerun the user comand without any 
> arguments
>
> SSH is configured properly... the command runs just fine from the command 
> line multiple times.
>
> Is/Was there a USER command tutorial in one of the FPDJ's that I failed to 
> remember reading about?
>
> Should I give up and run this as a system command?
> This should work as a USER command and be so elegant.
>
> --
> Walter
> _______________________________________________
> Filepro-list mailing list
> Filepro-list at lists.celestial.com
> http://mailman.celestial.com/mailman/listinfo/filepro-list
>

You have a real can of worms trying to use ssh from user unless you can 
garuntee what user ssh will run as every single time, and garuntee that that 
users ~/.ssh is all set up with the necessary keys and known_hosts. 
Otherwise ssh will print out several lines of messages and wait for input at 
a Y/N prompt about the storing the servers host key fingerprint in the users 
cache, none of which your processing will be expecting.

Basically the only secret to user is you have to be absolutely 100% always 
always always certain what the user programs is doing at all times.
Your processing has to always be right when it goes to read from or write to 
the user alias. The first time the processing gets out of sync or the user 
program does something you didn't expect, your pretty much hosed. At best 
you get garbage results, at worst your process hangs forever and you have to 
crash out.

Another issue to watch is multiple iterations in the same clerk/report 
session and zombie background processes piling up.
To avoid that you put your real command in a shell script that loops, and in 
processing you never close the user alias.
The user command that opens the alias can be put in the top of a gosub that 
does the other interacting with user, so that the user command is only 
invoked if needed, but once invoked, the user command stays there in the 
background and the next time you hit the gosub, it won't open another 
instance of the command, it'll just talk to the existing instance some more.
When you close the user command and reopen it, each close leaves a zombie in 
the background until the currently running instance of clerk/report exits.

I did some very similar work for American River (who read this list) and it 
was a bear. And I was only using netcat, just plain old netcat, no passwords 
or other authentication, no keys or fingerprint cache, no risk of unexpected 
messages and even so it was not simple to get the process table so that it 
was reliable. Ultimately I had to make the table so that it had seperate 
parts for:
a) reading/writing to user
b) parsing the responses from user
c) using the responses

Because no matter that the tcp server I was communicating with was well 
documented and I was adhering to those docs, I still got unexpected 
responses and would get knocked out of sync and get hung up trying to write 
when it wasn't listening or waiting for input when none was going to even 
come...
So I had to make it so that I stored more than one line of responses and 
never made any assumption about what I was reading.
After every single read I test for various possible things and base my next 
action on that.
Luckily in this case one thing I could count on was that no matter what 
other unexpected things the server did, it always printed "ready>" on a line 
by itself as the last thing in every response, so I was able to have a gosub 
after every read that checked for that and if found, I knew not to try to 
read another line.
The reason I stored several lines of responses was so that at every time I 
wrote a command and read answers, I'd just read in a loop until I got the 
ready prompt and didn't care how many times it took. Then when I got the 
ready prompt, my data would be one or more lines back in the history as the 
most recent read was always the ready prompt.
This avoided 90% of the hangs.

Hopefully you can find or make for yourself some kind or reset/resync 
mechanism like that ready prompt.

The reason you are only getting one iteration from the user program is 
because it's just running once and exiting.
The next time you try to read from it, it's gone. Putting the close phone in 
is causing it to run anew each time, but obviously something is wrong with 
the 2nd and further times.
But because of what I said about zombies, that's not a good way to get it to 
run more than once anyways so theres no point in diagnosing that.

You need to put the ssh command into a shell script that loops.
then in processing you can repeatedly read from it.

Make a script like this:

vi /usr/local/bin/fpcid
----top---
#!/bin/sh
while read junk ; do
ssh ff at facetphone /usr/facetphone_utapi/bin/fp_cid -n -s -u person 
2>>/var/adm/fctssh
done
---end---
chmod 755 /usr/local/bin/fpcid
touch /var/adm/fpcid
chmod 666 /var/adm/fpcid

and use like this:
Every time you want to read, first write something, anything, we throw it 
away in the script, it's just to make the script wait for input after each 
run.
Put the user command, the write, and the read all together in a gosub and 
_only_ ever use the gosub.
Use the gosub as many or few times as you wish.

then: gosub getph

getph: if:
then: user fpcid = fpcid
then: fpcid = "x"
then: ph = fpcid
then: return

and never close fpcid

This is if fp_cid is a simple output generator that just spits out a line of 
text each time you run it.
If you need to write commands and then get responses that adds a few more 
steps to each part above but the structure is the same.

Also the gosub should check the sanity of what it gets back in ph and 
optionally read some more and/or write an answer to a yes/no prompt etc...
Maybe you can actually handle most common forms of unexpected responses that 
way.

Brian K. White  --  brian at aljex.com  --  http://www.aljex.com/bkw/
+++++[>+++[>+++++>+++++++<<-]<-]>>+.>.+++++.+++++++.-.[>+<---]>++.
filePro BBx  Linux SCO  Prosper/FACTS AutoCAD  #callahans Satriani


Brian K. White  --  brian at aljex.com  --  http://www.aljex.com/bkw/
+++++[>+++[>+++++>+++++++<<-]<-]>>+.>.+++++.+++++++.-.[>+<---]>++.
filePro BBx  Linux SCO  Prosper/FACTS AutoCAD  #callahans Satriani
 



More information about the Filepro-list mailing list