I recently have started releasing Roms on the G2X. Coming from the Vibrant world where there were so many leaks and versions, that everyone forced wipes on updates, I was shocked when many roms were No-Wipe... Just seemed crazy.
Then on top of that, I realized I had to deal with the fact that custom kernels were ext4 while the stock kernel for the base I was using was ext3.
So I needed a script that could figure out what Rom was currently installed. The requirements:
1) Figure out what Rom is currently installed.
2) WIPE data and convert to ext3 if a non-compatible Rom is installed.
3) DO NOT WIPE data if a compatible Rom is already installed.
4) Install ext3 kernel ONLY if we wiped the partitions
5) Leave existing kernel alone if user already has compatible Rom
6) Backup files that are tied to kernel version (on LG, it's wireless.ko)
I searched high and low, and couldn't find any updater scripts that actually did this. The best I could find was this very useful post: http://forum.xda-developers.com/showthread.php?t=974450 that showed how to use ifelse and file_getprop. He has a lot of good ideas, but what was missing was an actual full updater-script that could be used.
Also, I needed to be able to backup a file from /system and deal with what happens if that file didn't actually exist.
So I wrote wrote my own updater script.
The basic process:
1: Extract needed tools from updater zip to /tmp
2: Run a shell script (tsugib.sh). It copies default.prop to /tmp/build.prop (just a kludge in case the next step fails).
3: Script then copies /system/build.prop to /tmp/build.prop. This is so we can still acess build.prop AFTER formatting /system
4: Control returns to edify, where we use an ifelse statement reading the properties with file_getprop to determine whether or not to wipe.
5: Normal install procedes.
6: Instead of just installing the kernel, we check the backed up build.prop again.
7: If keeping existing kernel, run a shell script (tsugir.sh) to restore the kernel library that was backed up.
8: If not keeping the kernel, then we install a new kernel.
Examples - Keep in mind, these scripts are written specifically for an LG G2X... you will need to modify them to work with your particular phone. In particular, I've REMOVED all sections that symlink files or set permissions. I have commented fully, so hopefully you can see how to integrate this with your phone's own version of updater-scripts.
tusgib.sh - this script does the backing up of build.prop and the kernel-linked wireless.ko file for later restoral if we don't flash a new kernel.
I'm sure I could have also checked to see if build.prop actually exists, before placing the dummy file, but why have a conditional statement if I can just place the dummy file (which won't match on my file_getprop anyway). We have to place the dummy file first, because if the user has formatted /system, then Edify will abort when attempting the file_getprop.
Code:
#!/sbin/sh
#
# Backup current install files.
# Kludgy hack to prevent having to replace kernel
#
cp /system/lib/modules/wireless.ko /tmp/wireless.ko
#
# Kludge since edify breaks if build.prop does not exist.
cp /default.prop /tmp/build.prop
#
# now if there *is* a build.prop, we'll overwrite the default.prop with the correct values.
#
cp /system/build.prop /tmp/build.prop
exit 0
tsugir.sh
I use this file to restore the wireless.ko file which is linked to kernel version. I have to restore the file since it is located in /system, which is wiped regardless of whether we wiped /data. Again, Rom specific. You may not even need this step if you have no files that are linked to kernel version.
Code:
#!/sbin/sh
#
# Restore current wireless.ko
# Kludgy hack to prevent having to replace kernel
#
cp /tmp/wireless.ko /system/lib/modules/wireless.ko
exit 0
And, here is the sample updater-script.
Code:
#
# Splash Message for the User
#
ui_print("");
ui_print("Tsugi 2.3.4 Smart Updater");
ui_print("");
show_progress(0.500000, 0);
ui_print("Preparing to Install...");
#
# LG G2XPartition Info
#
# Highly recommended to research and put your own phone's partition info here
# so you have a handy reference when editing updater-script.
#
# op7 = /data, - pillage on full wipe
# op1 = /system, - pillage only with full update (doesn't require wipe tho)
# op2 = /cache, - always pillage to avoid issues.
# op8 = /emmc, 1p1 = /sdcard - don't pillage unless u like mad users
#
# Kludges to make this a smart updater.
# 1: Backup build.prop so it can be accessed after installing /system
# 2: Check if Tsugi is already installed
# - NO: Perform FULL WIPE and INSTALL NEW KERNEL
# - YES: DO NOT WIPE, backup and RESTORE WIRELESS.KO
#
ui_print(" Checking Existing Install...");
# extract needed tools
package_extract_file("system/bin/tsugib.sh", "/tmp/tsugib.sh");
package_extract_file("system/bin/tsugir.sh", "/tmp/tsugir.sh");
set_perm(0, 0, 0777, "/tmp/tsugib.sh");
set_perm(0, 0, 0777, "/tmp/tsugir.sh");
#
# backup files to keep
# backs up current build.prop to /tmp so it can be checked
# /system must be mounted for this.
#
run_program("/sbin/busybox", "mount", "/system");
run_program("/tmp/tsugib.sh");
#
# Now unmount system since having it mounted will
# break formatting (if we format).
#
unmount("/system");
#
# Since I didn't include a CLEAR way to identify my Rom in early versions,
# I'll identify it by the LG release version for now
# but this may change in the future
#
# Any value can be checked here, such as ro.modversion or ro.developer or any that you just
# add to the file yourself.
#
ifelse(
file_getprop("/tmp/build.prop", "ro.build.lge.version.release") == "LG-L95G-V10c_final",
(
ui_print("Compatible Rom Detected. Not wiping.");
),
(
ui_print("Incompatible Rom. Wiping.");
run_program("/sbin/mke2fs", "/dev/block/mmcblk0p7");
run_program("/sbin/tune2fs", "-j", "/dev/block/mmcblk0p7");
run_program("/sbin/mke2fs", "/dev/block/mmcblk0p1");
run_program("/sbin/tune2fs", "-j", "/dev/block/mmcblk0p1");
run_program("/sbin/mke2fs", "/dev/block/mmcblk0p2");
run_program("/sbin/tune2fs", "-j", "/dev/block/mmcblk0p2");
)
);
#
# On LG this does not wipe user data.
# Just the cache
# Make sure you have the correct paths.
#
ui_print(" Clearing dalvik");
run_program("/sbin/busybox", "mount", "/data");
delete_recursive("/data/local");
delete_recursive("/data/dalvik-cache");
#
# Completely wipes /system partition, but this leaves user data alone.
#
ui_print(" Clearing system");
run_program("/sbin/busybox", "mount", "/system");
delete_recursive("/system");
#
# I found that if I don't wipe /cache there can sometimes be issues.
#
ui_print(" Clearing cache");
run_program("/sbin/busybox", "mount", "/cache");
delete_recursive("/cache");
#
# Normal rom extraction...
#
ui_print("Extracting new Rom...");
package_extract_dir("system", "/system");
#
# IN THIS SECTION YOU WOULD SYMLINK YOUR TOOLBOX,
# BUSYBOX and ANY OTHER TOOLS YOU NEED.
#
#
show_progress(0.500000, 40);
ui_print(" Linking Tools...");
# many many lines removed for demonstration purposes.
#
# Extract any data (such as preinstalled apps that user can uninstall)
#
ui_print("Extracting Data....");
package_extract_dir("data", "/data");
ui_print(" Setting Permissions....");
#
# Much setting of permissions removed for demo purposes.
#
#
# Extract anything to the user's SDCard such as ringtones, etc
#
package_extract_dir("sdcard", "/sdcard");
show_progress(0.200000, 0);
#
# If coming from compatible Rom, then
# don't touch kernel. Kernel will remain as user had it. Restore wireless.ko from backup.
#
# If incompatible Rom, then install new Kernel.
# We check the BACKED UP build.prop since the already installed one would NOW match which
# may not be correct.
#
# Use whatever method your rom uses for installing the kernel. It may be very different.
#
ifelse(
file_getprop("/tmp/build.prop", "ro.build.lge.version.release") == "LG-L95G-V10c_final",
(
ui_print("Leaving Existing Kernel.");
run_program("/tmp/tsugir.sh");
),
(
ui_print("Installing LG Kernel.");
package_extract_file("boot.img", "/tmp/boot.img");
run_program("/sbin/busybox", "dd", "if=/dev/zero", "of=/dev/block/mmcblk0p5");
run_program("/sbin/busybox", "dd", "if=/tmp/boot.img", "of=/dev/block/mmcblk0p5");
delete("/tmp/boot.img");
)
);
#
# Now do any post-kernel install cleanup.
#
ui_print(" Cleaning Up....");
unmount("/data");
unmount("/system");
unmount("/cache");
ui_print(" ");
show_progress(0.100000, 0);
ui_print(" ");
ui_print("Injection Complete");
ui_print(" ");
ui_print("You may now #OCCUPY your G2X.");
Also it may be possible that some updater binaries don't support ifelse. I haven't heard of any that don't, but I always see the warning that it may not be supported.
If you need to do updater-script troubleshooting, you can adb into recovery and should be able to view the recovery log in the /tmp directory.
Now, keep in mind.. this updater-script is based on LG G2X partitions and install techniques. Your Rom may do it very differently, but as long as your updater binary and version of recovery supports all the needed features (mine did), then you can use a similar method on your own updater-script.
okay nobody had any suggestions...
Now I'm stumped....
Is there any way to check that a file EXISTS without using an assert - I do not want the install to ABORT if the file does not exist.... currently, even trying to use read_file will cause an abort if the file does not exist. This of course means I can't use the method of checking for tsugi.txt that I thought I could...
EDIT:.... okay, looks like I'll have to use a shell script to do the dirty work... have ifelse act upon the exit code of the shell script... and I'm hoping run_program is actually smart enough to pass the return code.... Who in the world thought that edify scripting was sufficient?
EDIT2: Still NOT working.... either my shell scripting is worse than I think, or run_program does NOT actually pass the result back to the calling function, thus I *cannot* do this:
Code:
ifelse ( run_program("/tmp/tsugicheck.sh"), ui_print("result 1"), ui_print("result 2) )
Looks like I can either move more updater-script functions out to the shell script... or use the shell script to set properties that can then be checked by edify scripting...
Hey,
I don't really have suggestions for you but I am really interested in this kind of script. If works, I too would love to have this thing in my ROM.
BTW, instead of reading a txt file which might not be there and crashing the script, how about reading the build.prop??
Build.prop is there in every system and usually every developers modifies it before releasing his/her ROM build.
IlluminatedOne said:
Hey,
I don't really have suggestions for you but I am really interested in this kind of script. If works, I too would love to have this thing in my ROM.
BTW, instead of reading a txt file which might not be there and crashing the script, how about reading the build.prop??
Build.prop is there in every system and usually every developers modifies it before releasing his/her ROM build.
Click to expand...
Click to collapse
The problem with Build.prop is I'm not sure if getprop can deal with substrings... That is, if the version is "Tsugi 11-23-11-1048" and another version is "Tsugi 11-25-11-0430" to only match on the Tsugi portion. I did add a developer ID which doesn't vary between versions, but I only did that on the very last release.
I was thinking maybe of using the shell script to build a temporary properties file that describes the current install - which kernel, addons, etc - and then edify can use getprop on THAT file to match the current install. And, of course, by knowing which kernel is installed, I know if I can safely install the ext3 kernel, or if they require an ext4 kernel, etc.
I've seen another updater script that shells out and uses the actual filename of the update zip to modify the installation. that seems a little complicated to me, personally... since it assumes the user is going to name the file ahead of time. I want the updater to figure things out on its own.
Calling a shell script from the updater-script would be the best way, you could check for a file/string, if it exists, echo one to a temp file, and then the updater-script checks if the file is there, if it is, it installs the rom, if it isnt, then it aborts and prints goodbye
or the easiest way
Call a shell script from the updater-script, and let it do all the work, and recovery show output from the script too!
Worked out a bit of a compromise, and I back up the existing build.prop to the tmp partition on the phone using a shell script, then I can use file_getprop on it as needed, even after the /system partition is wiped. Once I determine if a new kernel needs to be flashed or not, I restore the old wireless.ko (which is linked to kernel build on a g2x) back to the system directory if necessary. All works out pretty smoothly.
I am surprised more people don't use ifelse and getprop in their updater scripts. If anyone wants to steal the work I've done in a more intelligent update script, I have rolled it out on the current version of my Rom here: http://forum.xda-developers.com/showthread.php?t=1358724 ... anyone can feel free to use bits and pieces of the updater script to make their updates a little smarter.
The only catch so far, is if someone already has my rom installed, and wants to revert to the ext3 kernel, they have to flash a scrubber (which i've provided) which reformats the partitions, since you can't revert from ext4 to ext3 without a wipe.. and the whole purpose of the intelligent updater was to avoid putting an ext3 kernel onto an ext4 install...
In theory, the shell script can detect all sorts of things about the current install and create a specific properties file that can be checked by the edify script to modify the new installation, but I haven't implemented that much intelligence.
Thanks. I am gonna look into your Intelligent Script. All I need is to figure out a simple thing, that is to wipe or not. Will get back here if I have any questions.
IlluminatedOne said:
Thanks. I am gonna look into your Intelligent Script. All I need is to figure out a simple thing, that is to wipe or not. Will get back here if I have any questions.
Click to expand...
Click to collapse
Btw, the 12-06 version had a bug in the shell script... if the user wiped /system manually before running the script, there would be no build.prop...
EDIT:
Copied the info I posted here up to the first post and made this a HowTo...
Nice How To
I've seen various installer methods coming from the g2 forums. Kind of liked the meXdroid method. This is a wonderful guide though. Was going to try to make an installer [like meX but different] that installed d2sd and deletes a2sd if cued [a2sd default] for wildfire s users. Severe memory challenges with that device. Wish me luck and any pointers are more than welcome.
Rob
insink71 said:
I've seen various installer methods coming from the g2 forums. Kind of liked the meXdroid method. This is a wonderful guide though. Was going to try to make an installer [like meX but different] that installed d2sd and deletes a2sd if cued [a2sd default] for wildfire s users. Severe memory challenges with that device. Wish me luck and any pointers are more than welcome.
Rob
Click to expand...
Click to collapse
The more you can move off to shell scripts, the more power you have during the install....
Unfortunately, I am no good with shell scripting in any detail, and even worse (hopeless) at string operations... A person good at shell scripting could do a lot more.
The basic lesson is that Edify is way too simple, you have to run shell scripts to do a lot of ops.
The one thing I couldn't find a way to do that I would've liked was an interactive install. I saw that ages ago back when I had a G1, but it depended on the keyboard. Maybe with the new touch-enabled recoveries it will be possible, but I suspect it'll be a while (if ever) before we see that built for "older" devices.
lotherius said:
okay nobody had any suggestions...
Now I'm stumped....
Is there any way to check that a file EXISTS without using an assert - I do not want the install to ABORT if the file does not exist.... currently, even trying to use read_file will cause an abort if the file does not exist. This of course means I can't use the method of checking for tsugi.txt that I thought I could...
EDIT:.... okay, looks like I'll have to use a shell script to do the dirty work... have ifelse act upon the exit code of the shell script... and I'm hoping run_program is actually smart enough to pass the return code.... Who in the world thought that edify scripting was sufficient?
EDIT2: Still NOT working.... either my shell scripting is worse than I think, or run_program does NOT actually pass the result back to the calling function, thus I *cannot* do this:
Code:
ifelse ( run_program("/tmp/tsugicheck.sh"), ui_print("result 1"), ui_print("result 2) )
Looks like I can either move more updater-script functions out to the shell script... or use the shell script to set properties that can then be checked by edify scripting...
Click to expand...
Click to collapse
Hi,
I read your post and your script. Very helpful to learn edify possibilities
I would like to ask a question:
How can I assert that a given file (/path/File_Check.do) exists using edify with assert command?
Also, how can I do it in an external script that will cause the update.zip to stop or continue depending on answer?
Any help would be appreciated
Phil3759 said:
Hi,
I read your post and your script. Very helpful to learn edify possibilities
I would like to ask a question:
How can I assert that a given file (/path/File_Check.do) exists using edify with assert command?
Also, how can I do it in an external script that will cause the update.zip to stop or continue depending on answer?
Any help would be appreciated
Click to expand...
Click to collapse
In edify, I don't know,
but you can use a script.
In your updater-script you can copy one files (with only 1 string "ro.chiave=0") and one script in /tmp and run the script (somthing like that)
Code:
package_extract_file("test/test.prop", "/tmp/test.prop");
package_extract_file("test/script1", "/tmp/script1");
set_perm(0, 0, 0777, "/tmp/script1");
set_perm(0, 0, 0777, "/tmp/test.prop");
run_program("/tmp/script1");
the script
Code:
#!/system/bin/sh
CHKRIP=0
EXTRIP="/path/File_Check.do"
PROP_PATH="/tmp/test.prop"
if [ -f $EXTRIP ]; then
echo "Find file"
CHKRIP=1
fi
if [ $CHKRIP -eq 1 ]; then
#Update test.prop
echo "ro.chiave=1" > $PROP_PATH
fi
Now in the updater-script you can test the ro.chiave value like that
Code:
ifelse
(
file_getprop("/tmp/test.prop", ro.chiave) == "1",
(
ui_print("DO SOMTHING");
),
(
ui_print("FILE NOT FOUND");
)
);
run_program("/sbin/reboot");
run_program("/xbin/reboot");
This is only an idea
Ciaooooo
fbatti73 said:
In edify, I don't know,
but you can use a script.
In your updater-script you can copy one files (with only 1 string "ro.chiave=0") and one script in /tmp and run the script (somthing like that)
Code:
package_extract_file("test/test.prop", "/tmp/test.prop");
package_extract_file("test/script1", "/tmp/script1");
set_perm(0, 0, 0777, "/tmp/script1");
set_perm(0, 0, 0777, "/tmp/test.prop");
run_program("/tmp/script1");
the script
Code:
#!/system/bin/sh
CHKRIP=0
EXTRIP="/path/File_Check.do"
PROP_PATH="/tmp/test.prop"
if [ -f $EXTRIP ]; then
echo "Find file"
CHKRIP=1
fi
if [ $CHKRIP -eq 1 ]; then
#Update test.prop
echo "ro.chiave=1" > $PROP_PATH
fi
Now in the updater-script you can test the ro.chiave value like that
Code:
ifelse
(
file_getprop("/tmp/test.prop", ro.chiave) == "1",
(
ui_print("DO SOMTHING");
),
(
ui_print("FILE NOT FOUND");
)
);
run_program("/sbin/reboot");
run_program("/xbin/reboot");
This is only an idea
Ciaooooo
Click to expand...
Click to collapse
Thank you a lot
I would run assert on file_getprop to avoid auto reboot
Thank you again. Thought it was possible in edify, but yes, easier in script
Sent from my GT-I9100 using Tapatalk 2
lotherius said:
Is there any way to check that a file EXISTS without using an assert - I do not want the install to ABORT if the file does not exist.... currently, even trying to use read_file will cause an abort if the file does not exist. This of course means I can't use the method of checking for tsugi.txt that I thought I could...
[...]
... or use the shell script to set properties that can then be checked by edify scripting...
Click to expand...
Click to collapse
That last idea is the only thing I can think of that would work:
Have the shell script echo a value out to a tmp file based on whether the file exists and have an ifelse with either a file_getprop or a read_file conditional for the contents.
Edit: Doh, that's exactly what fbatti73 wrote out above. That's what I get for reading the first page and skimming the 2nd
Gave it another think though, this MIGHT work.. :
Code:
ifelse(run_program("/sbin/busybox", "[", "-f", "/system/etc/FILETOTEST", "]", "&&", "/sbin/busybox", "true"),
(ui_print("FILE EXISTS");
),
(
ui_print("FILE DOES NOT EXIST");
)
);
Edit: Tried it out for my new Nexus Louder installer and the above doesn't work, though it should, just edify being idiotic I guess. Resorted to the following:
Code:
ui_print("Checking for previous install...");
package_extract_file("instchk.sh", "/tmp/instchk.sh");
set_perm(0, 0, 0755, "/tmp/instchk.sh");
run_program("/tmp/instchk.sh");
ifelse(file_getprop("/tmp/insttest", "installed") == "1",
(ui_print("");
ui_print("Nexus Louder is already installed.");
ui_print("");
ui_print("To upgrade or repatch please run");
ui_print("revert for version: ", file_getprop("/system/etc/.nexuslouder", "installed.version"), ".");
ui_print("");
delete("/tmp/instchk.sh", "/tmp/insttest");
ui_print("Script will now exit...");
ui_print("");
unmount("/system");
unmount("/data");
abort();
),
(package_extract_file(".nexuslouder", "/system/etc/.nexuslouder");
delete("/tmp/instchk.sh", "/tmp/insttest");
)
);
And the instchk.sh is as follows:
Code:
#!/system/bin/sh
# check for the install file and write a value for edify to check
[ -f /system/etc/.nexuslouder ] && echo installed=1 > /tmp/insttest || echo installed=0 > /tmp/insttest
Pretty much the same as fbatti73, but perhaps streamlined a little. Hope my trial and error helps someone in the future. Cheers.
osm0sis said:
That last idea is the only thing I can think of that would work:
Have the shell script echo a value out to a tmp file based on whether the file exists and have an ifelse with either a file_getprop or a read_file conditional for the contents.
Edit: Doh, that's exactly what fbatti73 wrote out above. That's what I get for reading the first page and skimming the 2nd
Gave it another think though, this MIGHT work.. :
Code:
ifelse(run_program("/sbin/busybox", "[", "-f", "/system/etc/FILETOTEST", "]", "&&", "/sbin/busybox", "true"),
(ui_print("FILE EXISTS");
),
(
ui_print("FILE DOES NOT EXIST");
)
);
Edit: Tried it out for my new Nexus Louder installer and the above doesn't work, though it should, just edify being idiotic I guess.
Click to expand...
Click to collapse
If you want to chain commands with "&&", you'll need to invoke the "sh" binary since it's the shell that knows how to handle that. The "[" busybox applet will just receive it as an additional argument and not know what to do with it.
This will work:
Code:
ifelse(run_program("/system/bin/sh", "-c", "/sbin/busybox [ -f /system/etc/FILETOTEST ] && /sbin/busybox true"), ...
sh requires exactly 2 arguments: "-c" and another string with the command line as typed on the interactive shell.
To simplify the particular scenario you're targeting, you can simply run the normal test (or "[" ) command and use == to validate the exit code:
Code:
ifelse(run_program("/system/bin/sh", "-c", "test -f /system/etc/FILETOTEST") == 0, ...
The sh binary understands the built-in "test" command (at least on my device), so this will work even without using busybox. (Just the toolbox-bundled sh).
Bringing back an old thread but thanks to the ideas here it allow me to put together a script for my vrTheme template.
Basically the layout of this script goes as followed:
It will copy and paste the backup.sh file over to the /tmp folder of the recovery.
It will then run a security check of that backup.sh file when commanded to run it.
If the file does not run like it is suppose to (which means the file wasn't copied over properly) then it will abort the installation immediately and notify the user on the screen as well as giving a suggestion that they review their recovery log.
If the backup.sh runs then it will proceed forward with the installation.
The backup.sh will copy your build.prop file over to the /tmp folder of your recovery.
Then the updater-script will read the fingerprint found within the build.prop file.
If the fingerprint does not match then it will delete the copied backup.sh and build.prop file, abort the installation, and let the user know that their Rom is incompatible.
If the fingerprint does match then it will give an ok to proceed forward with the installation.
At this point some other scripts will be applied to the device for assisting with injecting the themes whether images or xml files in to their respectable apk's and push back to their respectable locations.
This script was exactly what I needed to keep it device specific and insuring integrity.
Click below to review:
Code:
##########################################################################################
# Script By Modding.MyMind #
# K2_CL Partition Info #
# #
# Highly recommended to research and put your own phone's partition info here #
# so you have a handy reference when editing the updater-script. #
# #
# mmcblk0p22: "misc" #
# mmcblk0p21: "recovery" #
# mmcblk0p20: "boot" #
# mmcblk0p35: "system" #
# mmcblk0p29: "local" #
# mmcblk0p36: "cache" #
# mmcblk0p37: "userdata" #
# mmcblk0p25: "devlog" #
# mmcblk0p27: "pdata" #
# mmcblk0p38: "fat" #
# mmcblk0p30: "extra" #
# mmcblk0p32: "carrier" #
# mmcblk0p16: "radio" #
# mmcblk0p17: "adsp" #
# mmcblk0p15: "dsps" #
# mmcblk0p18: "wcnss" #
# mmcblk0p19: "radio_config" #
# mmcblk0p23: "modem_st1" #
# mmcblk0p24: "modem_st2" #
# mmcblk0p31: "skylink" #
# mmcblk0p33: "cdma_record" #
# mmcblk0p34: "reserve" #
# #
# Modifications to make this a smart updater. #
# 1: Backup build.prop so it can be accessed after installing /system #
# or so the device can be properly confirmed in general. #
# 2: Check if backup.sh is already installed for security checks and rom compatibility. #
# #
# #
# #
##########################################################################################
package_extract_file("backup.sh", "/tmp/backup.sh");
set_perm(0, 0, 0777, "/tmp/backup.sh");
run_program("/sbin/busybox", "mount", "/system");
ifelse(
run_program("/tmp/backup.sh"),
(
ui_print(" ");
ui_print("Checking For Compatibility!");
ifelse(
file_getprop("/tmp/build.prop", "ro.build.fingerprint") == "htc/sprint_wwe_boost/k2cl:4.1.2/JZO54K/209682.6:user/release-keys",
(
ui_print(" ");
ui_print("Compatible Rom Detected!");
delete("/tmp/backup.sh");
delete("/tmp/build.prop");
ui_print("--Ok to proceed!");
ui_print(" ");
ifelse(
is_mounted("/system") == "/system", unmount("/system")
);
ifelse(
is_mounted("/data") == "/data", unmount("/data")
);
ifelse(
is_mounted("/cache") == "/cache", unmount("/cache")
);
ui_print(" ");
ui_print("Preparing To Inject Theme.");
#####################################################################
# Double checking to insure they are unmounted! Harmless procedure. #
#####################################################################
ui_print(" ");
ifelse(
is_mounted("/system") == "/system", unmount("/system")
);
ifelse(
is_mounted("/data") == "/data", unmount("/data")
);
ifelse(
is_mounted("/cache") == "/cache", unmount("/cache")
);
#############################################################
# Beginning the injection of modified images and xml files. #
#############################################################
ui_print(" ");
ui_print("Final Preparations...");
ui_print(" ");
ui_print(" ");
run_program("/sbin/busybox", "mount", "/system");
run_program("/sbin/busybox", "mount", "/data");
run_program("/sbin/busybox", "mount", "/cache");
ui_print("Injecting!!!");
package_extract_dir("vrtheme", "/cache/vrtheme");
set_perm(0, 0, 0755, "/cache/vrtheme/installtheme.sh");
set_perm(0, 0, 0755, "/cache/vrtheme/zip");
set_perm(0, 0, 0755, "/cache/vrtheme/cleanup.sh");
set_perm(0, 0, 0755, "/cache/vrtheme/zipalign");
run_program("/cache/vrtheme/installtheme.sh");
ui_print(" ");
ui_print("Theming Completed!");
ui_print(" ");
#######################
# Performing cleanup. #
#######################
run_program("/cache/vrtheme/cleanup.sh");
######################
# Unmounting mounts. #
######################
ui_print("--> Unmounting partitions");
run_program("/sbin/umount", "/system");
run_program("/sbin/umount", "/data");
#################################################
# Let user know that the injection is complete. #
#################################################
ui_print(" ");
ui_print("Injection Done!");
),
(
##############################################################################################################
# Rom found incompatible so remove copied build.prop and backup.sh file then unmount and abort installation. #
# Notify user of the current status. #
##############################################################################################################
ui_print(" ");
ui_print(" ");
delete("/tmp/backup.sh");
delete("/tmp/build.prop");
run_program("/sbin/umount", "/system");
run_program("/sbin/umount", "/data");
ui_print("Incompatible Rom Detected!");
ui_print("Not Recommended To Continue!");
)
);
),
(
run_program("/sbin/umount", "/system");
ui_print("ERROR READING YOUR ROM'S FINGERPRINT!");
ui_print("Please review your recovery.log!");
ui_print(" ");
ui_print("This Installation Will Be Aborted!");
)
);
I know that this is an old thread but I'm just trying to check with a script if a file already exists or not.
This is the code I am using but without success:
Code:
ifelse(run_program("/system/bin/sh", "-c", "test -e /system/priv-app/LGSystemUI/LGSystemUI.apk_orig") == 0,
(
ui_print("BACKUP ALREADY EXISTS");
),
(
ui_print("BACKUP DOES NOT EXIST");
ui_print("Backing up original...");
run_program("/sbin/busybox", "mv", "/system/priv-app/LGSystemUI/LGSystemUI.apk", "/system/priv-app/LGSystemUI/LGSystemUI.apk_orig");
)
);
Can anybody please help me?
KreNtal said:
I know that this is an old thread but I'm just trying to check with a script if a file already exists or not.
This is the code I am using but without success:
Code:
ifelse(run_program("/system/bin/sh", "-c", "test -e /system/priv-app/LGSystemUI/LGSystemUI.apk_orig") == 0,
(
ui_print("BACKUP ALREADY EXISTS");
),
(
ui_print("BACKUP DOES NOT EXIST");
ui_print("Backing up original...");
run_program("/sbin/busybox", "mv", "/system/priv-app/LGSystemUI/LGSystemUI.apk", "/system/priv-app/LGSystemUI/LGSystemUI.apk_orig");
)
);
Can anybody please help me?
Click to expand...
Click to collapse
Yes i can, but you'll have to wait until I'm at home later today.
I used to do the exact same thing, though its a long time ago so I'll have to take a closer look.
crazymister said:
Yes i can, but you'll have to wait until I'm at home later today.
I used to do the exact same thing, though its a long time ago so I'll have to take a closer look.
Click to expand...
Click to collapse
You will definitely make my day. I'll wait patiently.
KreNtal said:
I know that this is an old thread but I'm just trying to check with a script if a file already exists or not.
Code:
ifelse(run_program("/system/bin/sh", "-c", "test -e /system/priv-app/LGSystemUI/LGSystemUI.apk_orig") == 0,
Can anybody please help me?
Click to expand...
Click to collapse
you used above code, but i think you forgot some --> "" <--
try this line instead:
run_program("/system/bin/sh", "-c", "test -e /system/priv-app/LGSystemUI/LGSystemUI.apk_orig") == "0",
or in complete code:
Code:
ifelse(
run_program("/system/bin/sh", "-c", "test -e /system/priv-app/LGSystemUI/LGSystemUI.apk_orig") == "0",
(
ui_print("BACKUP ALREADY EXISTS");
),
(
ui_print("BACKUP DOES NOT EXIST");
ui_print("Backing up original...");
run_program("/sbin/busybox", "mv", "/system/priv-app/LGSystemUI/LGSystemUI.apk", "/system/priv-app/LGSystemUI/LGSystemUI.apk_orig");
)
);
Hi friends of XDA,
I created this tutorial especially for noobs who would like to know how the clockworkmod uses the .zip
file and what and all goes into the process of flashing a .zip file and mainly about the format and syntax used in updater-script.
first is first!
#include
/*
* I am not responsible for bricked devices, dead SD cards or
* thermonuclear war.
* do some research if you have any concerns.
* YOU are choosing to make these modifications.
* yes, i copied this disclaimer from FXP because it is cool and i am lazy!
*/
now what is the updater-script and update-binary present in the META-INF>com>google>android in any flashable zip package?
1. updater-script - it is just a text file which contains all the commands which tells the clockworkmod what to do with the given
zip file. the updater-script is written in the edify scripting language.
2. update-binary - it is a binary which is requiered by the clockworkmod to translate the human readable format of the updater-
script to machine readable format for execution of the updater-script in our device.
exploring the updater-script:
now let's start exploring the updater-script !
1. open the updater script with notepad++ (strongly recommended)
2. now i will try and explain commands generally used in the updater-script,
assert(getprop("ro.product.device") == "ST15i" || getprop("ro.build.product") == "ST15i" ||
getprop("ro.product.device") == "ST15a" || getprop("ro.build.product") == "ST15a" ||
getprop("ro.product.device") == "smultron" || getprop("ro.build.product") == "smultron");
the above bunch of lines checks the device model to confirm that the zip file is flashed on the device
for which it is specifically created for. These bunch of lines are very important because it prevents
flashing of zip file which is not intended for the device hence avoiding any problems due to flashing
the wrong zip. for example the above lines checks for the value of "ro.product.device" and
"ro.build.product"in the build.prop file of the already existing rom in the device, if any of the three
defined values ST15i, ST15a, smultron are found it will continue with the next line of updater-script
otherwise flashing gets aborted with error in getprop.
format("yaffs2", "MTD", "system", "/system");
the above command explains itself, it is used to format the specified partition
syntax explanation:
format - the main command to direct the cwm to format using the following parameters
"yaffs2" - filesystem type used in the device
"MTD" - type of the partition used in the file system
"system" - name of the partition to be formatted
"/system" - location of the partition to be formatted
ui_print("Format Completed");
the above command is also self explanatory, it directs the cwm to display the following text
enclosed in double quotes in the user interface (display).
after succesful formatting it displays "Format Completed" in the device screen.
mount("yaffs2", "MTD", "system", "/system");
the mount command directs the cwm to mount the following file system and the following partition
the syntax is just as explained in the format command except that this command mounts the
defined partition whereas the format command formats the defined partition.
let's review what we have done till now,
1. we have checked the device to confirm that this is the device for which we created the zip.
2. we have formatted the system partition of the device.(this is only done when a new complete rom is being flashed, for flashing mods you
should never format the system partition!)
3. we have mounted the system partition of the device.
now let's continue,
package_extract_dir("system", "/system");
this command searches for the directory (folder) named "system" in the root of the zip file and
copies all the content of the "system" folder from the zip file into the "/system" partition
which is already mounted by the previous mount command.
remember the structure of the file system in the zip file and the "/system" partition of the device must be always identical.
for eg., you have created a mod by editing the systemUI.apk and you want to flash it, the system UI.apk resides in "/system/app"
so the structure of the file system in the update zip should be "/system/app/systemUI.apk"
ie., the update zip should contain folder named "system" at the root of it and folder named "app" inside the "system" folder and the
modded "systemUI.apk" must be placed inside the "app" folder.
package_extract_file("autoroot.sh", "/tmp/autoroot.sh");
this command searches for the file named "autoroot.sh" in the root of the zip file and
copies the file to "/tmp" folder and names it as "autoroot.sh" (here it does not change the name)
symlink("mksh", "/system/bin/sh");
the above command creates a symlink.
okay, now let's see about symlinks,
symlink is nothing but shortcuts, for example if a file is requiered in two different places instead of copy pasting the file
in two different locations, the file is copied to one of the two locations and in the other location a shortcut to the file(symlink)
is created. the source and the symlink can have different names (actually this is the prime use of symlinks).
to explain in a noob friendly manner,
take the above symlink, it creates a shortcut(symlink) for the command "mksh" and places it in the path of the operating system.
the shortcut(symlink) directs to the file "/system/bin/sh" , so whenever the os gets a request to execute the "mksh" command, the actual
binary that gets excuted will be "/system/bin/sh" .
creating symlinks saves a lot of space because instead of copying the whole file and placing it in requiered places we are just
creating shortcuts which directs to the source file which can be placed anywhere in the file system (generally placed in the path of the os).
set_perm_recursive(0, 0, 0755, 0644, "/system");
the above command is used to set permission recursively for the files and folders present inside a folder (in this case for "/system" folder).
syntax explanation:
0 - uid - it defines that the following permission is set for the user id 0 .
0 - gid - it defines that the following permission is set for the group id 0 .
0775 - dirmode - it defines that 0775 permission to set to directories contained within the specified directory.
0644 - filemode - it defines that 0644 permission to set to files contained within the specified directory.
"/system" - target directory to set the above mentioned permissions.
set_perm(0, 3003, 06755, "/system/bin/ip");
the above command is used to set permission for a individual file (in this case for "/system/bin/ip" file).
syntax explanation:
0 - uid - it defines that the following permission is set for the user id 0 .
3003 - gid - it defines that the following permission is set for the group id 3003 .
06775 - it defines that 06775 permission to set to the specific file.
"/system/bin/ip" - target file to set the above mentioned permissions.
run_program("/tmp/autoroot.sh");
remember the file autoroot.sh from package_extract_file command?
that file is supposed to be a shell script, the above command directs cwm to execute the "autoroot.sh" shell script present in "/tmp" folder.
unmount("/system");
the unmount command directs the cwm to unmount the following partition
the syntax is just as explained in the mount command except that this command unmounts the
defined partition whereas the mount command mounts the defined partition.
Okay now going into slightly complex and/or not widely used updater-script commands,
Ifelse
Syntax:
Ifelse(condition),(do_this),(else_do_this);
Example:
ifelse mount("yaffs2", "MTD", "system", "/system") == "system", ui_print("Mounted!"), ui_print("Mount Failed!");
Ifelse command can be explained simply as asking the system to do something based on the result of a condition.
From the example:
The ifelse command would attempt to mount the MTD partition named "system" to "/system".
If the mounting process succeeds (the condition), the script will display "Mounted!", else it will display "Mount Failed!"
abort()
It just abort's the script execution
Note: it is usually paired with some other command for example the getprop command or with ifelse.
Independently specifying abort() in the updater-script will kill the script abruptly right there so use this command carefully.
ALWAYS LEAVE A BLANK LINE AT THE END OF THE update-script (if the code contains 50 lines then 51 lines should be visible
in the notepad++ including a blank line after the end of the script)
ALWAYS REMEMBER TO SET THE EOL (end of line) CONVERSION OF updater-script
IN UNIX FORMAT BEFORE SAVING (notepad++ > edit > EOL conversion > UNIX format)
the above mentioned commands are just basic edify scripting commands which are generally used in updater-script.
for detailed scripting and coding in edify scripting language check out the following sources:
source of update-binary
introdution to edify
http://forum.xda-developers.com/wiki/Edify_script_language
scratchpad-documenting-edify-commands-for-android-updater-scritps
http://forum.xda-developers.com/showthread.php?t=1290062
HIT THANKS IF I HAVE HELPED YOU!
Nice tut bro
bandarigoda123 said:
Nice tut bro
Click to expand...
Click to collapse
thanks friend
Great piece of work buddy.... :good:
This is good for me:beer:
Sent from my HTC EVO 3D X515m using xda app-developers app
What l must to change here? I got error 7
Sent from my HTC EVO 3D X515m using xda app-developers app
analoncarkg said:
What l must to change here? I got error 7
Sent from my HTC EVO 3D X515m using xda app-developers app
Click to expand...
Click to collapse
Have you set the eol conversion to Unix format as described?
Have you left a blank line as described?
Make sure that Cyanogenmod Rom is for your device. Then try flashing again.
If the above mentioned steps fails and you still get a status 7 error or assert failed error then make SURE that the Rom is really specific for your device and remove the first three lines from the script
Remove lines starting From "assert" to "smultron");
Make sure that after removing the above specified three lines there is no blank line at the start of the script And flash again
Usually status 7 errors are due to bad formatting of the updater-script or in rare cases it is due to corrupted or incomplete download of the Rom.
hit thanks if I've helped!
sent from my smultron
here are some more commands if you like:
sleep();
show_progress(1.0, "1000"); more on this here: http://forum.xda-developers.com/showthread.php?t=1290062
if/ then/ endif; syntax
iONEx said:
here are some more commands if you like:
sleep();
show_progress(1.0, "1000"); more on this here: http://forum.xda-developers.com/showthread.php?t=1290062
if/ then/ endif; syntax
Click to expand...
Click to collapse
Thanks iONEX I knew them before but didn't add sleep and show_progress because they are just mere cosmetic changes and don't serve any serious purpose anyways I'll add them after understanding and testing
And about if/then/endif/ifelse , generally they are used rarely in updater-script but I'll add them anyways after understanding testing!
Thanks!
hit thanks if I've helped!
sent from my smultron
If anyone is interested in the source of the update-binary, I've added the link to it in the first post
hit thanks if I've helped!
sent from my smultron
Hello! How exactly should I write in the updater-script if I need to make the system folder rewriteable and then delete the existing framework-res.apk from system/framework and then copy a new framework-res.apk from the .zip file, then change the permissions of it and finally make the system folder write-only again?
My "idea" is something like this:
1. Content of the updater-script:
ui_print("Please wait...");
mount("MTD", "system", "/system");
delete("/system/framework/framework-res.apk");
package_extract_dir("system", "/system");
set_perm(0, 0, 04755, "/system/framework/framework-res.apk");
ui_print("Done");
unmount("/system");
2. Make a signed .zip file that would contain:
- system\framework\framework-res.apk
- META-INF\com\google\android\updater-script
3. Run the .zip from memory card via recovery
Would it work like this?
Note: My phone is bricked because of framework-res.apk and USB debugging is off, so this is the only way I could unbrick it.
You must have a unmodified updater-script in your meta-inf folder right?? Paste the "mount" command syntax here. It must be in the first few lines.
#pitchblack5691#
Actually I don't. I have to create it from scratch.
No. . . You need a meta-inf folder to work with which contains the signature files and a update-binary to create a flashable zip.
#pitchblack5691#
I only created those folders and an updater-script file and then I packed it & signed it using Update Zip Packager 3.0. The only update-binary file that I have is the one that's included with Update Zip Packager.
Code:
mount("MTD", "system", "/system");
ui_print("started. . . .");
delete("/system/framework/framework-res.apk");
package_extract_dir("system", "/system");
set_perm(0, 0, 0644, "/system/framework/framework-res.apk");
unmount("/system");
ui_print("finished");
This should work and you need a meta-inf folder extracted from some flashable zip. You can't create a meta-inf folder from scratch without using signature files and update-binary.
EDIT: what you said above will work. You either should have a meta-inf folder with signature files or a signing software.
And you don't have to give 755 permissions to an app because even though they are apps, technically they are not executed and only read from so no need for 755 permission. 644 permission should suffice and it's the default permission for a system app. . . 755 permissions is only useful for executable binaries and scripts.
#pitchblack5691#
I've just tried it. It returns this error:
...
Installing update...
E:Error in /tmp/sideload/package.zip
(Status 2)
Installation aborted.
E:Can't find misc
What does it mean please?
What code exactly you are using in the updater-script?? Paste the full code and paste the name of files present in the zip file in a hierarchical order.
#pitchblack5691#
The .zip contains these files:
Code:
META-INF\CERT.RSA
META-INF\CERT.SF
META-INF\MANIFEST.MF
META-INF\com\google\android\update-binary
META-INF\com\google\android\updater-script
system\framework\framework-res.apk
The code of updater-script:
Code:
mount("MTD", "system", "/system");
ui_print("started. . . .");
delete("/system/framework/framework-res.apk");
package_extract_dir("system", "/system");
set_perm(0, 0, 0644, "/system/framework/framework-res.apk");
unmount("/system");
ui_print("finished");
Bootloader unlocked?? Custom kernel?? Or installed cwm in a bootloader locked phone??? Looks like your cwm is not working properly. . .
#pitchblack5691#