You are not logged in.
Pages: 1
Hello everybody!
I know that this is incredibly OCD and anal-retentive, but a while back I pointed out that the Arch kernel allows the user to choose what directory is to be the archisobasedir via kernel parameter (set at bootloader, such as grub or isolinux), yet the archisobasedir is hard-coded in abinstall as "arch". This is a discrepency in funtionality. If I rename the folder from "arch" to "arch64", the installer will fail because it looks to "arch".
So I wrote a bash script. It can rip out just the archisobasedir directory substring from /proc/cmdline. Running "cat /proc/cmdline" will spit out one big string that is exactly the kernel line from the bootloader when the kernel was booted. My script gets just the desired directory substring.
It can handle directories not enclosed in quotes, directories enclosed in single quotes, and directories enclosed in double quotes. If there is a lone quote on the end of the directory substring, it takes that off.
It can handle any number of spaces (including zero) on either side of the equals sign.
It can return one of four error codes if something's wrong with the source string.
It also "catches red herrings":
"linux /arch64/boot/x86_64/vmlinuz archisobasedirRedHerring=haHaHaWrongDir archisobasedir=arch64 archisolabel=ArchBang64"
If given the above string, it will return "arch64", not "haHaHaWrongDir".
The idea is that one more variable can be added to abinstall, archisobasedir, and set archisobasedir to $(sh ./archisobasedirGetter.sh), and replace the hard-coded instances of "arch" with "$archisobasedir" in the appropriate paths.
Here is the script:
# Def: This script was written to extract the archisobasedir out of the
# list of parameters passed to the kernel, but can be used to
# extract any directory from any string, given the directory is
# heralded with a signaling substring such as "archisobasedir=".
#
# Overview:
#
#
# Variables:
#
#
# 1. The string that the script will extract _from_ is passed to
# the variable "ore". To pass the kernel parameters to ore, the
# following is done: ore=$(cat /proc/cmdline)
#
# 2. The substring that "heralds" the directory of interest is
# held by the variable "trigger". This excludes the equals sign.
#
# 3. currentChar is an integer holding the current position
# the script is at in its walk through ore. It will eventually
# be the last character postition of the desired directory
# substring in ore plus one (if nothing goes wrong).
#
# 4. firstChar is (or at least will be, if nothing goes wrong)
# the first character position of the desired
# directory substring in ore.
#
# 5.found is a boolean used in while loops as a part of their
# compound conditions. Each loop looks for something, and this
# states whether that something has been found. Note this needs
# to be reset back to false before moving on to the next loop.
#
# 6. output is a string variable that will be the output of the
# entire script, which is the directory of interest. It will be
# "echoed out".
#
# 7. hasLocalEquals is a boolean that says whether or not the parameter
# of interest has an equals sign. Note this is different than saying
# whether or not the entire ore string has an equals sign.
# Example:
# "linux /arch64/boot/x86_64/vmlinuz archisobasedir arch64 archisolabel=ArchBang64"
# Assuming the parameter of interest is "archisobasedir", the parameter of interest
# is missing an equals sign, even though the string as a whole does
# have an equals sign (after "archisolabel"). After this is discovered,
# localHasEquals will be set to "false". Until then, it is "true".
# The string should be:
# "linux /arch64/boot/x86_64/vmlinuz archisobasedir=arch64 archisolabel=ArchBang64"
#
# 8. quoteMode guides the script when it comes to determining where
# the directory substring ends. When quoteMode=0, the dir string ends
# just before the next space, when quoteMode=1, the dir string ends
# at the next single quote, and when quoteMode=2, the dir string
# ends at the next double quote (you want to include quotes).
# Of course, if no quotes are used, and the directory substring
# goes to the end of ore, there will be no space after it, and that
# is ok too. Also, if there is a lone quote on the end of the directory
# substring, that is taken off.
#
#
# Error Code Value Meanings:
#
#
# "0": output is zero if no error has occured yet.
# This should never get returned (echoed out) and is for internal use only.
#
# "-1": output is negative one if the heralding substring, trigger, was not
# found in ore. In this case, "-1" is returned (echoed out).
#
# "-2": output is negative two if no equals sign was found after trigger and
# before the next parameter, if there is a next parameter.
# In this case, "-2" is returned (echoed out).
#
# "-3": output is negative three if no suitable directory substring could be found
# after the equals sign. Right now this is means that, after successfully finding
# trigger and an equals sign after trigger, but before the next parameter, if there
# is a next parameter, the script got to the end of ore without finding anything but
# spaces after the equals sign or the equals sign was the last character in ore.
# In this case, "-3" is returned (echoed out).
#
# "-4": output is negative four if the second quote could not be found. If no quotes are
# used, this error can't happen. A single quote must be followed up by a single quote and
# a double quote must be followed up by a double quote. Even if a single quote is followed
# up by a double quote, or a double followed up by a single, this error will result.
# In this case, "-4" is returned (echoed out).
#
#
# Procedure:
#
# 1. Iterating through ore, search for the first instance of trigger in ore, and record the
# postition of its first character (in respect to ore) in currentChar, so that after this
# loop has finished, currentChar holds the position of the first character of the first instance
# of trigger in ore. If trigger cannot be found, output is set to "-1", echoed out,
# and the procedure is stopped.
# Check that this first instance of trigger is immediately followed by either a space or equals sign.
# If it isn't, it's the wrong trigger. Example:
# ore="linux /arch/boot/vmlinuz archisobasedirRedHerring=hahahaWrongDir archisobasedir=theRightDir"
#
# If it weren't for that check, you'd walk away with "hahahaWrongDir" as your directory. Can't have that!
# Obviously, keep going until you find the right trigger, or get to the end of ore, whichever comes first.
#
# 2. Iterating through ore, starting at the position immediately after the last character of the first instance of
# (a correct) trigger in ore, look for the first instance of a character that is not a space. If that character
# is an equals sign, record that position to currentChar. If not, output is set to -2, echoed out, and the
# procedure is stopped
#
# 3. Iterating through ore, starting immediately after the aforementioned equals sign, find the first
# character that is not a space. If it is a single quote, set quoteMode to 1. If it is a double quote,
# set quoteMode to 2. Otherwise, leave quoteMode as 0. Set currentChar to this position, even if it is
# a quote, because we want to include quotes. firstChar is set to this position as well.
# If it gets to the end without finding anything that's not a space, of if the equals sign is the last
# character in ore, output is set to "-3", echoed out, and the procedure is stopped.
#
# 4. Iterating through ore, starting at the character immediately after the first character of the directory
# substring, find the end of the directory string in ore. If quoteMode=1, this is the next
# single quote found. If quoteMode=2, this is the next double quote found. If quoteMode=0, this is
# the character immediately before the next space found, or the last charcter in ore if the directory
# substring goes all the way to the end. If quoteMode is 1 or 2, make sure to add one
# to this position so that the quote is included in the exclusive substring syntax.
# If quoteMode=1 or quoteMode=2, and the second quote couldn't be found, output is set to "-4", echoed out,
# and the procedure is stopped.
#
# minor check that happens between step 4 and 5: if the last character of the directory substring is
# either a single quote or a double quote, and the first character of the directory substring is not a single
# quote or double quote, take off that lone quote.
#
# 5. echo out the found directory substring. This is done with the following format:
# echo ${ore:beginningCharPositionInclusive:$(($endingCharPositionExclusive-beginningCharInclusive))}
# Variable declaration:
# For testing, comment-out the cat line and uncomment the line that manually sets ore.
# That way you can test whatever you want without having to have that parameter in your current boot's cmdline.
ore="linux /arch64/boot/x86_64/vmlinuz archisobasedirRedHerring=haHaHaWrongDir archisobasedir=arch64 archisolabel=ArchBang64"
#ore=$(cat /proc/cmdline)
trigger="archisobasedir"
currentChar=0
firstChar=0
found="false"
output="0"
hasLocalEquals="true"
quoteMode=0
# Variable declaration done.
# Step 1 of procedure (look for trigger in ore):
# If this becomes no longer the first step, append to the condition so
# that the loop won't be entered if an error occured.
while [[ "$found" == "false" && $currentChar -lt $(expr length "$ore") ]]
do
# Notice it starts out just looking to see if it can find the
# first letter of trigger in ore. Only then does it bother
# to look for trigger in its entirety.
if [ "${ore:currentChar:1}" == "${trigger:0:1}" ];then
if [ "${ore:currentChar:$(expr length "$trigger")}" == "$trigger" ];then
found="true"
# Move currentChar to be immediately after trigger:
currentChar=$(($currentChar+$(expr length "$trigger")))
# "Red Herring" check, see procedure step 1 comment
# in the overview:
if [[ currentChar -lt $(expr length "$ore") ]];then
if [[ "${ore:currentChar:1}" != "=" && "${ore:currentChar:1}" != " " ]];then
found="false"
fi
fi
else
currentChar=$(($currentChar+1))
fi
else
currentChar=$(($currentChar+1))
fi
done
# If trigger was not found, output should be set to -1
# as an error code.
# Notice I'm not anding on a second subcondition of "output == 0"
# because this is the first time output can be set to an error code.
# If this becomes no longer the first time that can happen, add that
# subcondition.
# For later error-code-passing if blocks, it is important they don't
# override the error code. Or else if an error happens, and they all detect
# their errors the same way, the error code echoed out will always be the one of
# whichever error-code-passer comes last.
if [ "$found" == "false" ];then
output="-1"
fi
# resetting found for next loop:
found="false"
# Step 2 of procedure (look for equals sign after trigger):
# Note that this loop won't be entered if trigger could not be
# found because currentChar won't be less than the length of ore.
# If that changes, and the following subcondition: "$output" == "0"
while [[ "$found" == "false" && "$hasLocalEquals" == "true" && $currentChar -lt $(expr length "$ore") ]]
do
# The idea is, if anything other than a space is found after trigger at this point,
# it better be an equals sign, or else it's ran into the next parameter without
# finding the equals sign for the parameter of interest.
# That means the parameter of interest does not have an equals sign,
# which means it is incomplete, wrong, and will cause this script to
# return "-2" as an error.
if [ "${ore:currentChar:1}" != " " ];then
#It's starting to look like a triple equals!
if [ "${ore:currentChar:1}" == "=" ];then
found="true"
# Move currentChar to be immediately after found equals sign:
currentChar=$(($currentChar+1))
else
hasLocalEquals="false"
fi
else
currentChar=$(($currentChar+1))
fi
done
# If an equals sign was not found, output should be set to -2
# as an error code.
if [[ "$found" == "false" && "$output" == "0" ]];then
output="-2"
fi
# resetting found for next loop:
found="false"
# Step 3 of procedure (find beginning of directory substring):
# Note that this loop won't be entered if an error happened
# because output won't equal 0.
while [[ "$found" == "false" && $currentChar -lt $(expr length "$ore") && "$output" == "0" ]]
do
if [ "${ore:currentChar:1}" != " " ];then
found="true"
if [ "${ore:currentChar:1}" == "'" ];then
quoteMode=1
elif [ "${ore:currentChar:1}" == "\"" ];then
quoteMode=2
fi
# Setting firstChar to the first character position:
firstChar=$currentChar
# Moving currentChar to the next position:
currentChar=$(($currentChar+1))
else
currentChar=$(($currentChar+1))
fi
done
# If the beginning of the directory substring was not found,
#output should be set to -3 as an error code.
if [[ "$found" == "false" && "$output" == "0" ]];then
output="-3"
fi
# resetting found for next loop:
found="false"
# Step 4 of procedure (find end of directory substring):
# Note that these loops can't be entered if an error happened
# because output won't equal 0.
if [ $quoteMode == 0 ];then
while [[ "$found" == "false" && $currentChar -lt $(expr length "$ore") && "$output" == "0" ]]
do
if [ "${ore:currentChar:1}" == " " ];then
found="true"
else
currentChar=$(($currentChar+1))
fi
done
# It's ok for the last character of ore to be a part of the
# directory substring if there are no quotes used with the
# directory substring, that just means it went right up to the end.
# So if the end comes and no space has been found, that's ok.
if [ $currentChar == $(expr length "$ore") ];then
found="true"
fi
elif [ $quoteMode == 1 ];then
while [[ "$found" == "false" && $currentChar -lt $(expr length "$ore") && "$output" == "0" ]]
do
if [ "${ore:currentChar:1}" == "'" ];then
found="true"
# Make sure to include the quote:
currentChar=$(($currentChar+1))
else
currentChar=$(($currentChar+1))
fi
done
elif [ $quoteMode == 2 ];then
while [[ "$found" == "false" && $currentChar -lt $(expr length "$ore") && "$output" == "0" ]]
do
if [ "${ore:currentChar:1}" == "\"" ];then
found="true"
# Make sure to include the quote:
currentChar=$(($currentChar+1))
else
currentChar=$(($currentChar+1))
fi
done
fi
# If the end of the directory substring was not found,
# output should be set to -4 as an error code.
# The only way the end can't be found is if it had a
# quote to start it, and the closing quote is missing.
if [[ "$found" == "false" && "$output" == "0" ]];then
output="-4"
fi
# And check to see if there is a lone-quote on the end:
if [[ ("${ore:$(($currentChar-1)):1}" == "'" || "${ore:$(($currentChar-1)):1}" == "\"") && ("${ore:firstChar:1}" != "'" && "${ore:firstChar:1}" != "\"") ]];then
currentChar=$(($currentChar-1))
fi
# Note, do not have to reset found for the next loop
# because there is no next loop. Uncomment if this is no
# longer true:
#found="false"
# Step 5 of procedure (echo out the found directory substring!):
if [ "$output" == "0" ];then
output=${ore:firstChar:$(($currentChar-$firstChar))}
fi
echo $outputCheers,
Jake
WARNING/DISCLAIMER: My posted solutions (or attempts thereof) are usually my attempt at (re)iterating something that worked for _me_. I do not guarantee they will work for you. Use at your own risk.
My solutions may not be the simplest solutions, either. However, I do not intentionally add pointless complications.
Offline
TBH, I'm not sure what itch you're scratching with this. I'm not even sure how you trigger this situation in the first place and I read the initial thread a few times :-)
Of course, it may just be way over my head
Welly, welly, welly, welly, welly, welly, well. To what do I owe the extreme pleasure of this surprising visit?
Offline
Sorry if I didn't make it clear. I guarantee you that it is _not_ over your head.
Let's say you download an ArchBang iso. You install a bootloader to a thumb drive, and copy the folder named "arch" out of the iso and onto the thumb drive.
This "arch" folder is the archisobasedir.
Let's say that was the ArchBang 32-bit installer.
You rename that "arch" folder to "arch32", for example. Now the archisobasedir is "arch32".
Now you want the ArchBang 64-bit installer on the thumb drive as well.
So you copy the ArchBang 64-bit "arch" folder off the ArchBang 64-bit installer iso and onto the thumb drive.
You rename that "arch" folder to "arch64". Now there is an archisobasedir for the 32-bit installer, which is "arch32", and another archisobasedir for the 64-bit installer, "arch64".
The installer will fail whether you boot into the 32-bit installer or the 64-bit installer because the installer, abinstall, which is a bash script, is hard-coded to look in the "arch" folder. Well, there is no "arch" folder anymore. Instead, there is an "arch32" folder and an "arch64" folder. So the installation will fail.
My bash script allows for this to be fixed. It goes and gets the archisobasedir, which can be passed to a variable in abinstall, and using the variable, abinstall will use whatever the archisobasedir is for the archisobasedir, rather than always trying to use "arch" for the archisobasedir, even if "arch" isn't the archisobasedir.
It is important to note that I am not truly introducing new functionality. I am healing a discrepancy.
The arch kernel accepts "archisobasedir" as a parameter (bootloader line). That means the kernel supports letting the user name the archisobasedir anything. The user can name the archisobasedir "turkey pie" if he or she wanted to, the kernel supports that.
But abinstall is hard coded to think the archisobasedir will always be "arch".
If the kernel didn't support the user naming the archisobasedir anything, then it would be right for abinstall to hard-code "arch" as the archisobasedir. Because then they both wouldn't support that, and there would be no discrepancy.
But since the kernel does and abinstall doesn't, there's a discrepancy. I am fixing this discrepancy.
Cheers,
Jake
WARNING/DISCLAIMER: My posted solutions (or attempts thereof) are usually my attempt at (re)iterating something that worked for _me_. I do not guarantee they will work for you. Use at your own risk.
My solutions may not be the simplest solutions, either. However, I do not intentionally add pointless complications.
Offline
It is not hard coded into abinstall as script simply copies from iso to destination.
Are you wanting to have both i686 and x86_64 installations on external drive?
Offline
Let's use the following line from abinstall as an example of what I'm talking about:
mkinitcpio -k /run/archiso/bootmnt/arch/boot/${arch}/vmlinuz -c /etc/mkinitcpio.conf -g ${DESTDIR}/boot/initramfs-linux.imgThe "/run/archiso/bootmnt/arch/boot/${arch}/vmlinuz" part should be "/run/archiso/bootmnt/${archisobasedir}/boot/${arch}/vmlinuz".
In other words, the "arch" part should be replaced with a variable, because that folder isn't always named "arch", because the kernel invites the user to rename it. Right now abinstall is hard-coded to look to the "arch" folder. If that folder has been renamed to something other than "arch", abinstall will fail because it always looks to the "arch" folder. What if it's been renamed to "arch32" or "arch64" or "watermelon"?
In the iso, that folder is named "arch". But if the user copies that "arch" folder to a thumb drive, the user is free to rename that folder anything. Heck, they could name it "Apple Pie With Cinnimon". The user simply goes to the bootloader config file and sets the archisobasedir parameter to "Apple Pie With Cinnimon". So that kernel parameter line might look like this:
linux /"Apple Pie With Cinnimon"/boot/x86_64/vmlinuz archisobasedir="Apple Pie With Cinnimon" archisolabel=ArchBang64The point here is that since the kernel supports naming the archisobasedir anything, abinstall should too.
I do want both i686 and x86_64 installers on an external drive, and have succeeded in doing so by giving them separate partitions, and this is what got me into all this, but ultimately, that is not the point.
The point is that the user should be free to rename the "arch" folder whatever he or she wants it to be named, once copied onto a USB drive or other readily re-writable media.
Jake
WARNING/DISCLAIMER: My posted solutions (or attempts thereof) are usually my attempt at (re)iterating something that worked for _me_. I do not guarantee they will work for you. Use at your own risk.
My solutions may not be the simplest solutions, either. However, I do not intentionally add pointless complications.
Offline
The point is that the user should be free to rename the "arch" folder whatever he or she wants it to be named, once copied onto a USB drive or other readily re-writable media.
Jake
But you are...
Offline
But you are...
I did rename the folders to arch32 and arch64, but I then had to edit the abinstall script to use "arch32" or "arch64" instead of "arch".
I have since renamed them back to "arch" so that I don't have to do that.
Users shouldn't have to edit abinstall if they rename the folder. My script can make it so that they don't have to.
Last edited by SpawnHappyJake (2012-06-22 10:45:18)
WARNING/DISCLAIMER: My posted solutions (or attempts thereof) are usually my attempt at (re)iterating something that worked for _me_. I do not guarantee they will work for you. Use at your own risk.
My solutions may not be the simplest solutions, either. However, I do not intentionally add pointless complications.
Offline
I did rename the folders to arch32 and arch64, but I then had to edit the abinstall script to use "arch32" or "arch64" instead of "arch".
I have since renamed them back to "arch" so that I don't have to do that.
How many times are you running abinstall?
Welly, welly, welly, welly, welly, welly, well. To what do I owe the extreme pleasure of this surprising visit?
Offline
Hopefully only once per installation. How many installations do I do? Not en masse.
If you're asking because you're curious if I'm doing so many installs that editing abinstall is a significant inconvienence, the answer is "no", I'm not running abinstall _that_ much.
It's not particularly about me. I am hoping that my script will be accepted into the next ArchBang iso for the convenience of others, should they rename that folder.
I didn't even know that abinstall was a bash script when I first started using ArchBang. I didn't even know that the name of the installer program was "abinstall". Let alone where it was, that it could be edited, and that it was the problem.
Imagine someone new to ArchBang renaming the "arch" folder and not knowing why the installer failed. The user could have been playing by the rules and edited the bootloader line so that the archisobasedir is how it should be, so why would they suspect that to be the issue?
I'm desiring that abinstall be improved.
WARNING/DISCLAIMER: My posted solutions (or attempts thereof) are usually my attempt at (re)iterating something that worked for _me_. I do not guarantee they will work for you. Use at your own risk.
My solutions may not be the simplest solutions, either. However, I do not intentionally add pointless complications.
Offline
Sorry folks, I'll be unavailable this week. How about picking it up the next? Have a good one!
Jake
WARNING/DISCLAIMER: My posted solutions (or attempts thereof) are usually my attempt at (re)iterating something that worked for _me_. I do not guarantee they will work for you. Use at your own risk.
My solutions may not be the simplest solutions, either. However, I do not intentionally add pointless complications.
Offline
Pages: 1