LC3 programming to prompt a user for a password, verifies if it is valid - lc3

write a program where the user must enter a password that
satisfies the following criteria:
o at most 12 characters and at least 8 characters
o may contain only capital A through Z, “*” or “ ” (space) characters
The process must continue until the user enters a valid password. To pull this off,
you’ll need to utilize TRAPS, Branches, Loads/Stores, and pretty much everything
LC3 has to offer.
The program works as follows:
o Ask to enter a password of up to 12 characters.
o If password has any characters that are not allowed, warn the user that at least
one character is not allowed, and ask for another password
o Once the user enters a password that only contains allowed characters, print
“Password created” and halt the program.
.ORIG x3000 ; start of the program
; setup the trap vector table
; TRAP x23 is used to check password
; TRAP x25 is used to print "Password Created"
; TRAP x22 is used to print "Please enter a valid password"
; TRAP x21 is used to read characters from keyboard
; set up trap vector table
; TRAP x23 is used to check password
; TRAP x25 is used to print "Password Created"
; TRAP x22 is used to print "Please enter a valid password"
; TRAP x21 is used to read characters from keyboard
TRAP x23 ; address of check password subroutine
TRAP x25 ; address of print "Password Created" subroutine
TRAP x22 ; address of print "Please enter a valid password" subroutine
TRAP x21 ; address of read characters from keyboard subroutine
.END ; end of program
; check password subroutine
CheckPassword
; check if the password is valid
; if valid, jump to PrintSuccess
; if invalid, jump to PrintError
; get the length of the password
; compare it to 8 and 12
; if length is less than 8 or greater than 12
; jump to PrintError
; loop through the characters of the password
; compare each character to A..Z, *, and space
; if any character is not in that range
; jump to PrintError
; if all characters are valid, jump to PrintSuccess
PrintSuccess ; print "Password Created"
; halt the program
PrintError ; print "Please enter a valid password"
; jump back to the start of the program
.END

Related

Bash Variable Not Being Assigned

I have this bash script, that gets an input from the user, and returns a phonetic transcription of the word, even if no transcription is available. However, the variable results isn't being assigned as a blank line is being printed instead of the value inside.
I have tried putting the commands into a different script, and that also produced blank lines, and doubled checked that there was no space between results and =
Code:
#!/usr/bin/env bash
#check if user entered a word to translate to ipa
#if a word was not entered prompt the user to enter a word
#else set the word passed as an argument to the variable current
if [ -z "$1" ]
then
echo "You did not enter a word for translation, Please enter one now: "
read current
else
current=$1
fi
#confirm to user the word they entered
echo "The word you chose for translation: $current"
#format the word into '< w o r d >'
onmt_word=$(python ONMT_DATA_FORMAT.py "$current")
#write over current word in temp_word.txt
echo $onmt_word > temp_word.txt
#translate the word in temp_word.txt using openNMT with the model created from a set of 32k words
results=$(onmt_translate -gpu -1 -model eng_ipa_model1_steps/eng_ipa_model1_step_100000.pt -src temp_word.txt -replace_unk -verbose -output model1_step_10000_temp_pred)
#print only the results we care about, i.e. the translated IPA
echo "The provided IPA translation is:"
echo $results | egrep -o '< .* >'
echo "Please ignore the first and last symbol, these are needed for the translation process."
Source:
https://github.com/LonelyRider-cs/LING4100_project

bash: parsing F-key (F1-F10) in script

I wrote a bash script, which has "buttons" similar to "mc" or Norton Commander. Right now, I use the number keys (1-0) to simulate the buttons being pressed. However, I would rather have the F-keys (F1-F10) to do it.
I saw this question and answers, but I am not certain this can be used in a script to trigger a function (e.g. by using "read").
Does bash support it? If so, is there a fairly easy way to implement it?
UPDATE
The script is kind of a dash, which needs to be refreshed in order to keep the contents current. However, at the same time I would like to keep the "channel" open to allow user input (therefore sleep would not be adequate).
The read line currently in use to get the user input looks like this:
read -n 1 -s -t "${iRefresh}" sReturnVar.
Here "iRefresh" is set to 2 seconds in order to time out when no input is given to refresh the display and return to the read line thereafter. In essence the read line doubles as a content refresher while waiting for user input.
This will dynamically determine the values for F1-F24, then use them in the context you're looking for. My system coopts F11, so I did not show that. This is somewhat brittle in that it depends on terminfo and sane terminal codes -- YMMV.
#!/usr/bin/env bash
read_key_press() {
if read -sN1 key_press; then
while read -sN1 -t 0.001 ; do
key_press+="${REPLY}"
done
fi
}
declare -a fnkey
for x in {1..24}; do
raw=$(tput kf$x | cat -A)
fnkey[$x]=${raw#^[}
done
while read_key_press; do
case "${key_press}" in
$'\e'${fnkey[1]}) echo 'F1';;
$'\e'${fnkey[2]}) echo 'F2';;
$'\e'${fnkey[3]}) echo 'F3';;
$'\e'${fnkey[4]}) echo 'F4';;
$'\e'${fnkey[5]}) echo 'F5';;
$'\e'${fnkey[6]}) echo 'F6';;
$'\e'${fnkey[7]}) echo 'F7';;
$'\e'${fnkey[8]}) echo 'F8';;
$'\e'${fnkey[9]}) echo 'F9';;
$'\e'${fnkey[10]}) echo 'F10';;
$'\e'${fnkey[11]}) echo 'F11';;
$'\e'${fnkey[12]}) echo 'F12';;
$'\e'${fnkey[13]}) echo 'F13';;
$'\e'${fnkey[14]}) echo 'F14';;
$'\e'${fnkey[15]}) echo 'F15';;
$'\e'${fnkey[16]}) echo 'F16';;
$'\e'${fnkey[17]}) echo 'F17';;
$'\e'${fnkey[18]}) echo 'F18';;
$'\e'${fnkey[19]}) echo 'F19';;
$'\e'${fnkey[20]}) echo 'F20';;
$'\e'${fnkey[21]}) echo 'F21';;
$'\e'${fnkey[22]}) echo 'F22';;
$'\e'${fnkey[23]}) echo 'F23';;
$'\e'${fnkey[24]}) echo 'F24';;
^D) exit ;; # note: this is a real <ctrl>-<d>
*) echo "Key pressed: ${key_press}";;
esac
done
For me, this produces:
<~> $ /tmp/so8897.sh
Key pressed: q
Key pressed: w
Key pressed: e
Key pressed: r
Key pressed: t
Key pressed: y
F1
F2
F3
F4
F5
F6
F7
F8
F9
F10
F12
F13
F14
F15
F16
F17
F18
F19
F20
F21
F22
F23
F24

How to write a unix shell script for

Program shall ask the secret key to run the program; a user should program this secret key in advance. If the user enters correct secret key it should move to next step (3), else it should prompt to enter correct key for five times and then exit the program
You may be trying to implement something like this
#!/bin/bash
secretKey="qwerty1234"
failcount=5
success=0
while [ $failcount -gt 0 ]
do
echo "please enter secretKey"
read inp
if [ $inp = $secretKey ]
then
success=1
break
else
((failcount--))
echo $failcount" tries remaining"
fi
done
if [ $success = 0 ]
then
exit 1
fi
echo "code runs here"
The above code has a preset secret key written into the script (in this case qwerty1234)
The program loops 5 times as determined by the failcount variable.
If the password is entered correctly, the success variable is set to 1 and the code executes.
If the password is incorrect 5 times, the loop ends with the success variable as 0.
This causes the program to exit with error code 1
Hope this helped, however please try to provide a clearer example, possibly with some basic implementation in the future.

How do I chain multiple user prompts together with the ability to go back a prompt?

I am wondering how I can make a bash script that has multiple menus in it.
For example, here's what the user would see upon running it:
Type the number of choosing:
1-play
2-load
3-exit
1
What is your name:
::prev::
Type the number of choosing:
1-play
2-load
3-exit
1
What is your name:
Brad
Where are you from, Brad?
Pennsylvania
What is your favourite colour?
1-blue
2-red
3-green
4-grey
5-magenta
,sdfhljalk:J;
What is your favourite colour?
1-blue
2-red
3-green
4-grey
5-magenta
2
What is your favourite toy?
train
What would you like on your sandwich?
::prev::
What is your favourite toy?
~`!##$%^& * ()_+=-{}[]|\"':;?/>.<,
What is your favourite toy?
::exit::
Exiting....
I apologize for it being long, I just want to cover all bases for the new game I'm going to be making. I want this to be the question to end all questions.
I want to be able to type ::prev:: wherever I am and have it go back to the previous question, and I'd like ::exit:: to exit the script wherever it is. Also, I'd like unrecognized input during questions with numbered responses to just reload the question without continuing, and for input containing characters that may cause a script break (something like :;!## ...) to reload the question instead of breaking.
Any help is greatly appreciated!
By the way, I'm using OS X Yosemite
First thing to do in this situation is to try and think of how, generally, you could implement something like this. Probably the biggest addition to complexity is using ::prev:: to go back a question. This means we need to represent the application state in some way such that we can move forward or backward.
Luckily, this is pretty simple: it's basically just an implementation of a stack that we need. Some visuals:
...
<--pop-- <--pop-- Location prompt <--pop-- ...
Name prompt Name prompt ...
Main menu --push-> Main menu --push-> Main menu --push-> ...
This also means each individual piece of the program needs to be self-contained. We can easily do this in shell scripting with functions.
So we need several pieces:
Function which displays a menu and allows the user to choose a value.
Function which displays a text prompt and allows the user to choose a value.
Function which manages a stack that represents the state of the program.
Individual functions for each piece of the program.
Let's first write our menu prompt function. This part is pretty easy. Bash will do most of the work using the select loop, which prints a menu for us. We'll just wrap it so that we can handle custom logic, like expecting ::exit:: or ::prev:: and some pretty-printing.
function show_menu {
echo "$1" # Print the prompt
PS3='> ' # Set prompt string 3 to '> '
select selection in "${menu_items[#]}" # Print menu using the menu_items array
do
if [[ "$REPLY" =~ ^(::exit::|::prev::)$ ]]; then
# If the user types ::exit:: or ::prev::, exit the select loop
# and return 1 from the function, with $selection containing
# the command the user entered.
selection="$REPLY"
return 1
fi
# $selection will be blank if the user did not choose a valid menu item.
if [ -z "$selection" ]; then
# Display error message if $selection is blank
echo 'Invalid input. Please choose an option from the menu.'
else
# Otherwise, return a success return code.
return 0
fi
done
}
We can now use this function like so:
menu_items=('Item 1' 'Item 2' 'Item 3')
if ! show_menu 'Please choose an item from the menu below.'; then
echo "You entered the command $selection."
fi
echo "You chose $selection."
Great! Now on to the next item on the agenda, writing the code that accepts text input from the user.
# Prompt for a required text value.
function prompt_req {
# do...while
while : ; do
# Print the prompt on one line, then '> ' on the next.
echo "$1"
printf '> '
read -r selection # Read user input into $selection
if [ -z "$selection" ]; then
# Show error if $selection is empty.
echo 'A value is required.'
continue
elif [[ "$selection" =~ ^(::exit::|::prev::)$ ]]; then
# Return non-success return code if ::exit:: or ::prev:: were entered.
return 1
elif [[ "$selection" =~ [^a-zA-Z0-9\'\ ] ]]; then
# Make sure input only contains a whitelist of allowed characters.
# If it has other characters, print an error and retry.
echo "Invalid characters in input. Allowed characters are a-z, A-Z, 0-9, ', and spaces."
continue
fi
# This break statement only runs if no issues were found with the input.
# Exits the while loop and the function returns a success return code.
break
done
}
Great. This function works similarly to the first:
if ! prompt_req 'Please enter a value.'; then
echo "You entered the command $selection."
fi
echo "You entered '$selection'."
Now that we have user input handled, we need to handle the program flow with our stack-managing function. This is fairly easy to implement in bash using an array.
When a part of the program runs and completes, it will ask the flow manager to run the next function. The flow manager will push the name of the next function onto stack, or rather, add it to the end of the array, and then run it. If ::prev:: is entered, it will pop the last function's name off of the stack, or remove the last element of the array, and then run the function before it.
Less talk, more code:
# Program flow manager
function run_funcs {
# Define our "stack" with its initial value being the function name
# passed directly to run_funcs
funcs=("$1")
# do...while
while : ; do
# Reset next_func
next_func=''
# Call the last function name in funcs.
if "${funcs[${#funcs[#]}-1]}"; then
# If the function returned 0, then no :: command was run by the user.
if [ -z "$next_func" ]; then
# If the function didn't set the next function to run, exit the program.
exit 0
else
# Otherwise, add the next function to run to the funcs array. (push)
funcs+=("$next_func")
fi
else
# If the function returned a value other than 0, a command was run.
# The exact command run will be in $selection
if [ "$selection" == "::prev::" ]; then
if [ ${#funcs[#]} -lt 2 ]; then
# If there is only 1 function in funcs, then we can't go back
# because there's no other function to call.
echo 'There is no previous screen to return to.'
else
# Remove the last function from funcs. (pop)
unset funcs[${#funcs[#]}-1]
fi
else
# If $selection isn't ::prev::, then it's ::exit::
exit 0
fi
fi
# Add a line break between function calls to keep the output clean.
echo
done
}
Our run_funcs function expects:
to be called with the name of the first function to run, and
that each function that runs will output the name of the next function to run to next_func if execution of the program must proceed.
Alright. That should be pretty simple to work with. Let's actually write the program now:
function main_menu {
menu_items=('Play' 'Load' 'Exit')
if ! show_menu 'Please choose from the menu below.'; then
return 1
fi
if [ "$selection" == 'Exit' ]; then
exit 0
fi
if [ "$selection" == 'Load' ]; then
# Logic to load game state
echo 'Game loaded.'
fi
next_func='prompt_name'
}
function prompt_name {
if ! prompt_req 'What is your name?'; then
return 1
fi
name="$selection"
next_func='prompt_location'
}
function prompt_location {
if ! prompt_req "Where are you from, $name?"; then
return 1
fi
location="$selection"
next_func='prompt_colour'
}
function prompt_colour {
menu_items=('Blue' 'Red' 'Green' 'Grey' 'Magenta')
if ! show_menu 'What is your favourite colour?'; then
return 1
fi
colour="$selection"
next_func='prompt_toy'
}
function prompt_toy {
if ! prompt_req 'What is your favourite toy?'; then
return 1
fi
toy="$selection"
next_func='print_player_info'
}
function print_player_info {
echo "Your name is $name."
echo "You are from $location."
echo "Your favourite colour is $colour."
echo "Your favourite toy is $toy."
# next_func is not set, so the program will exit after running this function.
}
echo 'My Bash Game'
echo
# Start the program, with main_menu as an entry point.
run_funcs main_menu
Everything is in order now. Let's try out our program!
$ ./bash_game.sh
My Bash Game
Please choose from the menu below.
1) Play
2) Load
3) Exit
> ::prev::
There is no previous screen to return to.
Please choose from the menu below.
1) Play
2) Load
3) Exit
> 2
Game loaded.
What is your name?
> Stephanie
Where are you from, Stephanie?
> ::prev::
What is your name?
> Samantha
Where are you from, Samantha?
> Dubl*n
Invalid characters in input. Allowed characters are a-z, A-Z, 0-9, ', and spaces.
Where are you from, Samantha?
> Dublin
What is your favourite colour?
1) Blue
2) Red
3) Green
4) Grey
5) Magenta
> Aquamarine
Invalid input. Please choose an option from the menu.
> 8
Invalid input. Please choose an option from the menu.
> 1
What is your favourite toy?
> Teddie bear
Your name is Samantha.
You are from Dublin.
Your favourite colour is Blue.
Your favourite toy is Teddie bear.
And there you have it.

How a function should exit when it called with here-document from shell script?

I have a COBOL program which should be run thru shell script and should accept the values from the here document. in the here document, i should call a function that should let control to be exit abnormally with exit code.
I have tried as below but it is not working for me.
This is my COBOL program:
01 WW-ANS PIC X value space.
IRS-200.
display "ARE THE ABOVE ANSWERS CORRECT? Y/N/E".
Accept ws-ans.
display "entered value is " ws-ans "<".
IF WW-ANS = "E" or "e"
PERFORM STOP-RUN-CA.
IF WW-ANS NOT = "Y" AND "N" AND "E"
and "y" and "n" and "e"
PERFORM DISPLAY-01 THRU DISPLAY-01-EXIT
GO TO IRS-200.
IF WW-ANS = "Y" or "y"
display "Program executed successfully"
PERFORM STOP-RUN-CA.
ELSE
GO TO IRS-200.
DISPLAY-01.
DISPLAY "value is >" WW-ANS "<".
DISPLAY "INVALID RESPONSE".
This is my shell script:
#!/bin/bash
funexit ()
{
echo "calling funexit"
exit 1
}
/caplus/pub/test123<<:EOD:
1
g
$(funexit)
Y
:EOD:
Output is:
[Linux Dev:adminusr ~]$ ./test123.sh
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is 1<
value is >1<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is g<
value is >G<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is c<
value is >C<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is Y<
Program executed successfully
When ever function gets called from here document the COBOL program accept the value as "C", since at function: it invoke the echo command and considering the first character from the "calling funexit" string, instead of getting exit.
From the function, I have removed echo statement like below:
#!/bin/bash
funexit ()
{
exit 1
}
/caplus/pub/test123<<:EOD:
1
g
$(funexit)
Y
:EOD:
Output is:
[Linux Dev:adminusr ~]$ ./test123.sh
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is 1<
value is >1<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is g<
value is >G<
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is <
value is > <
INVALID RESPONSE
ARE THE ABOVE ANSWERS CORRECT? Y/N/E
entered value is Y<
Program executed successfully.
When ever function gets called from here document the COBOL program accept the value as spaces instead of getting exit.
The script should get exit abnormally with some exit code.
This example looks contrived because you are giving it both static input. However, that is probably because this is just a simplified example.
I guess is that you want funexit to return the E so that the input would mean that there is no more input, and nothing if there is more input. To be clear, the funexit script is called (and finishes) before COBOL is called.
I think you would want to code your shell script like this:
#!/bin/bash
funexit ()
{
echo calling funexit 1>&2
echo E
}
/caplus/pub/test123<<:EOD:
1
g
$(funexit)Y
:EOD:
Notice that the call to funexit and the following Y are on the same line. That way, if funexit did not return anything, the cobol program would not see a blank line. If funexit returns an E (actually an E followed by a new line) it would see the E.
Also notice that your debugging output of "Calling funexit" is redirected to standard error; before it was being sent to the cobol program and it ACCEPTed the letter C (from "Calling").
And lastly, the funexit script does not need to exit, as that is what will happen at the end of the script anyway.
#ANR;
Use ACCEPT ... ON EXCEPTION
Ala
identification division.
program-id. sample.
data division.
working-storage section.
01 the-fields.
05 field-one pic x(8).
05 field-two pic x(8).
05 field-three pic x(8).
05 field-four pic x(8).
*> ***************************************************************
procedure division.
accept field-one end-accept
display field-one end-display
accept field-two end-accept
display field-two end-display
accept field-three
on exception
display "no field three entered" end-display
not on exception
display field-three end-display
end-accept
accept field-four
on exception
display "no field four entered" end-display
not on exception
display field-four end-display
end-accept
goback.
end program sample.
So a run with four lines of input looks like
./sample <fourdatums.txt
one
two
three
four
and with only three
./sample <threedatums.txt
one
two
three
no field four entered
Since funexit is executed in a subshell created by the command substitution, you'll need to check its exit status outside the here document to determine if the parent shell should exit.
#!/bin/bash
funexit () {
echo "calling funexit"
exit 1
}
output=$(funexit) || exit
/caplus/pub/test123<<:EOD:
1
g
$output
Y
:EOD:
Assign the output of your function to a variable outside the heredoc and check for failure there:
#!/bin/bash
funexit ()
{
exit 1
}
if ! funexitvalue=$(funexit) ; then
echo "Failure!"
exit 1
fi
/caplus/pub/test123<<:EOD:
1
g
$funexitvalue
Y
:EOD:
This will prevent the COBOL program to be run if funexit does not exit successfully.
Explanation:
Command substitutions ($(...)) in bash always "work", as in, the substitution is replaced by the output of the command. Even if the command exits with an error:
$ echo "$(echo foobar; exit 1)"
foobar
$ echo $?
0
As you can see, the first echo exits successfully, even though the command in the substitution failed. The return code of the command substitution does not affect the actual command in any way.
In contrast:
$ a="$(echo foobar; exit 1)"
$ echo $?
1
$ echo $a
foobar
Here the return code of the command substitution is not shadowed by any other command, so you can actually check, if it returned successfully. Anyway, the assignment of the output to a was still successful.
Note: If you intended the COBOL program to be run up to the point where the faulty input would happen, than heredocs are not the way to go, as they are completely evaluated before they are even passed to the program. So with heredocs it is an all or nothing deal.
The heredoc is going to be parsed by the shell and passed as input in its entirety, and your approach is not going to work. However, you can certainly break up the input:
{ cat << EOF
This text will always be entered to the test123 executable;
EOF
funexit # exit or return, as needed
cat << EOF
If funexit returned, this will go to test123.
If funexit exited, it will not
EOF
} | caplus/pub/test123

Resources