Cool Edify Scripting Commands

I would like to try and put together a guide to Edify scripting commands and what their function is to compliment my above tutorial, I hope again we can all collaborate to make this a helpful source of information to all budding devs...we all have to start somewhere right!?

***Please, if there are any mistakes in this post or if you can help by adding further info please post below, thanks***

Ok...

Check you are flashing the correct device:

Code:
Select Code
assert(getprop("ro.product.device") == "maguro" || getprop("ro.build.product") == "maguro" || getprop("ro.product.board") == "maguro");
This will check your device is showing the correct name in the build.prop, in this case "maguro", you can obviously replace this with your device name.

To explain this a little further, you have told the script to check certain properties within your 'build.prop' file located in your /system folder. The above command ensures the following categories have the correct definitions before proceeding with the flash:
Code:
Select Code
ro.product.device=
ro.build.product=
ro.product.board=
Here are the main build properties within your build.prop:

Code:
Select Code
ro.build.id=
ro.build.display.id=
ro.build.version.incremental=
ro.build.version.sdk=
ro.build.version.codename=
ro.build.version.release=
ro.build.date=
ro.build.date.utc=
ro.build.type=
ro.build.user=
ro.build.host=
ro.build.tags=
ro.product.model=
ro.product.brand=
ro.product.name=
ro.product.device=
ro.product.board=
ro.product.cpu.abi=
ro.product.cpu.abi2=
ro.product.manufacturer=
ro.product.locale.language=
ro.product.locale.region=
ro.wifi.channels=
ro.board.platform=
ro.build.description=
ro.build.fingerprint=
ro.build.characteristics=
ro.cm.device=

Print text in the recovery during flashing process:

Code:
Select Code
ui_print("Your text here");
Code:
Select Code
ui_print(" ");
This simply prints a line of text in the recovery, it has no actual effect on the flashing process, if you want a blank line just leave a blank space as the second example.

Controlling the progress bar:

I believe I understand this correctly, if not please do post below with further clarification.

Code:
Select Code
show_progress(0.000000, 0);
or
Code:
Select Code
set_progress(0.000000);
You have two choices when controlling the progress bar, the first example allows you to define fractions of the progress bar and how long they will take to fill. The second example just allows you to specify that the bar fills to a certain fraction at whatever point during the flashing process.

The command is defined as: (progress bar fraction, duration in seconds to fill defined fraction);

For example the following code lines interspersed with your other commands would fill a fifth of the progress bar every five seconds:

Code:
Select Code
show_progress(0.200000, 5);
ui_print(" ");
show_progress(0.200000, 5);
ui_print(" ");
show_progress(0.200000, 5);
ui_print(" ");
show_progress(0.200000, 5);
ui_print(" ");
show_progress(0.200000, 5);
This process will only complete if the script takes long enough to flash, therefore you need to be aware of what you are actually flashing and how long it will take when defining these values.

If you wish to just define a fraction without fill without a time scale you can use the following command:

Code:
Select Code
set_progress(0.000000);
It is also best practice to include this element in your scripts as it will reassure people that their handset hasn't frozen during a flash.

Mount/Unmount a partition:

To mount a partition you need to use the following syntax:

Code:
Select Code
mount("filesystem-type", "partition-type", "device-specific-location", "mount-point");
filesystem-type: "ext4" or "yaffs2" (maguro is ext4)
partition-type: "EMMC" or "MTD" (maguro is EMMC)
location: Device specific address
mount-point: /system etc

So far I have managed to define the following Maguro specific mount points:

Code:
Select Code
"/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "/system"
"/dev/block/platform/omap/omap_hsmmc.0/by-name/userdata", "/data"
"/dev/block/platform/omap/omap_hsmmc.0/by-name/cache", "/cache"
"/dev/block/platform/omap/omap_hsmmc.0/by-name/efs" "/factory"
"/dev/block/platform/omap/omap_hsmmc.0/by-name/userdata", "/mnt/sdcard"
"/dev/block/platform/omap/omap_hsmmc.0/by-name/boot"
Example command would be:

Code:
Select Code
mount("ext4", "EMMC", "/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "/system");
I have taken these mount points from the file output by the maguro when you enter the following adb command:

Code:
Select Code
adb shell "mount > /sdcard/maguro_mountinfo.txt"
I have to admit I am a little in the dark about the "/factory" partition, any info would be greatly appreciated!

To unmount a partition you need to input the following command:

Code:
Select Code
unmount("/system");
Obviously replace the mount partition with whatever partition you are working in.

Format a partition:

To format a partition you need to use the following syntax:

Code:
Select Code
format("filesystem-type", "partition-type", "device-specific-location", "0");
Example:

Code:
Select Code
format("ext4", "EMMC", "/dev/block/platform/omap/omap_hsmmc.0/by-name/system", "0");
Some scripts include the "0" and some do not, not sure exactly on the function difference when included or not, again clarification would be great.

Flashing the contents of your ZIP file:

To flash an entire directory:

Code:
Select Code
package_extract_dir("system", "/system");
To flash a single file:

Code:
Select Code
package_extract_file("boot.img", "/dev/block/platform/omap/omap_hsmmc.0/by-name/boot");
These commands are structured as follows:

Entire directory: ("zipfileSource", "destination-partition");
Single File: ("file", "device-specific-mountpoint");

Deleting folders & files:

You can delete multiple folders or files using just one command, as follows:

To delete files:

Code:
Select Code
delete("file-path-1", "file-path-2", "file-path-3);
To delete folders/directories:

Code:
Select Code
delete_recursive("directory-path-1", "directory-path-2", "directory-path-3");
Setting Permissions

Here are the basics for setting permissions.

If you want to research the reasons behind this, there is some useful information on Linux permissions here: chmod wiki, linuxquestions.org linux wiki.

Thanks to JoeSyr for his input and help understanding this section of the tutorial.


Set permissions of a file or set of files:

Code:
Select Code
set_perm(uid, gid, mode, "filepath1", "filepath2")
Example:
Code:
Select Code
set_perm(0, 0, 06755, "/system/xbin/su");
uid - user id
gid - group id
mode - permission mode
filepath... - file to set permission on

Set permissions of a directory or set of directories and all files and folders within them:

Code:
Select Code
set_perm_recursive(uid, gid, dirmode, filemode, "dirpath1", "dirpath2")
Example:
Code:
Select Code
set_perm_recursive(0, 0, 0755, 0644, "/system");
uid - user id
gid - group id
dirmode - permission to set to directories contained within the specified directory
filemode - permission to set to files contained within the specified directory
dirpath... - directory to set permission on

Permissions syntax explained...so I can understand it lol (if I do then anyone can!):

The following are the pre-defined Android UID's & GID's. Taken from the following link: Android UIDs and GIDs

Code:
Select Code
AID_ROOT             0  /* traditional unix root user */

AID_SYSTEM        1000  /* system server */
AID_RADIO         1001  /* telephony subsystem, RIL */
AID_BLUETOOTH     1002  /* bluetooth subsystem */
AID_GRAPHICS      1003  /* graphics devices */
AID_INPUT         1004  /* input devices */
AID_AUDIO         1005  /* audio devices */
AID_CAMERA        1006  /* camera devices */
AID_LOG           1007  /* log devices */
AID_COMPASS       1008  /* compass device */
AID_MOUNT         1009  /* mountd socket */
AID_WIFI          1010  /* wifi subsystem */
AID_ADB           1011  /* android debug bridge (adbd) */
AID_INSTALL       1012  /* group for installing packages */
AID_MEDIA         1013  /* mediaserver process */
AID_DHCP          1014  /* dhcp client */

AID_SHELL         2000  /* adb and debug shell user */
AID_CACHE         2001  /* cache access */
AID_DIAG          2002  /* access to diagnostic resources */

/* The 3000 series are intended for use as supplemental group id's only. */
/* They indicate special Android capabilities that the kernel is aware of. */
AID_NET_BT_ADMIN  3001  /* bluetooth: create any socket */
AID_NET_BT        3002  /* bluetooth: create sco, rfcomm or l2cap sockets */
AID_INET          3003  /* can create AF_INET and AF_INET6 sockets */
AID_NET_RAW       3004  /* can create raw INET sockets */

AID_MISC          9998  /* access to misc storage */
AID_NOBODY        9999

AID_APP          10000 /* first app user */

"root",      AID_ROOT
"system",    AID_SYSTEM
"radio",     AID_RADIO
"bluetooth", AID_BLUETOOTH
"graphics",  AID_GRAPHICS
"input",     AID_INPUT
"audio",     AID_AUDIO
"camera",    AID_CAMERA
"log",       AID_LOG
"compass",   AID_COMPASS
"mount",     AID_MOUNT
"wifi",      AID_WIFI
"dhcp",      AID_DHCP
"adb",       AID_ADB
"install",   AID_INSTALL
"media",     AID_MEDIA
"shell",     AID_SHELL
"cache",     AID_CACHE
"diag",      AID_DIAG
"net_bt_admin", AID_NET_BT_ADMIN
"net_bt",    AID_NET_BT
"inet",      AID_INET 
"net_raw",   AID_NET_RAW
"misc",      AID_MISC
"nobody",    AID_NOBODY
You will need to also understand the way file permissions are represented:

Example = drwxrwxrwx

-Use Root Explorer to find the UID, GID, and permissions for a file. Permissions are the string that looks like some variation on 'rwxr-xr--' next to each file. Long press and choose "change owner" to get the UID and GID. You just want the number next to "owner" and "group", respectively.

-If you're replacing a file, look up these settings for the existing copy and use them. If you're adding a file, just find a file that does the same functions and copy what it has (for example, installing an app to /system/app? Just look at these settings for any other app in that directory).

-MODE is technically a 4-bit string, but the first character can be omitted. There doesn't seem to be any android file permissions with the first character set. For good practice, I think it's safe to assume you can always use a leading 0 unless you know otherwise for something specific. Or, just use a 3-digit MODE, which says to leave those settings as they are (disabled by default). (I.e. 0644=644).

The next 9 characters define the file permissions. These permissions are
given in groups of 3 each.

The first 3 characters are the permissions for the owner of the file or directory.
Example = -rwx------

The next 3 are permissions for the group that the file is owned by.
Example = ----rwx---

The final 3 characters define the access permissions for everyone not part of the group.
Example = -------rwx

There are 3 possible attributes that make up file access permissions.

r - Read permission. Whether the file may be read. In the case of a
directory* this would mean the ability to list the contents of the
directory.

w - Write permission. Whether the file may be written to or modified. For
a directory* this defines whether you can make any changes to the contents
of the directory. If write permission is not set then you will not be able
to delete* rename or create a file.

x - Execute permission. Whether the file may be executed. In the case of a
directory* this attribute decides whether you have permission to enter*
run a search through that directory or execute some program from that
directory

You set these permissions using the following binary based numerical system:
Code:
Select Code
0:  ---   No Permissions (the user(s) cannot do anything)
1:  --x   Execute Only (the user(s) can only execute the file)
2:  -w-   Write Only (the user(s) can only write to the file)
3:  -wx   Write and Execute Permissions
4:  r--   Read Only
5:  r-x   Read and Execute Permissions
6:  rw-   Read and Write Permissions
7:  rwx   Read, Write and Execute Permissions
Default Linux permissions:

For Files:
"Read" means to be able to open and view the file
"Write" means to overwrite or modify the file
"eXecute" means to run the file as a binary

For Directories:
"Read" means to be able to view the contents of the directory
"Write" means to be able to create new files/directories within the directory
"eXecute" means to be able to "Change Directory" (cd) into the directory
Most of the time you set "Read" and "eXecute" together on directories (kind of useless when set by themselves)


Interestingly through further research it seems this system is based on the Octal Binary system...I may be wrong...
Code:
Select Code
Octal

Binary is also easily converted to the octal numeral system, since octal uses a radix of 8, which is a power of two (namely, 23, so it takes exactly three binary digits to represent an octal digit).
The correspondence between octal and binary numerals is the same as for the first eight digits of hexadecimal in the table above.
Binary 000 is equivalent to the octal digit 0, binary 111 is equivalent to octal 7, and so forth.

Octal	Binary
0	000
1	001
2	010
3	011
4	100
5	101
6	110
7	111

Converting from octal to binary proceeds in the same fashion as it does for hexadecimal:
658 = 110 1012
178 = 001 1112
And from binary to octal:
1011002 = 101 1002 grouped = 548
100112 = 010 0112 grouped with padding = 238
And from octal to decimal:
658 = (6  81) + (5  80) = (6  8) + (5  1) = 5310
1278 = (1  82) + (2  81) + (7  80) = (1  64) + (2  8) + (7  1) = 8710
Flash boot partition

This uses the following command but with some caveats:
Code:
Select Code
write_raw_image("path to boot.img", "boot");
An example of this commands use would be to flash a custom kernel, as far as I can tell though you need to place the boot.img in a temp file before the actual flash (clarification on this would be helpful). You would therefore use the following commands as part of your edify script:
Code:
Select Code
package_extract_file("boot.img","/tmp/boot.img");
write_raw_image("/tmp/boot.img", "device-specific-boot-partition-mount-point");
delete("/tmp/boot.img");
It seems this may only be for specific handsets though e.g HTC, having looked through quite a few updater-script files from maguro zips it seems this can just be flashed directly with the following command:
Code:
Select Code
package_extract_file("boot.img", "/dev/block/platform/omap/omap_hsmmc.0/by-name/boot");
Many thanks for further clarification on this particular command from efrant below:

I feel more comfortable using something like this:
Code:
Select Code
package_extract_file("boot.img", "/tmp/boot.img");
run_program("/sbin/busybox", "dd", "if=/tmp/radio.img", "of=/dev/block/platform/omap/omap_hsmmc.0/by-name/boot");
delete("/tmp/boot.img")
The second line is using the "dd" command to flash the image.

The dd command (included in busybox) is:
Code:
Select Code
dd if=xxx of=yyy
where xxx is the source image/partition and yyy is the target image/partition. So, for example, to flash a radio image stored in /sdcard called xxlf1.img to a GNex, it would be:
Code:
Select Code
busybox dd if=/sdcard/xxlf1.img of=/dev/block/platform/omap/omap_hsmmc.0/by-name/radio (I've added "busybox" the the beginning, just to be explicit.)
So, to put it in edify format, it becomes:
Code:
Select Code
run_program("/sbin/busybox", "dd", "if=/sdcard/xxlf1.img", "of=/dev/block/platform/omap/omap_hsmmc.0/by-name/radio");
However, as I said, I believe your one line:
Code:
Select Code
package_extract_file("boot.img", "/dev/block/platform/omap/omap_hsmmc.0/by-name/boot");
would work.

Further Commands:

In progress...


So, this is by no means an exhaustive list and I would appreciate it that if I have made any mistakes people make me aware in this thread and I can update this tutorial.

I would also like to add further commands and their uses, if people can provide more I will add them too.

I hope this helps people out! Many thanks!