489 Commits
froyo ... ics

Author SHA1 Message Date
1e2da51172 Merge branch 'ics' of github.com:CyanogenMod/android_bootable_recovery into ics 2012-06-07 11:58:13 +01:00
8ba9a6335b Fix build on gcc 4.6.
Several programs were not linked against libcrecovery which has the __system
function.

Change-Id: I12b33a9157ab74825129896d0f2177fa83638464
Signed-off-by: Evan McClain <aeroevan@gmail.com>
2012-05-18 01:28:26 -04:00
9a7615326e use TARGET_RECOVERY_FSTAB location if defined
If TARGET_RECOVERY_FSTAB is defined use this location to find
recovery.fstab

Change-Id: Ic4cd26f5be064586359f39ff82d7f9b09ce57f53
2012-05-06 11:14:41 +02:00
08bedb21d8 remove copyright, switch to AOSP license
Change-Id: I53485386d68726f5c0596ac842e6a480d4463b74
2012-04-10 13:23:50 -07:00
7ba8a30150 Merge pull request #21 from IEF/ics
Fix BCB clearing for eMMC devices.
2012-04-09 09:34:19 -07:00
IEF
21b8a12300 Always call set_bootloader_message(), not just for MTD-devices. set_bootloader_message has a built-in check for MTD/eMMC via fstab. 2012-03-07 16:50:26 +01:00
d87b8df56d Remove random offset message during installation
Change-Id: I2281a571e37ba9fac2b99806ce9c63e591b4d39f
2012-02-13 16:18:53 -05:00
1c50ff29e6 Fix ui menu bug for long menus.
Change-Id: If009dee6b7597daeec62dd65baa7ad35e1adec5d

Conflicts:

	ui.c
2012-01-31 20:28:36 -08:00
a465962667 use source built e2fsprogs! thanks cvpcs!
Change-Id: Id3067d4da53643ae1af0b9f15445262afda7b197
2012-01-30 22:51:36 -08:00
e2a66586a3 fix up key value parsing
Change-Id: I05e821cd1215c44be780694644e568676fd67565
2012-01-29 14:03:04 -08:00
10034aabc9 Merge "Always run adbd as root in recovery." into ics 2012-01-28 09:26:53 +03:00
638103922f more derpage
Change-Id: I878386195a408d2a98137816515f5eaaa52ccf79
2012-01-27 02:58:40 -08:00
67e73e1559 fix build
Change-Id: Iac099f5a275b9633ed30d9e4a84acb99a57c4434
2012-01-27 02:46:19 -08:00
3cdfd138fa Various fixes to fix rendering of text. There will always be 3 lines of log shown. The menu can have long items in it now, rather than being truncated. The log text will be bottom aligned.
Change-Id: I09289e053c8ab673814318da55302efaab0404de

derp

Change-Id: I3fc31f5ea311c73c0ec999aa77d3fa0d01238001
2012-01-26 22:56:33 -08:00
ccc1fdb386 derp
Change-Id: I5ffece3af80c0c328c61975d46f4de4cb22f2282
2012-01-26 16:49:58 -08:00
18e3f62ad2 Fix up the mess around fonts and defines.
Change-Id: I3df3dae482ac6f8e9ddcbe2946dba43428bf46b1
2012-01-26 16:49:33 -08:00
b20a4812ba reversed the logic
Change-Id: I62c104ee0c9218f929c10eda31f4bf5828b0de22
2012-01-26 15:29:08 -08:00
5617056cb8 Recovery : Show menu if in non user initiated mode and error occurred
When using rom manager and applying a zip, if one encounters an error in recovery,
they're left on a screen with no visible controls (Forcing to hard reset phone).

Change-Id: Ia9b2f396fc95c7972a5a5580e1a50adf4af26060
2012-01-26 15:20:57 -08:00
aa3c3d429b Respect volume length when formatting ext4 when restoring
This is needed for device encryption to work properly (there must
be space for a 16 KB footer at the end of the partition, which is
usually specified by the length option).

And yes, the old signature of make_ext4fs was wrong, but worked
anyway because the related header was not included and the compiler
let it pass an as implicit delcaration.

Change-Id: Ied7ec70bebc120cc2917771f59eeaeb7ea76bf8d
2012-01-26 15:16:53 -08:00
cd3705e4ab remove power off. not useful in the main menu.
Change-Id: I8923d1e878994c3516798118961b4cdaa82ddc88
2012-01-26 15:09:08 -08:00
4f78176329 Misc tweaks / bug fixes
- readd "power off" to the main menu
- fix bug where stdout overflows into menu text
- remove +++++Go Back+++++ from main menu as there is nothing to go back to (detects menu depth)

Change-Id: Icb84ac86e55712412d07add0ab76955d7902f07c
2012-01-26 15:08:15 -08:00
de338e56b3 Big Font Mod and Roboto Fonts (XHDPI, HDPI, and MDPI)
- lets xhdpi devices (Galaxy Nexus, Xoom, etc) have a bigger font size (15x24)
- port Google's Roboto font into recovery for both XHDPI, HDPI, and MDPI font size, make them optional (LDPI is too small!)

(credits to gweedo767 for big font)

Change-Id: I621dbc7c8ac30a8f16039ce64720512e3e63881a
2012-01-26 14:57:07 -08:00
5a44ceb692 remove hacky board define around usb storage mounting on /data/media devices.
Change-Id: I2d382762271a2cfc6d83454160ed127b7457c88c
2012-01-26 14:56:56 -08:00
4c8e2482a6 Who approves this stuff... use get_volume_for_path('/sdcard') and check for null...
Revert "Hide "mount USB storage" option from mount menu when the board has a virtual sdcard"

This reverts commit e510810c71.
2012-01-26 14:47:34 -08:00
059db9bfb6 Always run adbd as root in recovery.
At present, invoking "adb shell" while in recovery results in:

- exec '/system/bin/sh' failed: No such file or directory (2) -

"adb shell" should invoke /sbin/sh, but cannot as /sbin and /sbin/recovery
lack other-user execute permission.  Invoking "adb root" to restart adbd as
root _does_ work, however this behavior may not be intuitive to users who
encounter the above error.

The solution implemented here is to always run adbd as root in recovery, so
it has permission to run /sbin/sh.  Furthemore, user shells in recovery are
not particularly useful and "su" doesn't exist, thus "adb root" is likely
to be invoked anyways.

Change-Id: Iaaa25090e85d970e9a076fef068f5fae8202ab0b
2012-01-26 16:05:56 -05:00
e510810c71 Hide "mount USB storage" option from mount menu when the board has a virtual sdcard
Change-Id: I4e59768e9f34f0fb33d88ad382feaa2515d70bc4
2012-01-15 02:37:34 -05:00
4e50004a0e fix yes/no issue where the index is 0 and not 7 2012-01-13 14:16:03 +00:00
d43f5a01bf merge, and fix extendedcommands.c for yes/no 2012-01-11 11:10:07 +00:00
1cb1ce343b fix yes/no 2012-01-11 11:08:31 +00:00
9487d2965f add comments around /data/media
Change-Id: I35ad822ed602e2b1018f1e1a0d67499867b60a40
2011-12-18 13:49:52 -08:00
d4c04cb00b Merge branch 'ics' of git://github.com/CyanogenMod/android_bootable_recovery into ics 2011-12-18 13:40:30 -08:00
e9039792c9 5.5.04
Change-Id: Idb2f70a8a02d2f9418356f011c9392f8d9b1d1d2
2011-12-18 11:53:08 -08:00
f0c389ddcd nandroid/root/extendedcommands: attenuate for /data not being auto in fstab
Change-Id: I0e7bec03bb29f1ae72f23321f89cf704e54ff4d9
2011-12-18 02:52:30 -05:00
357a2f5109 extendedcommands/nandroid: remove internal options if no sdcard and is_data_media
-force /data as backup_path if volume for /sdcard is null and the same is true

Change-Id: I927b723cde5b519d81402c6d841f2424627253e8

Conflicts:

	nandroid.c
2011-12-18 02:52:21 -05:00
db524c28b4 Merge "Fix wipe from android settings for devices with /datadata" into ics 2011-11-30 08:14:02 +03:00
a64c697333 Fix up the autoinclusion rules for the recoveryimage target. 2011-11-27 14:07:29 -08:00
1659814576 Fix wipe from android settings for devices with /datadata
Change-Id: I2d80d580bc2ccdc756f411dbe514270d5c245816
2011-11-26 22:44:29 +07:00
a9017dabc5 remove redundant fix 2011-11-23 14:07:06 -08:00
ddc1241a36 fix missing prebuilts in recovery. mmc bootloader message support. fix segfault happening due to C structs not being zeroed out. 2011-11-23 14:06:26 -08:00
edae7a5b0f Merge "recovery: fix non-MTD mounting (uninitialized variables)" into ics 2011-11-22 21:45:36 +03:00
d2eecca360 Update extendedcommands.c one "No". 2011-11-21 14:37:29 -08:00
b062713ee0 Merge pull request #13 from chris41g/gingerbread
Update extendedcommands.c one "No".
2011-11-21 14:37:00 -08:00
d280f6e0d8 rewrite mtd_restore_raw_partition to use the new aosp code 2011-11-21 11:22:04 -08:00
b0a63d857f Update extendedcommands.c one "No". 2011-11-20 15:26:53 -06:00
ff316eb739 recovery: fix non-MTD mounting (uninitialized variables)
Mounting failed due to invalid (garbage) fs_options
2011-11-19 13:31:21 +07:00
21ad8d04dd remove dedupe 2011-11-16 18:28:20 -08:00
0e7d88613a Support custom graphics.c. Set the recovery timeout to 1 hour. 2011-11-16 16:47:53 -08:00
0df56f4db4 wip 2011-11-16 16:00:35 -08:00
070dafc6fe fix flashing, which was breaking 2011-11-16 23:48:50 +00:00
63fb0eedbd Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-11-12 01:30:08 +00:00
88a233d5fa Fix up bmlutils to include fat.format automatically if rfs is found in the recovery.fstab. Use __system rather than run_exec_process.
Change-Id: I669bfb75cf0cc00364b815b54130c01786866406
2011-11-11 00:41:57 -08:00
2291705c41 Merge pull request #12 from DRockstar/gingerbread
Add RFS format support
2011-11-11 00:27:25 -08:00
7ef88155e0 fix advanced restore
Change-Id: I0805799343800912f8ea2caf9d06be4d59e9f4bf
2011-11-11 00:26:32 -08:00
a8f265dd6f Add RFS format support
Change-Id: Ifd1e5ce9875c3eaacc1cec1759b67e672894e279
2011-11-10 15:54:14 -06:00
e0bbe565af Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-10-30 19:32:02 +00:00
890b951a3d fix flash image for explicit bml path
Change-Id: Ifeccfb65d6a927440249f7ab2fd9b0512ccc491c
2011-10-29 21:38:53 -07:00
c971f76e45 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-10-30 02:30:05 +00:00
c9ea117b56 actually implement internal sdcard restore
Change-Id: I10799352768a2babb46dc9b74671fd3b1049583d
2011-10-29 18:48:18 -07:00
b4812b5b34 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-10-29 01:30:07 +01:00
4fcd523ded fix driver looking for recovery, rather than checking the basename. fix badness in nandroid menu generation.
Change-Id: I7d7011e36583509f07534e4bc85ed8d567022d3e
2011-10-28 11:47:02 -07:00
7691202e89 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-10-28 01:30:05 +01:00
89ed0b7355 support backup and restore on internal sdcard
Change-Id: I6295b5bb7ada967ca223758be58d555c1a2ff462
2011-10-26 21:25:34 -07:00
46ba04b01b Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-10-25 01:30:07 +01:00
f0e81c4643 deprecate BOARD_USES_RECOVERY_CHARGEMODE
Change-Id: Iac0a457335220d905f478b6941990adb185ba426
2011-10-23 20:17:59 -07:00
24ba583ec2 deprecate BOARD_USES_RECOVERY_CHARGEMODE
Change-Id: Ibda5585257f4380abccd97036eae3e747779a9e9
2011-10-23 20:17:49 -07:00
85850a553b Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-10-24 01:30:32 +01:00
6cf153cd50 Revert "zero the partiiton before writing to it."
This reverts commit 17fd32d0a2.
2011-10-23 13:28:53 -07:00
04fae9d67e fix the disabled states in init.htc.rc....
Change-Id: I475f470bc9d638383f0fd69ba0c43fe7c7928179
2011-10-23 13:20:50 -07:00
17fd32d0a2 zero the partiiton before writing to it.
Change-Id: I4717fd45c822a2026f907914c900cf8c60d8a48d
2011-10-22 22:34:58 -07:00
441031dadc minui: add ability to synchronize current key state
If a key is down prior to the time of initialization, we would not get the
down event for the key, and thus think that the key is not pressed.

Add an interface that allows one to provide a callback to execute
on all keys that are currently down.

Change-Id: I2a4096c0cb4c7c7a9a80d207835f168a0b418413
Signed-off-by: Dima Zavin <dima@android.com>
2011-10-12 15:53:32 -07:00
9996a5cd15 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-10-05 01:30:05 +01:00
2e85422f89 juggle around some of the ext handling tools. add setprop link
Change-Id: Ic091d682d42d14d4942e481a6099e04bb8d7ac21
2011-10-04 16:33:30 -07:00
f908e5bdbe Merge pull request #11 from DRockstar/gingerbread
edited nandroid.c to include rfs in fs lists, required for tar restore with rfs file systems
2011-10-04 16:32:14 -07:00
a87bb5f57b edited nandroid.c to include rfs in fs lists
Change-Id: I403331df04d6a4cf75fd898af42dec7aab5a1b59
2011-09-29 15:37:19 -05:00
f6abd409bb fix problem where the screen is sometimes all black in recovery
Change-Id: Ifa0b59e43eaf0bea9435aa4d96c5b0fc4f10fbfe
2011-09-27 13:09:48 -07:00
b1c19c1334 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-09-23 15:00:24 +01:00
95fb821c19 shuffle some code
Change-Id: Ifb5afe8ef6de7b6de58dfc07a30c1f89b5c1eb08
2011-09-23 03:57:25 -07:00
0917a7aedf note usage of extendedcommand;
Change-Id: Iab212b3a0cc5259630883c4783a28bcecd9e7028
2011-09-23 03:50:29 -07:00
3681b91861 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-09-23 01:30:31 +01:00
81a61516c9 fix text
Change-Id: I56e682be485d1bb8191f54b5df1fc2634b6d9ad5
2011-09-22 15:10:20 -07:00
fdfb636336 update recovery with new 3D images
Change-Id: I6d52fd1db27fdf1b61f41f598a2209b70385b106
2011-09-20 14:16:46 -07:00
7f13e150cf more cwr5 work.
Change-Id: I72bb14ef25a9067ccde3e40ea989c7990512687a
2011-09-08 16:55:35 -07:00
30a937a954 cwr 5
Change-Id: I70cbb4df78b0bbc9d227d19aa6d9434eba2b540d
2011-09-05 21:14:06 -07:00
88e0899617 minui: events: only open input devices with EV_KEY and/or EV_REL
Change-Id: I8283d7aaa0f66d488f462cd108350cc49657a745
Signed-off-by: Dima Zavin <dima@android.com>
2011-09-02 14:55:20 -07:00
365836736c minui: events: add ability to poll on non-input fds
Change-Id: Iad52a6f2adcae0068d252d6163586f9d7b93121d
Signed-off-by: Dima Zavin <dima@android.com>
2011-09-02 14:55:20 -07:00
bc29063bf4 minui: events: refactor event acquisition
Events are now delivered through a callback mechanism during
a call to ev_dispatch(). This will allow us to extend the events
code to handle other devices/fds, not just input. One such example
is the ability to process uevents.

During initialization, we provide an input callback to ev_init
that gets called when a new event is encountered during dispatch.

ev_get has been removed and replaced with ev_get_input() helper
function that can be called from inside the callback to attempt
to get an input event.

The existing client of ev_get in recovery has been split up such
that the input thread just calls ev_wait(); ev_dispatch(); and
the input_callback handles individual events by using the
ev_get_input() helper.

Change-Id: I24d8e71bd1533876b4ab1ae751ba200fea43c049
Signed-off-by: Dima Zavin <dima@android.com>
2011-09-02 14:55:20 -07:00
cf2de074f6 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-09-02 01:30:05 +01:00
bf5a60a034 add some error logging to mmcutils
Change-Id: I4c886822e7d47a0b5636bfc656039b171303d4e5
2011-08-31 23:28:21 -07:00
5268131918 allow explicitly provided mount locations
Change-Id: I3930b2abeb81c09c25c1750f0545c233c0d5a4a2
2011-08-31 23:26:45 -07:00
d6bf694ff0 allow overriding mke2fs and htcbatt
Change-Id: Ibff628238c39661874e1e55bfcf6d51516b6bdd5
2011-08-31 23:25:23 -07:00
4daf48a10b minui: graphics: add interface for framebuffer blank/unblank
Change-Id: I5c3ee61cbf6fadae50f10b9f2e73caceaa5048a7
Signed-off-by: Dima Zavin <dima@android.com>
2011-08-30 11:59:20 -07:00
3c7f00ede6 minui: graphics: add ability to query font size
Change-Id: I5e8f477b7b205794f2975f12e6b6010c177f6052
Signed-off-by: Dima Zavin <dima@android.com>
2011-08-30 11:58:24 -07:00
c2ddaea83a change recovery images to match blue holo theme
Change-Id: I912d3ab32973c5c5e7b6b1749698f8a71d884fa3
2011-08-19 16:56:31 -07:00
7f33591677 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-08-18 01:30:08 +01:00
01ba8bc552 updated mke2fs from motorola that should also work on non-neon devices.
Change-Id: If66906147da2a3d84745dc1e58a180dec0d1d156
2011-08-17 16:44:22 -07:00
337dcdd011 ver
Change-Id: Id02cd499546b72ab0eeb545a4479e1ba977b13cf
2011-08-15 20:33:56 -07:00
b3122e51a0 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-08-15 01:30:08 +01:00
6afbcdc651 handle mounts in recovery if the have only one argument
controlled by BOARD_RECOVERY_HANDLES_MOUNT if it is not set
the recovery will behave like before.

this allows the recovery to handle commands like 'mount system'
it is needed for devices with two different filesystem in
recovery.fstab like RFS and EXT4 cause the regular recovery
behaviour will only generate a fstab for mounts of fstype2
and ignore the other fstype. This will also enable things like

run_program("/sbin/busybox", "mount", "/system");

on those system.

Change-Id: Ib10ffc7735a2edb8dd32be230ba885d5d2744f73
2011-08-13 13:19:39 +02:00
97c7df2f33 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-08-04 01:30:08 +01:00
5e922a4bf4 Merge "adding text output for battery stats wipe. just a confirmation that it completed successfully" into gingerbread 2011-08-04 04:23:04 +04:00
5ee0380c67 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-29 01:30:08 +01:00
04a211f372 Merge "htc offmode charge: update daemons and init.htc.rc. remove png files needed by old offmode charge. add htcbatt daemon" into gingerbread 2011-07-29 03:13:34 +04:00
7b2697f66f Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-27 01:30:08 +01:00
0d651b1b70 Merge branch 'gingerbread' of git://android.git.kernel.org/platform/bootable/recovery into upstream-2.3.5 2011-07-26 13:06:34 -04:00
d41c2c8e89 htc offmode charge: update daemons and init.htc.rc. remove png files needed by old offmode charge. add htcbatt daemon
Change-Id: Id9a521decaa381b5d4cffca3fd51814a07f027ca
2011-07-24 11:37:47 -04:00
1a873797f7 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-22 01:30:08 +01:00
7e70b6be7f Deleted check for equality in flash image header and partition
header.

Skipping flash after just checking a 1K header is
incorrect in the case where something scribbles over
the partition after the header because flash_image
would not be able to rewrite the whole
partition due to this check.

Also, Samsung devices use a combined boot and
recovery image where the header is the same even if the
initramfs changes and these do not get flashed even
if the boot.img is actually different due to different
appended initramfs.

Change-Id: I53ab0a23347cdf1fa7ff58dff37e812fd84645be
2011-07-21 18:41:49 -04:00
45df699a5e cwm: Clarify on-screen labeling of recoveries
Koush is the only authoritative source for clockworkmod recoveries,
so lets try to reduce confusion as to what is "officially supported"
and what isn't...

Change-Id: Icb0f93530e69829ce69f2500b6f29df350099273
2011-07-21 16:31:57 +01:00
81a1ffea20 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-20 22:52:04 +01:00
c915937ebd herp
Change-Id: I4aace74f1d3638241939f842a4526f9724cf5dac
2011-07-20 01:26:02 -07:00
137c9f41c4 fix crash
Change-Id: I65be72b5cd8c0679fb328a78eb4016e2c89ec9b0
2011-07-20 01:19:44 -07:00
d07ffd72cd Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-20 01:30:07 +01:00
eb557e4233 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-19 01:30:06 +01:00
55e6e7dc4f graphics.c: revert RGB8888 support
Change-Id: Id2a4c8055c2bc82120871293235cf98c7c5b50e6
2011-07-18 16:42:57 -07:00
0bf56815b7 graphics.c
Change-Id: I5d9b5508a568b2ce47123524a5978628c013a1e8
2011-07-17 20:38:32 -07:00
d5d1fcdc96 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-15 01:30:07 +01:00
6242a8bc9b Support multiple recovery updater extensions.
Change-Id: I787c086223b674050c0a12fc575add9badb471af
2011-07-14 15:12:20 -07:00
cd264e7f94 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-14 01:30:07 +01:00
8918673cf7 Merge "Check pointer for null before dereferencing" 2011-07-13 15:42:09 -07:00
b2ceb696d0 Check pointer for null before dereferencing
Change-Id: Ie7563bf8fb2d627454010de7388d0992e2accf91
2011-07-13 15:24:38 -07:00
5c69bdd735 graphics: use gr_flip_32() only if we're really on a 32bpp device.
Change-Id: I996b2dadf43477064480a47ee536e6ec395a6aad
2011-07-13 12:19:47 -07:00
94a4babac7 Google Music stores their music cache /sdcard/Android...
Can't back this up unless we start selectively excluding apps, which is gross.

Most apps only store interstitial files here, so it is not a huge deal.
Apps need to be able to work properly without an SD card. (Oops ROM Manager).

Revert "backup and restore of /sdcard/Android (see getExternalFilesDir)"

This reverts commit 50732e3c67.

Conflicts:

	Android.mk

Change-Id: I3978c5521b4f29c4d709c3bb6a8fa7e53678a79e
2011-07-13 10:34:23 -07:00
e87f9e695e support explicitly provided device paths
Change-Id: I1ddb862f62932d2e1525d8b317613bf67a64093e
2011-07-12 18:07:45 -07:00
6057bade5c Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-13 01:30:07 +01:00
eb3aa6ff32 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-12 16:15:06 -07:00
1115c8f325 use sha256 instead
Change-Id: Ie4e7bfec568c786f58367f55fee866b6aae9732b
2011-07-12 16:15:05 -07:00
8d92ae052e Merge "Update usb_connected() to support new gadget driver" 2011-07-12 15:39:11 -07:00
70f25bead8 dedupe: include external/openssl/include for host build
Change-Id: I65907c5fa5736c0587567b0d6b4cfb2ce155472e
2011-07-12 14:49:39 -07:00
32ac1666e2 size
Change-Id: I0b43832bc896864abb0a659fc3bf58793879a2e8
2011-07-12 14:03:03 -07:00
7e6067e36c Update usb_connected() to support new gadget driver
Change-Id: Iabe8be5bbfa7d2bf1d13280c8734ff75b62a152f
2011-07-12 12:38:46 -07:00
b0462e6ae2 Remove the simulator target from all makefiles.
Bug: 5010576

Change-Id: Ib465fdb42c8621899bea15c04a427d7ab1641a8c
2011-07-11 22:11:45 -07:00
491f4847f6 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-12 01:30:05 +01:00
80cd7707c0 unnecessary, but clean up the open files properly.
Change-Id: I58f571fd00f914cba1102dd89d50dc08d917b671
2011-07-11 14:41:44 -07:00
24c802b05e fix up symlinks and lack of lchmod
Change-Id: Iccfddabe239b97a20b0b5302af4488482fffd86b
2011-07-11 14:40:17 -07:00
7f3a8c90b0 fix copy_file fail
Change-Id: I46e31ee17255e76a3c64a9e661dc74e636a345ec
2011-07-11 14:32:02 -07:00
e8bdefda33 build fixes and arm support.
Change-Id: I96fa6366c8bb1406d89f944f0fd1733bde565126
2011-07-11 14:13:43 -07:00
de7025e43c wtf
Change-Id: Id473833012794723c3fae22edc1cb436efdcda85
2011-07-11 13:27:34 -07:00
fd6a28be5d working restore
Change-Id: If5963348d2e9ac27164b1a929937a3ec3a4ecfa7
2011-07-11 13:26:14 -07:00
4f1c5e37f4 working restore
Change-Id: Id152f5f28b3836bae5884fcf2bec67b599e991c7
2011-07-11 13:25:04 -07:00
67700e791a dedupe for cloud backups
Change-Id: If88285763d89323a0417d9cc44cd161e906d2b69
2011-07-11 12:26:45 -07:00
3f2e286747 adding text output for battery stats wipe. just a confirmation that it completed successfully
Change-Id: I8c00521081b12f123c35239212f2b53dde3a7c8e
2011-07-10 22:48:39 -04:00
5e4f258ca2 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-10 01:30:07 +01:00
bc9dc6fc48 Merge "minui: graphics: finish updates for 32-bit framebuffer in recovery" into gingerbread 2011-07-09 22:05:10 +04:00
a2bc7245f7 Merge "[PATCH] [recovery]: Fix recovery mode display for RGB8888 display." into gingerbread 2011-07-09 22:05:00 +04:00
1c2238b3af minui: graphics: finish updates for 32-bit framebuffer in recovery
work around slight issue on Sensation device and Shooter, by using xres_virtual instead of xres to get the 4 extra bits needed. based of original changes from toastcfh and modified to not be hard coded 32 bit and work with 16 bit as well.

Change-Id: I15850a0969050598ffc14279b8b50c6fcb4682f7
2011-07-09 12:32:05 -04:00
128f131e41 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-09 01:30:06 +01:00
aaad77fc80 move choose zip option first in apply zip menu, update.zip is on main menu 2011-07-08 10:11:27 -07:00
9154b8cfd2 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-07-08 01:30:07 +01:00
933487868f Add missing commands to recovery init.rc
Wrote some missing items in recovery, most notably the serial number so that it shows up correctly on adb.

Change-Id: If430c0b78191c8d77f781aa605b5081571451775
2011-07-07 13:29:43 -07:00
e9ab999990 Merge "Add a new 'Show log' extended function. Could also be used to report last lines from log on error." into gingerbread 2011-07-07 23:59:59 +04:00
a75c067df4 Support overriding of the bml partition used for boot and recovery. This is not ideal, because that means that there are different flash_image binaries for different samsung phones. But as far as I know, there is no way to find out which bml device is boot or recovery.
Change-Id: I5e3b83dd9267a275def003182c1bd5d2cf585896
2011-07-07 12:55:02 -07:00
50732e3c67 backup and restore of /sdcard/Android (see getExternalFilesDir)
Change-Id: I6306464cdce4e3b48e0d109284e5606f65a84ee2
2011-07-07 12:44:05 -07:00
78f44e8bdf [PATCH] [recovery]: Fix recovery mode display for RGB8888 display.
Change-Id: If9cf141d89ef3b537d1228148cb324af7dcc11db
2011-07-07 02:02:51 -04:00
0b06fc0696 recovery: Ignore wipe command from bootloaders that always send it
Change-Id: Ia93e1aae4d07ff609a252ae60850c739b02f2969
2011-07-07 01:09:52 +01:00
67d358cf4e Add a new 'Show log' extended function.
Could also be used to report last lines from log on error.

Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>

Change-Id: I3d9e51f4e81e48f20120e2449ccde651efae8d07
2011-06-30 01:26:13 +02:00
718a2f7872 init.rc: Simplify logic for starting adbd in recovery
Always start adbd if ro.debuggable=1 rather than basing it on user preference
in persistent system properties.

Use new D001 product ID, which I just allocated for "android recovery mode"

Change-Id: I6f1eac5257eaad2e538c0a8dd549ad89219efa3e
Signed-off-by: Mike Lockwood <lockwood@android.com>
2011-06-29 10:22:04 -04:00
ca0fc46095 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-29 01:30:06 +01:00
b4261d9ddd hopefully fix the logic. also address that the tune2fs and mke2fs binaries provided by codeaurora is arm v7, and thus can not be included for all devices.
Change-Id: I9ca996c904579fdb5df9a5453d2f1b9448f505db
2011-06-27 17:54:16 -07:00
47591ce0d0 Revert "use BOARD_HAS_SMALL_RECOVERY instead of BOARD_HAS_LARGE_FILESYSTEM"
This reverts commit 5ab3281dbe.
2011-06-27 17:52:25 -07:00
31c3ccf531 Revert "reversed logic"
This reverts commit 7305f7d956.
2011-06-27 17:52:15 -07:00
6c88ec2e8b Revert "reversed logic"
This reverts commit 9e08693670.
2011-06-27 17:52:07 -07:00
eed82c0f81 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-28 01:30:07 +01:00
9e08693670 reversed logic
Change-Id: Ie29418d7e3d82345f82888ade3eabdf6af5865f6
2011-06-27 11:30:31 -07:00
7305f7d956 reversed logic
Change-Id: I8fb671556b6fdfac9b34d48106cb3365c80bbe5a
2011-06-27 11:29:55 -07:00
5ab3281dbe use BOARD_HAS_SMALL_RECOVERY instead of BOARD_HAS_LARGE_FILESYSTEM
Change-Id: I7fe8bf226bdcf6429df62ae7fee82b5dabe6725b
2011-06-27 11:06:10 -07:00
b986fe24b4 Revert "Reverts: http://review.cyanogenmod.com/#change,6130"
This reverts commit a42d2b1e24.
2011-06-27 11:03:04 -07:00
aee5f85b29 fix up libreboot dependency to librebootrecovery
Change-Id: If39697943554538c938edaa478976eed9feb82d7
2011-06-27 11:02:44 -07:00
40fd4565d7 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-27 01:30:06 +01:00
a42d2b1e24 Reverts: http://review.cyanogenmod.com/#change,6130
The system() call implemented in bionic/libc/unistd/system.c
depends on paths.h which sets _PATH_BSHELL to "/system/bin/sh"
which is incorrect for recovery - recovery cannot
depend on /system being mounted or even sane because /system
could be corrupt when recovery is used.

We need _PATH_BSHELL to be pointing to /sbin/sh - and
therefore bootable/recovery has its own __system() call
implemented in bootable/recovery/libcrecovery that sets
_PATH_BSHELL as well as makes sure environ is used in
the call to execve.

Change-Id: I2e5fd9c259e4fd0a9aad826a297fd3233a50a7c1
2011-06-25 18:41:05 -04:00
9759ede732 Use the callback function in the call to mkyaffs2image() in _wrapper
Change-Id: Iee385a602e33a44dfa0deee8af49133f16f09d2c
2011-06-25 18:40:18 -04:00
9d2629c1c4 Allow applying an OTA package manually from cache.
Change-Id: I8f78377555c658a992ca95cadf11b67ddc93fed8
2011-06-24 11:53:58 -07:00
3dbe66b71d Get the correct line_length.
Set the BPP and other fields and write it back, so the line_length comes back correctly.

Change-Id: I85e4e8223c79b9394ae1fb609b3026de62027ab8
2011-06-24 11:06:01 -07:00
fb04b87002 fix adb root in recovery
recovery's init.rc was missing lines that made adb root work.

Change-Id: I300e6997e3b5cb9c7b542b2012eed61deb2550f1
2011-06-23 15:30:34 -07:00
9d1bcdf7b8 Graphics can handle stride != xres, and BGRA support.
Change-Id: Ifee94ac08028e62a40241a089ac7c36346fea3a3
2011-06-22 15:04:00 -07:00
7e58b65efb Fix starting adb in recovery mode
Change-Id: I8444f44d3194ff16ce54121633d5b255231393f5
Signed-off-by: Mike Lockwood <lockwood@android.com>
2011-06-19 02:52:01 -04:00
eb1ecab9bb Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-17 01:30:06 +01:00
11cff33332 bug fixes
Change-Id: Iadce53c6fbd4fe07d899e18c94198ec2e3a60f0d
2011-06-16 17:05:34 -07:00
fb3bd71038 fix crash bug.
Change-Id: I1afbc75815ffc72508942b73e40f67307f330ddf
2011-06-16 14:13:02 -07:00
e909c69169 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-16 01:30:06 +01:00
7905c80940 bug fixes
Change-Id: I1125db9cb1a12a95060f7673965fd40994a78c5b
2011-06-15 00:00:55 -07:00
fcb87af735 fix build
Change-Id: I3701f71ed9ecf5b6879e12ab6f618d5b678ef2f3
2011-06-14 23:44:39 -07:00
55e5e7b59a cleanups for tar and /data/media support
Change-Id: I4afe3a8d4484f91b1e689d7b3aa4f137acd66e93
2011-06-14 23:39:59 -07:00
16cfb3c72f Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-15 01:30:04 +01:00
7126ef404c use new libreboot static lib for rebooting
relevant commit is here: http://review.cyanogenmod.com/#change,6128

Change-Id: Id8587cba4017c322b3a5b89c1f994ade684f424a
2011-06-14 15:53:57 -05:00
2457adcdf7 Do not duplicate reboot.c
Change-Id: I2ed41ffd14372bec9e18865cf299e15abc67d689
2011-06-14 10:57:01 -07:00
0e961cd47a Fix up tune2fs republish bug
Change-Id: I43d77d52e73071777ee06bad360fe33f1cb747a0
2011-06-13 19:51:00 -07:00
5583712d6f Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-11 01:30:05 +01:00
4fbfc4610e 4.0.0.2
Change-Id: I6db9589e90f78e83201ebda90701b364223274d1
2011-06-10 10:52:31 -07:00
38a921435a make tar backups opt in.
Change-Id: Ib01131f3a65ce4114e73abe2c7ba42263d281844
2011-06-10 09:45:52 -07:00
94caefedb7 move the sdcard symlinker into process_volumes
Change-Id: I863fbeadea8428c7809260522316c493a6ea33ea
2011-06-10 09:17:30 -07:00
2e0964bed1 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-10 09:13:00 -07:00
4eff651c83 4.0.0.1
Change-Id: I0824973915621b86b41bace2abeeb5012cd1ffef
2011-06-10 09:12:52 -07:00
1f40b86175 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-10 01:30:05 +01:00
14d9e75577 added the efs partition to the do not format list since this holds the imei info.
Change-Id: I2644327c1dbaa63420b7eb7b1bce10377c0e0837
2011-06-09 18:37:28 -04:00
4d8c033203 also fix up the /sdcard symlink on startup
Change-Id: Ie7647b3fbb2543761d59b8c33ceeea36e3221c32
2011-06-09 14:19:04 -07:00
0e6b3f22ca Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-09 21:18:34 +01:00
967e15c44d 4.0.0.0
Change-Id: Ie7cf932287d5c7a2fed6cb7341a5b86d5baec2d8
2011-06-09 11:04:32 -07:00
5082299146 tar nandroid and /data/media support.
Change-Id: I9405e701887fc83c422c63c1dbf5ff087fff880d
2011-06-08 19:03:27 -07:00
5a4e03d120 am f84b2524: am 6ebedf00: am 82da01d6: Merge from gingerbread
* commit 'f84b25243d7ebeaca8424171f5ca3b192cc76d80':
2011-06-08 14:47:00 -07:00
7f72ad7934 am a94d9548: am 1117c69f: am 7172eb7b: Merge "Mute unharmful build warning at the top of the build log:" into gingerbread
* commit 'a94d954862fab26f6159ed7bb836ba6758a569fd':
  Mute unharmful build warning at the top of the build log:
2011-06-08 14:46:59 -07:00
f84b25243d am 6ebedf00: am 82da01d6: Merge from gingerbread
* commit '6ebedf0053ccefd414e5887db316f84bd8f6c44c':
2011-06-07 13:23:26 -07:00
a94d954862 am 1117c69f: am 7172eb7b: Merge "Mute unharmful build warning at the top of the build log:" into gingerbread
* commit '1117c69fe40dccfa6090d184094c4a6d407ab8d6':
  Mute unharmful build warning at the top of the build log:
2011-06-07 13:22:51 -07:00
5f77b7d715 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-07 01:30:05 +01:00
ebe7a1dcf6 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-06 02:13:04 +01:00
c56768cfb1 3.2.0.1
Change-Id: Ic043cdf147a6bb9f07ff0b1616d9f8fe8d9546dd
2011-06-05 16:28:25 -07:00
cdcb773cea Rename format_ignore_partitions to a forbid_format
There is a max length for system property names at 32 characters. The
old recovery property name was over this length.

Renamed the property to one much shorter so it is read properly.

Change-Id: Iecadd1218a64cab0c4fb94c5e910b920217580f1
2011-06-05 16:40:00 -06:00
ab0f3f79d6 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-06-04 03:00:06 +01:00
b3aac3c367 Merge "Fix 6 extentedcommands declaration warnings" into gingerbread 2011-06-03 06:44:41 +04:00
6ebedf0053 am 82da01d6: Merge from gingerbread
* commit '82da01d6a32c4fbfe57155c119d4669d7faba438':
2011-06-01 14:23:11 -07:00
82da01d6a3 Merge from gingerbread
Change-Id: I30902cdb19698f88a1ea57cf8c7667ef867d13a8
2011-06-01 14:08:15 -07:00
1117c69fe4 am 7172eb7b: Merge "Mute unharmful build warning at the top of the build log:" into gingerbread
* commit '7172eb7b623f4b30f5a709d639fcd3fb51cd6220':
  Mute unharmful build warning at the top of the build log:
2011-06-01 08:06:14 -07:00
7172eb7b62 Merge "Mute unharmful build warning at the top of the build log:" into gingerbread 2011-05-31 14:03:36 -07:00
8d2e1defb8 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-05-31 03:00:05 +01:00
01143a5630 remove logging, fix bug
Change-Id: Ie300222a3754a1ed7de5851a2298526a416da5d3
2011-05-30 15:22:04 -07:00
b2d30187d6 remove logging, fix bug
Change-Id: Ia7d0f5e7cdf64235bb2142d9143fff3f289ad605
2011-05-30 15:21:44 -07:00
88efbfb82b Fix 6 extentedcommands declaration warnings
Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
2011-05-30 13:27:05 +02:00
195e06be59 allow flashing only bml8 if explicitly specified.
Change-Id: Ie0d282105413b3a448436c9ee69206718e924754
2011-05-29 19:33:42 -07:00
aff130d843 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-05-30 03:00:05 +01:00
cf5195aa79 fix boot image not flashing properly, prevent the error in the future.
Change-Id: I6163e5a519ef28e9e9ea12d5a46d525d1d9d8fb2
2011-05-29 18:45:42 -07:00
ef5994fe29 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-05-27 03:00:05 +01:00
30712302e0 more logging
Change-Id: I2f5f37751f16c8b50f5c3ccf1eb56b9b52f44c6b
2011-05-26 17:49:56 -07:00
4187347329 fix formatting
Change-Id: Ic6162e5044b50544fab2d5aa83e1e22f373419d7
2011-05-26 17:30:43 -07:00
0bf1c6e598 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-05-26 22:19:42 +01:00
7adeadce47 fix up some implicit declarations
Change-Id: Ia98bb5bea04a9cb87bf1993687e7f91f46022509
2011-05-26 11:47:56 -07:00
e62132bb6d more fixes
Change-Id: Ic55d94ef69b6b8ea4ec2a6df708a9444e9d5f4e5
2011-05-26 11:29:29 -07:00
8a6bc77423 test
Change-Id: I25bd6846aea09247459c89ba98e6ac34c3debaa3
2011-05-26 11:14:15 -07:00
d3e66fed8b Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-05-26 00:00:10 +01:00
d79b7541f3 whoops
Change-Id: Ided86fe1991e5d9d6a707465429ec35ccc09743a
2011-05-25 10:47:41 -07:00
b7b7b37457 Mute unharmful build warning at the top of the build log:
diff: out/target/product/generic/obj/PACKAGING/updater_extensions_intermediates/register.inc.list:
No such file or directory

Change-Id: I269b1703b6091b343db45b1c5cdd0962c738788b
2011-05-24 16:11:05 -07:00
28a08efe15 Reconcile with honeycomb-release
Change-Id: I1205ca405fdaf586ebc349fbe83969e9694fab60
2011-05-20 12:45:51 -07:00
0b4eac9e01 also set UPDATE_PACKAGE in updater for old recoveries
Change-Id: I90e3feb0c1655279d58751ce800f299d9b4f3d03
2011-05-16 13:32:01 -07:00
666053ed26 3.1.0.1
Change-Id: Ia3115a520922254565532bbbb1e9aba6c680e80b
2011-05-16 10:04:53 -07:00
63605f1d45 Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-05-15 18:49:22 -07:00
20b516a408 set the env for UPDATE_PACKAGE (the source zip) for update-binary. This allows shell scripts to use the source zip.
Change-Id: Ia8118b31408f687780dd45e14f540a7e76619cba
2011-05-15 18:48:17 -07:00
49553c7561 Do not close the zip archive prematurely. It may be accessed later for a firmware update.
Change-Id: I31c298f75bbcdc7998221aa2b3aa334926343139
2011-05-13 13:01:26 -07:00
9ad8ba21b3 Allow per device unsafe-to-format partition list
The change switches is_safe_to_format() from a hard coded list
to a list that can be overwritten by system property.

Change-Id: Ie536044a912c3e88462831851d288a60fdc30e2b
2011-05-12 17:11:31 -06:00
4d5109cfa8 update to 3.1.0.0
Change-Id: I86d5aa2651c297ddf03279269da0c23819a06be1
2011-05-12 13:46:19 -07:00
e44b41a770 am c2a158db: Merge remote branch \'goog/honeycomb-mr2\' into honeycomb-LTE
* commit 'c2a158db9588e6ad290dd0f9171a190609900387':
  delay accessing misc partition until its device exists
2011-05-09 10:53:22 -07:00
c2a158db95 Merge remote branch 'goog/honeycomb-mr2' into honeycomb-LTE 2011-05-08 22:31:27 -07:00
54815c9dc9 Use TARGET_RECOVERY_PRE_COMMAND before calling __reboot() recovery
For the Power menu,
frameworks/base/core/jni/android_os_Power.cpp#L180
already uses TARGET_RECOVERY_PRE_COMMAND if
TARGET_RECOVERY_PRE_COMMAND is defined in the
BoardConfig.mk for a device to make a system() call before
calling __reboot() for recovery. This commit adds
the same thing to the other places that we know we are
getting into recovery using __reboot().

Change-Id: Ifd0394fed1e87b63d80d95e0e2a049004518e27e
2011-05-07 15:36:56 -04:00
c636b7300b am 90588820: delay accessing misc partition until its device exists
* commit '90588820b7110acf142d17457f0d10cd7cb57a8a':
  delay accessing misc partition until its device exists
2011-05-04 12:46:12 -07:00
90588820b7 delay accessing misc partition until its device exists
When the misc partition is on an emmc device, recovery can get started
and try to access it before the kernel has actually created the
device.  Try statting the device before reading or writing it; delay
up to 10 seconds waiting for the device to exist.

Change-Id: I93256db4b047c76020490e8a3dc76b8ade643291
2011-05-04 11:17:35 -04:00
f4bb554ee9 delay accessing misc partition until its device exists
When the misc partition is on an emmc device, recovery can get started
and try to access it before the kernel has actually created the
device.  Try statting the device before reading or writing it; delay
up to 10 seconds waiting for the device to exist.

Change-Id: I988442d5701394d7152bfab3c571e7548c364f61
2011-05-04 11:07:48 -04:00
wjb
cea6eba92d recovery: display mount point when confirming format
Change-Id: I474a511774b9e7ecf92f9fcedb1952d4c0adfdbc
2011-04-30 21:04:04 -04:00
cde585e3de Merge "Try to mount vol->device2 partition to UMS." into gingerbread 2011-04-27 09:56:27 +04:00
df3004bd16 Try to mount vol->device2 partition to UMS.
Stock sd-card that ships with LG-P500 formatted with no partitions.
This issue can be handled with device2 in recovery.fstab.
But UMS didn't.
We will try to mount second device (if it was defined) if first failed.

Change-Id: Ia8b58b9fdfa3e63f703a1dd5870cb76936cec88e
2011-04-26 19:15:22 +03:00
9c4c8e2c66 bml_over_mtd: Take care of bad blocks on "boot" partition for Samsung Galaxy S Phones.
The Samsung Galaxy S bootloader apparently expects the kernel to be flashed to BML-managed flash - bad erase blocks will be mapped from a reservoir area.
CWM however just skips bad blocks, the usual procedure for mtd-accessed flash.
Consequently, the bootloader sees a corrupt zImage, and will usually crash when the kernel initializes.
This of course will only happen when the "boot" partition has bad blocks.

This patch was written by "eifert" and adds a tool called "bml_over_mtd" for flashing boot images which takes care of bad blocks and maps them to a reservoir area, like BML does.

Change-Id: If570717a19b879d47d70d937a0751cd85853eacd
2011-04-25 11:16:41 -07:00
6a97396572 3.0.2.8
Change-Id: Icce5373f73f349c07bad29763803ba919cf64dc1
2011-04-24 20:16:39 -07:00
7364e82a5f format .android_secure on RM data wipe.
Change-Id: If417334263f577f0f1ca9a8c5bf6b63582dbb09f
2011-04-23 19:01:16 -07:00
1f1a274ecc 3.0.2.7
Change-Id: I43e32be031bf7803ca3ef3c8e77e7955218fd798
2011-04-23 16:35:19 -07:00
803896f62c Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-04-22 12:12:33 -07:00
f573510b50 bml fixes
Change-Id: I442ef3c155bab36db578ca5735215aedda353c29
2011-04-22 12:12:32 -07:00
f1bde36572 fix bug where the wrong SD Card block gets partitioned. rely on the ftsab to glean the sdcard mmcblk
Change-Id: Idee8d3e147ba91c45a9f9fe91126c7b5a19ee38d
2011-04-22 11:26:03 -07:00
cfd256a332 delay accessing misc partition until its device exists
When the misc partition is on an emmc device, recovery can get started
and try to access it before the kernel has actually created the
device.  Try statting the device before reading or writing it; delay
up to 10 seconds waiting for the device to exist.

Change-Id: Ib9bf6c35fa2c28fc43aa7550aaaffb76c9f6e120
2011-04-22 09:33:14 -07:00
907ed71a5c yes/no only, yes before no 2011-04-18 03:54:24 +01:00
eee085415f remove old chargemode crap
Change-Id: I6ca88be821ebb713a796251f416b02c1f7144c44
2011-04-17 15:56:30 -07:00
fdd4766c1e Revert "allow precise device detection"
This reverts commit ed7d296dfa.
2011-04-17 00:49:15 -07:00
ed7d296dfa allow precise device detection
Change-Id: Ie837500d459c95df0b1a5f849b3eba718cf8cf09
2011-04-16 13:45:53 -07:00
179b2d9895 make write_raw_image able to take a blob
write_raw_image() can now take either a blob or a filename as the
source.  The blob format eliminates the need for a temp file.

Change-Id: I0c6effec53d47862040efcec75e64b7c951cdcf7
2011-04-12 16:48:49 -07:00
469243e536 save a last_install file with the result of the last package install attempt
When installing a package, create /cache/recovery/last_install, which
contains the filename of the package and a 1 or 0 for success or
failure.

Also, don't mount ext4 and vfat filesystems as read-only (on devices
where /cache is ext4, we need it to be read-write).

Change-Id: I0cf2a1921bbd65e06343aa74e2006577fac77c2c
2011-04-12 09:28:10 -07:00
3a7dc29b24 Merge "add offmode charging for htc" into gingerbread 2011-04-12 00:36:22 +04:00
bab66b40f7 Merge "recovery: Prevent the users from doing stupid things." into gingerbread 2011-04-10 21:30:40 +04:00
6944713e92 add offmode charging for htc
Change-Id: I76ea278c10658e16bf864a8290edc95e4232970e
2011-04-10 10:20:53 -07:00
7a52627720 Recovery: Fix improper variable check
Change-Id: Ib2bb105c204f4f3f88d9a10056d368d6f54548ed
2011-04-09 20:32:48 -04:00
0d87851037 recovery: Prevent the users from doing stupid things.
Don't allow formatting of special partitions like radio, bootloader,
or misc. No sense in formatting recovery from recovery either dawg.

Change-Id: I0f935aad103574b17be237993730afaeae623871
2011-04-09 14:49:09 -04:00
814a934c8f Recovery: Fix keys for many new devices
cwm 3.0.2.4 had the bad habbit to bind back key to enter,
which is the same function as power key, when there is no
select-button on that device.

many many new (htc) devices got: home | menu | back | search

back should be always back. having back working as enter
button confused the shit out of me.
home/menu was not used. i bound up/down highlight movement to it
back is fixed back. search on the other hand is replacement enter.

so, you can control the whole recovery with those 4 easy-to-reach
keys now. on some devices power/vol+/vol- are kinda hard to reach.

if this patch breaks any other devices i am not aware off, please
handle this issue in another sane way.

Change-Id: Ic9c14e6ae7a8a0f1c9cf5c8895716e5357b3da0e
2011-03-26 18:51:18 +01:00
d2375719d5 reverse the logic cause it weirds me out.
Change-Id: I0203d0713c1cc3085d0df77da4b85c1b99a271de
2011-03-23 23:12:27 -07:00
3bf881539c Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-03-23 22:51:57 -07:00
ee9ab1969a 3.0.2.4
Change-Id: Ic727ec267f090bd8f9bc04f02e852184aecccc89
2011-03-23 22:51:53 -07:00
5615b2d46a Fix makefile fail
Change-Id: I47e0332d2c8aff8909cc5f0cc75195b1ed3fc688
2011-03-21 20:31:52 -04:00
3f26366993 Recovery: rearrage defines to fix recovery for mecha and
not break it for toastcfh

Change-Id: If6d4ced872bc04fc5d02803672c8279c82fe9ea3
2011-03-21 08:03:46 -04:00
faa477ec99 fix potential break that toastcfh found?
Change-Id: I590bf171a78380daaa9ea65b4ece726b64c7cd23
2011-03-20 15:44:48 -07:00
6d19f22c85 Recovery: Add support for filesystems >2gb
Add a  prebuilt static linked mke2fs with support for >2gb FS.
Add board_has_large_filesystem define
Adjust mmcutils for differences between busybox and static mke2fs

Change-Id: Ib02771ee161e8874b6840067dc8682fc63ad6513
2011-03-20 08:28:09 -04:00
67fa0c375f fix erroneous detection of device flash type when device is explicitly provided. fix bugs in mount generation.
Change-Id: I54a35390550b1384f12c4b12267029d77bef8fa3
2011-03-17 11:37:21 -07:00
3ed8e18721 am 4762633c: log which key a package verified against in recovery
* commit '4762633cf846d17516878303502b056b52353a5d':
  log which key a package verified against in recovery
2011-03-15 13:47:23 -07:00
4762633cf8 log which key a package verified against in recovery
Change-Id: I0d91b715d1eb9e45e2fce54bb93ba0abef92727e
2011-03-15 12:11:08 -07:00
201aa88cba recovery: mount /sdcard read-only
Change-Id: Ieffafe00cf82620057cacd0629cb60b0e6aad817
Signed-off-by: Iliyan Malchev <malchev@google.com>
2011-03-11 16:47:53 -08:00
90415aca67 am 6e4472ab: Have recovery reboot using the new android_reboot() function.
* commit '6e4472abbd3c7be9cd31d98a03df1e3b6fa92f40':
  Have recovery reboot using the new android_reboot() function.
2011-03-10 19:44:38 -08:00
6e4472abbd Have recovery reboot using the new android_reboot() function.
The new android_reboot() function is a nicer way to reboot the
system.  I can optionally sync() and remount read-only writable
filesystems.  This fixes bug 3350709.

Change-Id: Ic4c8676debd642e57bce3107b99dd810d90b6f82
2011-03-10 19:30:13 -08:00
f66088d2ce am 6ce4a326: don\'t reboot for inactivity if USB is connected
* commit '6ce4a326efae4abb108e19899f4d7776abc362da':
  don't reboot for inactivity if USB is connected
2011-03-08 23:53:35 -08:00
6ce4a326ef don't reboot for inactivity if USB is connected
(Cherry-pick back from master.)

Bug: 4071007
Change-Id: I28355c593770df678968185171bdd19dabe7f062
2011-03-08 17:51:14 -08:00
4cc533dd1c don't reboot for inactivity if USB is connected
Change-Id: Icba35da91167d30c446581afb47d0804e49964bf
2011-03-08 12:25:05 -08:00
b70fe3f76a am 68189f29: allow paletted RGB images in recovery
* commit '68189f2994690538b6e3bddc3788cb092cbda088':
  allow paletted RGB images in recovery
2011-03-07 15:47:04 -08:00
92796ec949 build "mount & storage" menu from fstab 2011-03-07 13:06:07 +01:00
59d86b4cf7 fix wimax backup for emmc
Change-Id: I3da8a3d9411b52e07bebe6214f86dd12ac98bb82
2011-03-06 15:18:48 -08:00
68189f2994 allow paletted RGB images in recovery
Recovery assumes any paletted images are in RGBA format.  Make it
handle both RGB and RGBA paletted images.

Bug: 3514884
Change-Id: I517cd571aa3f434dacacc33a774236260aec20ef
2011-03-04 17:13:16 -08:00
7e69e2cccc Merge branch 'master' of ssh://android-git:29418/platform/bootable/recovery 2011-03-04 00:29:22 -08:00
73bb6f749f convert recovery images to palettized PNGs
Cuts the byte size of the recovery images in half, roughly.

Change-Id: I3c45b5e58423b57faca83fc67b4e24e8d643c5b1
2011-03-03 16:52:06 -08:00
b7c91766da convert recovery images to palettized PNGs
Cuts the byte size of the recovery images in half, roughly.

Change-Id: I453a499e9937163c545dab3c552201882766e218
2011-03-03 14:43:13 -08:00
5ee98b20d0 for toast
Change-Id: I5dd56606ace68d77e244840941852571c05d36e0
2011-03-02 19:35:05 -08:00
65ad19c943 version
Change-Id: I34d22f72896a15abc4f0c75267dbcb78b1d6a33c
2011-03-02 12:36:14 -08:00
13ac7a473f fix build
Change-Id: If907795c670fb1ca7ba28bbfd40d21ce51405b7d
2011-03-02 12:36:10 -08:00
e734dad68c fixes
Change-Id: I28b58fec5ac92463bf189269267b8e1579dbc92c
2011-03-02 12:32:13 -08:00
be6d4d1052 change the default recovery assets to be in holograph style
Also remove the weird backwards compatibility thing for animations
with fewer than 10 frames.  Frames are always named "name01.png",
"name02.png", ..., no matter how many there are.

Change-Id: I7af64fdec1bfcdb0464998b735ec8d6c626ffe9d
2011-03-02 10:38:02 -08:00
fa265db3a3 remove redundant code
Change-Id: I6a24f89068c882b18973c9143a02768531b71ddd
2011-03-01 21:43:29 -08:00
c5ab2a34f9 remove debug code
Change-Id: I14a6657a6f875d4305ed72a163bf72e3e9c5dad1
2011-03-01 21:43:05 -08:00
e2b929ded1 forgot to check this in.
Change-Id: I97a7cf0b9bb296bff4b8a80f528082c0c409e9e1
2011-03-01 21:41:54 -08:00
6809c51f8d make recovery UI images more general; allow for installation animation
Change some of the UI parameters (# of indeterminate progress bar
frames, fps, etc.) from #defined constants to variables that can be
set by the device-specific recovery_ui code (via a new function).

Support overlaying different images on top of the base installation
icon to animate it.  Make the FPS control more accurate.

Change-Id: I9268b389b7ea6b3ed9e0c7eae37baf4272e60edd
2011-03-01 14:04:34 -08:00
a1f43bfd27 build break!
Change-Id: Ia33661ea1c735990528095038b93fd4ecb717341
2011-02-27 18:31:41 -08:00
978a0e25c4 logging
Change-Id: Id835419f1ed3d9cf9c946f73a35eddc3ac029a2c
2011-02-27 17:58:26 -08:00
ab1f8b836e more fixes for sammy
Change-Id: Ie11c673a204a328a82f767a2610c5f1d9a51233c
2011-02-27 17:28:30 -08:00
47d86a35bc option to specify usb_mass_storage device in device overlay 2011-02-27 17:07:53 -08:00
7161f35736 specify a type on the mount.
Change-Id: I610330e2971aaf235e0420fa7d4387e4f55b0015
2011-02-27 17:00:47 -08:00
33e37f3e5d check for bml too
Change-Id: Iff062f439c0daa0ce768c3853fd7c290e75b8d3d
2011-02-27 16:33:32 -08:00
d9fbe2f1ce Dont error spew if no misc partition is available.
Change-Id: Ic5d9c8dc936e8f9a4c61474cebeabb2eecc4446e
2011-02-27 15:54:03 -08:00
e8bc2c808c Support fs mount options.
Change-Id: I8b0dc79dd054c4d1af599d9b68b5478196bdd183
2011-02-27 14:00:19 -08:00
33fd0d0a70 Fix inc /datadata wiping from RM.
Change-Id: I983bf83a7baf1494c7ff26199591bb93fab5ae74
2011-02-27 12:42:24 -08:00
c007b961d7 am 8d43d940: am 2c273f00: store partition length in recovery.fstab
* commit '8d43d94065e88e00e1460841b43c7de584ee5585':
  store partition length in recovery.fstab
2011-02-24 20:35:19 -08:00
ee458bbf9b store partition length in recovery.fstab
Don't hardcode magical partition behavior in roots.c.

Change-Id: I587fc2c066575b51c11efd2e45a50f5b864df484
2011-02-24 18:46:44 -08:00
8d43d94065 am 2c273f00: store partition length in recovery.fstab
* commit '2c273f004e0504ae0389ad160ed2a92624873189':
  store partition length in recovery.fstab
2011-02-24 18:38:48 -08:00
2c273f004e store partition length in recovery.fstab
Don't hardcode magical partition behavior in roots.c.

Change-Id: I587fc2c066575b51c11efd2e45a50f5b864df484
2011-02-24 18:34:36 -08:00
75b2fa023b Merge "Added Power off capability" into gingerbread 2011-02-18 23:28:39 +00:00
2810ceda34 store partition length in recovery.fstab
Don't hardcode magical partition behavior in roots.c.

Change-Id: I587fc2c066575b51c11efd2e45a50f5b864df484
2011-02-17 15:55:21 -08:00
a9f0e7fdfe remove unused defines. dont try to mount boot if it is emmc or bml either.
Change-Id: I835f74785938be940111f03a6b092b926681d745
2011-02-12 10:21:11 -08:00
c7ef9af5d7 Change-Id: Id6ee1fed1eebbaa6d3a9e6117910f00a56378da4 2011-02-09 16:32:42 -08:00
49ee9a8b09 Defer to fstype2 if found. Use auto fs if two fstypes are specified
Change-Id: Id6ee1fed1eebbaa6d3a9e6117910f00a56378da4
2011-02-09 16:15:54 -08:00
64d79c6531 Support multiple file system types.
Change-Id: Icd89a7ce14ef7948dbd25bfbb17ff9d930514b00
2011-02-09 06:13:30 -08:00
4c05d95112 Fix x86 build.
Change-Id: Iada6268b0a72ee832113ea397334cc7950a37051
2011-02-08 19:51:07 -08:00
28fee5a1b2 Merge "Add support for devices that have an upside-down mounted display." into gingerbread 2011-02-06 22:12:49 +00:00
6d0604bf34 Add support to mount /boot for systems that have a mountable /boot.
This is checked at runtime to see if /boot is a mountable parition (i.e not mtd), if so it adds an entry into /etc/fstab.

This will allow us to mount /boot from an edify script and push certain files without completely imaging the parition which can contain other files such as the bootloader (u-boot), and recovery kernel and ramdisks as is the case with the encore (NookColor)

Test on NookColor and passion.  Correct entry was added to the NC and not added to the passion as expected.

Change-Id: I9850dee866b77653bf400bb5193905e55da3f25f
2011-01-28 13:42:14 -07:00
6da1abbc38 am 5df22d03: am 5cae445e: make recovery reboot after 2 minutes of no activity
* commit '5df22d03d2e7c6de213d83a58e0af39c42f839ca':
  make recovery reboot after 2 minutes of no activity
2011-01-25 13:56:07 -08:00
5df22d03d2 am 5cae445e: make recovery reboot after 2 minutes of no activity
* commit '5cae445e43c5928daba0a76745b0dd2657274eda':
  make recovery reboot after 2 minutes of no activity
2011-01-25 13:53:52 -08:00
5cae445e43 make recovery reboot after 2 minutes of no activity
If recovery sits for 2 minutes in prompt_and_wait(), and you've never
turned the screen on via the magic keypress, go ahead and reboot.  (We
used to assume that the user could pull the battery to get out of this
state, but on devices with nonremovable batteries...)

If you've ever enabled display of the log/menu since recovery started,
we assume you know what you're doing and will stay in recovery until
you choose to reboot.

Bug: 3387873
Bug: 3387274
Change-Id: I041621e5db132df9a925e6808845a7c45e1b427a
2011-01-25 13:50:16 -08:00
80abd51dbc am da993fcf: am 8d58c957: Merge "Free allocated struct after freeing field"
* commit 'da993fcf2665102435b05d6b20a4c4e8f8bd3b8f':
  Free allocated struct after freeing field
2011-01-21 16:15:02 -08:00
da993fcf26 am 8d58c957: Merge "Free allocated struct after freeing field"
* commit '8d58c957036835db148acc4e506633a016dc6c7e':
  Free allocated struct after freeing field
2011-01-21 16:12:03 -08:00
1966aaf4e6 Merge "remove encrypted filesystem code from recovery" 2011-01-21 13:12:30 -08:00
8d58c95703 Merge "Free allocated struct after freeing field" 2011-01-20 07:06:02 -08:00
8f132ed870 Reserve the last 16 Kbytes of /data for the crypto footer.
When formatting /data, if it's an ext4 filesystem, reserve the
last 16 Kbytes for the crypto footer.

Change-Id: I7b401d851ee87732e5da5860df0287a1c331c5b7
2011-01-19 17:12:47 -08:00
862c83bb31 Free allocated struct after freeing field
Free allocated MtdReadContext after freeing buffer field in struct,
not before.

Change-Id: I237920dc36115389cd2d6948e7a962dbec22fe56
2011-01-19 12:22:41 +01:00
b5d0bd024c Add support for devices that have an upside-down mounted display.
ZTE Blade is an example of this type of devices.
The original patch comes from Sebastian404 -> http://goo.gl/QC37W

Change-Id: Idffd97adf7da8a352617342bb6ff2161e6eac3a5
2011-01-19 11:15:08 +00:00
540d57f25a remove encrypted filesystem code from recovery
This was never used; encrypted filesystems are being done a different
way now.

Change-Id: I519c57b9be44d001f0b81516af7bfc252069892b
2011-01-18 13:36:58 -08:00
066a1027a4 Use raw partition functions for emmc
Change-Id: Ia5d9f18d43228a08f12633d432b299def8e26ae1
2011-01-16 06:29:31 -06:00
a25cf5ec4f Use erase_raw_partition for unknown named partitions
Change-Id: I84014a851ebdfb2c228cff43879580a761c22708
2011-01-16 06:05:22 -06:00
e06e539196 fix sd-ext backup and restore.
Change-Id: I346724f231bb29df2c0fa833df420620ab1be1b4
2011-01-16 02:33:04 -08:00
be3e6f13b8 option to allow recovery to use 24-bit graphics in UI
Add "RECOVERY_24_BIT := true" to the device's BoardConfig.mk to use
24-bit framebuffers in the recovery ui.

Change-Id: Iaede138bf7870becf237f12f1c0e49c9ff82d007
2011-01-13 16:43:44 -08:00
d646a6fa1d Added Power off capability
Change-Id: I545f8b73e84c5083d2d17b98f8edcdd612c0f78e
2011-01-10 06:14:21 +01:00
49396b79b5 Update make_ext4fs arguments in roots.c
Change-Id: I835e55fb80add6a74cd4d99f77b2528829d9a349
2011-01-05 17:19:37 -08:00
53c9bd8b10 Refactor nandroid so the availability of boot backup is determined automatically. Boot backups are also no longer assumes to be on raw partitions, as they may be on a VFAT partition or someting different, such as in the case of Nook.
Change-Id: I036befb44f0d873fde02485e34aab14faf8bfe8d
2011-01-04 11:38:31 -08:00
d8e21c3712 Add the volume command for seeing the current recovery.fstab. Support crazy HTC chargemode.
Change-Id: I26a6e83dc5704aa03ab3aa078f24f8943cf13614
2011-01-04 10:46:55 -08:00
b4c5fd6305 Support for ext2 and ext3 update-binary.
Change-Id: Ide34392bd8ac56878aa3e992b275a39d6b6bc7cf
2011-01-02 22:54:31 -08:00
9f52e5f23b fix android secure formatting
Change-Id: I617b8c453aad6d306cf8ddbc1a067c59ead56573
2011-01-02 14:11:24 -08:00
67c381a6fa 3.0.0.4. Provide an error message if an Amend zip is provided.
Change-Id: Ia740686a138cff01de2c1475acc0abccb18d9c2d
2011-01-02 12:26:35 -08:00
949f3b34ee Merge branch 'gingerbread' of git://github.com/CyanogenMod/android_bootable_recovery into gingerbread 2011-01-01 20:03:39 -08:00
f1cb0d5b35 fix ums mounting
Change-Id: I97316668fe3e4447a04cd9f189b0d3d89cd97d9f
2011-01-01 20:03:30 -08:00
ad10e56863 fix nandroid-md5.sh executable bit.
Change-Id: Ib90872e1ff341cc913de8ed3577738efd2428f61
2011-01-01 18:50:09 -08:00
7aa8ef9abc fix executable bit on e2fsck
Change-Id: Iedc3ead52645af5c104642e2eb78f3578fb7b8fb
2011-01-01 18:26:49 -08:00
a25deae3ef fix wimax
Change-Id: Ieff7638293e01546baf382d9c8a5b798cff46331
2011-01-01 18:17:48 -08:00
f12df71ffb fix nandroid linkage issue
Change-Id: I36998f2e94ad1ead656c6374c551d5e02e2db219
2011-01-01 18:16:01 -08:00
3affbec593 fix up boot formatting. remove depracated function.
Change-Id: I9d707e62b1752079ec1b669a3800dbf12e035ead
2011-01-01 18:10:11 -08:00
2e45449ef3 more logging
Change-Id: I77a7198808133e5f0a6d8de1f5e716aecf31c0ae
2011-01-01 18:06:17 -08:00
1375df75ff fix bug
Change-Id: Id38cf292fd93f5a53552c80c48d9281701b88ce0
2011-01-01 18:04:44 -08:00
a8708c6044 readd ext2/ext3 format support.
Change-Id: Ic21197df8ff53fdc8ffd3dc1947bd2ecb475eda8
2011-01-01 18:00:27 -08:00
da32b54f85 readd ext2/ext3 format support.
Change-Id: I58652abaea8f7a52b70bc1b14aec5b530fe70382
2011-01-01 17:55:22 -08:00
29a7891204 3.0.0.2
Change-Id: I4705196b5bf8e66e4ac409a027650be9ce491f4c
2010-12-30 23:17:28 -08:00
10a91b0bf2 Merge branch 'gingerbread' of https://github.com/jwise/android_bootable_recovery into gingerbread 2010-12-30 23:17:04 -08:00
5a3f1d8af5 Erase WiMAX device before restore. 2010-12-31 02:16:00 -05:00
05d4a09aba Fix up for property_get in recovery, which appears to have slightly different semantics. Durr. 2010-12-31 02:05:35 -05:00
15b06184cd cwm: set sd-ext label
Change-Id: I963924083f1f6de17effafa80fb6f7fe003b304d
2010-12-30 22:49:34 +01:00
ebc5aab351 3.0.0.1
Change-Id: Ie38f59158f6ada921e9be4e5a8e7cd89207225d5
2010-12-30 11:41:31 -08:00
ca889ec844 WiMAX backups have their serial number in them, and messages now say WiMAX instead of wimax. 2010-12-30 02:48:25 -05:00
5b7f34a2d8 wimax restore should not be on by default
Change-Id: I1e1869e615905ce6dbefd0b1a8e64414f619508e
2010-12-29 23:36:03 -08:00
1f76a5da6b Add support for wimax imaging
Change-Id: I2f14918f3ffb37fe94bab469e1d89a9874d89d18
2010-12-29 23:03:32 -08:00
264f549b7d Update arguments to make_ext4fs
Change-Id: Id96e98da76b3091987b01651f980797b1d6b49d8
2010-12-29 14:18:26 -08:00
7501798fab Fix nullpointer when recovery.fstab does not define a "misc" partition
Change-Id: I57437e3c637a1c619d254a3fc025db19ffe53c10
2010-12-28 23:54:29 +01:00
c8ff793bf4 fix build break
Change-Id: I8bc7dbe3a3c0ad09b032f332317e55ed2ebd28e3
2010-12-21 15:16:05 -08:00
1e6d772f35 Merge remote branch 'github/gingerbread' into gingerbread 2010-12-21 15:14:40 -08:00
03cf72a4f5 fix restore
Change-Id: I97d2bb16b364e701e9c37567b5c07e30be00fafb
2010-12-21 15:14:21 -08:00
cdb433af66 fix bml dump
Change-Id: Iaf3c6bd2f09b42dcb2474e700aee57c0aaacd996
2010-12-21 15:13:58 -08:00
745b5ff987 Use unique filenames for the pre ext4 convert backup.
Change-Id: I49ee96c454c826fc92c45f160c6d45cc5566f0a6
2010-12-21 00:58:43 -08:00
31b741174c Fix fstab generation.
Change-Id: Ibab3c93c55abcece80a89bbff620f164588baf96
2010-12-20 08:49:20 -08:00
bec0995afe ROM Manager is now powered by Edify,
Change-Id: I3857aa6591b743be146d87a4e97afdc9d9c765ed
2010-12-19 20:37:57 -08:00
33491accea Fix sdcard mount bug.
Change-Id: I2e448f3f0a0a4de39a8d1cd7db5dc8cd986d3229
2010-12-19 03:41:41 -08:00
4196e0fa5e bml devices that are using rfs are automatically upgraded to ext4. Version 3.0.0.0.
Change-Id: I069f0c5122e8d48ce311f519f08890d3e569dbb3
2010-12-19 03:38:29 -08:00
d0fff5633c Ifdef this a bit better.
Change-Id: I4528821563181ca7a64adff3a3128cea35447f09
2010-12-18 23:18:50 -08:00
5460f0c746 Automatically detect /datadata from recovery.fstab. Remove BOARD_HAS_DATADATA.
Change-Id: I28d3c7a6beaacd77c67c5af0ae3464acfd2572e3
2010-12-18 22:37:49 -08:00
5d80817f2b There was apparently a lack of carebear.
Change-Id: Ie65bce617b99985ab937602e1e30a97340b0dd5b
2010-12-18 22:29:27 -08:00
4995114d38 Add BOARD_HAS_JANKY_BACKBUFFER for terrible Galaxy Tabs.
Change-Id: I72e7a8aaf65c97d4cd2b77ff92cf7232f8c9e7a7
2010-12-18 21:58:43 -08:00
9765a037a1 Remove usage of BOARD_HAS_NO_MISC_PARTITION.
Change-Id: I5775f47fb1d5ef66e2461a0c53166af03354a6f6
2010-12-18 21:31:02 -08:00
7c1bffefeb Fix the build
Change-Id: I2ae07e94eb68dd261b3978671aec88c25cd2518e
2010-12-18 19:44:33 -08:00
bf4444f1fb Fix various bugs.
Change-Id: I46e3001e6857480a77253be24b1753b2e4d88e69
2010-12-18 18:57:47 -08:00
b643e4f3d0 Fix up fstab generation
Change-Id: I922183bc3de8d2b3bb7d1497725f2641a4358216
2010-12-18 18:39:39 -08:00
8637c73757 revert updater changes except what is necesary to do a write_raw_image on emmc devices.
Change-Id: I674c7b5873b7758bf15f0b55c34ec01513e6f23c
2010-12-18 18:18:44 -08:00
df1e406782 Merge from ClockworkMod recovery
Change-Id: Id5b312147173ced559a62d97029acede6c2f8766
2010-12-18 17:42:31 -08:00
70f7e8dbf0 am c5ebf1fb: am 5d6309e7: fix comparison of ECC stats before and after mtd reads
* commit 'c5ebf1fba2f870a4e9453721112900975c18e083':
  fix comparison of ECC stats before and after mtd reads
2010-11-04 07:20:28 -07:00
c5ebf1fba2 am 5d6309e7: fix comparison of ECC stats before and after mtd reads
* commit '5d6309e77f6055a9aec062dd991d071054726ebb':
  fix comparison of ECC stats before and after mtd reads
2010-11-03 15:18:12 -07:00
5d6309e77f fix comparison of ECC stats before and after mtd reads
ECC errors are found by comparing the result of ioctl(ECCGETSTATS)
before and after the read.  But if an error was found causing us to go
to the next block, we'd compare the stats before the *first* read to
the stats after the second (third, fourth, etc.) reads, so we'd read
to the end of the partition without ever succeeding.  Fix logic so we
compare the values before and after each read independently.

Bug: 3162777
Change-Id: I5a13abd7243d2afd1d21bd98cbb233e5124b2e80
2010-11-03 14:31:01 -07:00
02971af254 am 8521ef59: am 51266d13: clear recovery framebuffers on allocation; display icon right after ui_init
* commit '8521ef5965675da85c7bbbe9c8b86fe68716e855':
  clear recovery framebuffers on allocation; display icon right after ui_init
2010-11-01 10:40:33 -07:00
8521ef5965 am 51266d13: clear recovery framebuffers on allocation; display icon right after ui_init
* commit '51266d1397309978eac9b2e96035582454f0321b':
  clear recovery framebuffers on allocation; display icon right after ui_init
2010-11-01 10:38:12 -07:00
51266d1397 clear recovery framebuffers on allocation; display icon right after ui_init
Make ui_init() clear the framebuffer memory it maps in so the user
isn't treated to a visible flash of random bits on recovery startup.
Call ui_set_background() (to show the installing icon) right after
ui_init() to display something while device_recovery_start() is
working (which can take a second or two on some devices).

Bug: 3145331
Change-Id: I11e7859fab5847370ea4f4932c3fb1558af26c5d
2010-11-01 10:19:12 -07:00
7c3ee270ce am 2d87023e: am 2c3539e4: save the log from recovery\'s last run in /cache/recovery/last_log
Merge commit '2d87023e77b20aa2196c8ceae833b33040b0dc57'

* commit '2d87023e77b20aa2196c8ceae833b33040b0dc57':
  save the log from recovery's last run in /cache/recovery/last_log
2010-09-30 11:25:31 -07:00
2d87023e77 am 2c3539e4: save the log from recovery\'s last run in /cache/recovery/last_log
Merge commit '2c3539e4d8251ad91e0b881253d39583680093e8' into gingerbread-plus-aosp

* commit '2c3539e4d8251ad91e0b881253d39583680093e8':
  save the log from recovery's last run in /cache/recovery/last_log
2010-09-29 13:46:06 -07:00
2c3539e4d8 save the log from recovery's last run in /cache/recovery/last_log
Also, don't lose the start of the log whenever a wipe cache is
performed.

Change-Id: I29999762854eb36d1ff2bc20b4183c9077b19777
2010-09-29 13:40:44 -07:00
1a32732db2 am 704fa750: am 9b125b04: handle old-style CACHE: packages
Merge commit '704fa75024467fb4e362537f7c341eb056e283b5'

* commit '704fa75024467fb4e362537f7c341eb056e283b5':
  handle old-style CACHE: packages
2010-09-22 13:53:57 -07:00
704fa75024 am 9b125b04: handle old-style CACHE: packages
Merge commit '9b125b04c6ba8f07d8aa6494d58917a596443dc5' into gingerbread-plus-aosp

* commit '9b125b04c6ba8f07d8aa6494d58917a596443dc5':
  handle old-style CACHE: packages
2010-09-22 12:06:24 -07:00
9b125b04c6 handle old-style CACHE: packages
Change-Id: I7bf52b56770c207ba1c8329243991b07ebb65779
2010-09-22 12:01:37 -07:00
6b26c882a8 am af78591c: am 2c3c5c15: Merge "mount sdcard only on demand; fix sideload installs" into gingerbread
Merge commit 'af78591c9a2aa8379c2d8528c31ea1eb813f6cae'

* commit 'af78591c9a2aa8379c2d8528c31ea1eb813f6cae':
  mount sdcard only on demand; fix sideload installs
2010-09-21 20:21:52 -07:00
af78591c9a am 2c3c5c15: Merge "mount sdcard only on demand; fix sideload installs" into gingerbread
Merge commit '2c3c5c15d15faf1c9fa074851c57d0afa2a40d28' into gingerbread-plus-aosp

* commit '2c3c5c15d15faf1c9fa074851c57d0afa2a40d28':
  mount sdcard only on demand; fix sideload installs
2010-09-21 20:01:51 -07:00
2c3c5c15d1 Merge "mount sdcard only on demand; fix sideload installs" into gingerbread 2010-09-21 20:00:18 -07:00
c18eeb874b mount sdcard only on demand; fix sideload installs
Bug: 3009493
Change-Id: I1a7f99fc41a6a7012742e82f8c06a0c75584890a
2010-09-21 16:58:10 -07:00
3d798835a3 am 8147ba85: (-s ours) am 93ca4fc6: use fs_type "emmc" instead of "block" for consistency (do not merge)
Merge commit '8147ba850b2e74dc950183e67c77a0da2b1a19b7'

* commit '8147ba850b2e74dc950183e67c77a0da2b1a19b7':
  use fs_type "emmc" instead of "block" for consistency (do not merge)
2010-09-21 14:46:43 -07:00
8147ba850b am 93ca4fc6: use fs_type "emmc" instead of "block" for consistency (do not merge)
Merge commit '93ca4fc6943a3ebf758c5db98531531b8fe92c98' into gingerbread-plus-aosp

* commit '93ca4fc6943a3ebf758c5db98531531b8fe92c98':
  use fs_type "emmc" instead of "block" for consistency (do not merge)
2010-09-21 14:37:10 -07:00
93ca4fc694 use fs_type "emmc" instead of "block" for consistency (do not merge)
Change-Id: Iab60665d9c6daef7893896a64b7f319120a5f8ee
2010-09-21 14:28:11 -07:00
cc8cd3f3ca remove the notion of "root path"; support mixed flash types
Remove the wacky notion of "roots" and "root paths" (those things that
look like "FOO:some/path" instead of just "/foo/some/path").  Let each
device specify its own table of available partitions and how to mount
them (needed for devices that use both MTD/yaffs2 and EMMC/ext4
partitions).

(Cherrypicked from gingerbread w/slight edits.)

Change-Id: I2479ce76b13e73f1d12035c89386c3a82b3edf51
2010-09-21 14:13:45 -07:00
0f1ad110f8 am 3dba40da: (-s ours) am d4208f9f: remove the notion of "root path"; support mixed flash types (do not merge)
Merge commit '3dba40da1e533c6f419857e4274d9d9dd55868b6'

* commit '3dba40da1e533c6f419857e4274d9d9dd55868b6':
  remove the notion of "root path"; support mixed flash types (do not merge)
2010-09-21 11:38:21 -07:00
3dba40da1e am d4208f9f: remove the notion of "root path"; support mixed flash types (do not merge)
Merge commit 'd4208f9f9d4e9f268ba1888c1fe879ee73eb7e47' into gingerbread-plus-aosp

* commit 'd4208f9f9d4e9f268ba1888c1fe879ee73eb7e47':
  remove the notion of "root path"; support mixed flash types (do not merge)
2010-09-21 11:34:39 -07:00
d4208f9f9d remove the notion of "root path"; support mixed flash types (do not merge)
Remove the wacky notion of "roots" and "root paths" (those things that
look like "FOO:some/path" instead of just "/foo/some/path").  Let each
device specify its own table of available partitions and how to mount
them (needed for devices that use both MTD/yaffs2 and EMMC/ext4
partitions).

Change-Id: I18b0a572a71c5e087e0b7ae11b1774388339bfd1
2010-09-20 18:07:31 -07:00
c9ebb58623 resolved conflicts for merge of 40f0d3b4 to master
Change-Id: If14ab094a8bb11106b0ea7fdf8736e5e4c223089
2010-09-17 16:07:14 -07:00
40f0d3b4e0 am d7d42089: remove unneeded partition roots
Merge commit 'd7d4208976125d114d0b8e44438e2417d5275098' into gingerbread-plus-aosp

* commit 'd7d4208976125d114d0b8e44438e2417d5275098':
  remove unneeded partition roots
2010-09-17 13:30:15 -07:00
d7d4208976 remove unneeded partition roots
Recovery itself no longer needs to access all these partitions;
manipulation of them is done by the updater binary.  This is a small
first step towards removing roots entirely.

Change-Id: I3fbcada32079a37db4cc097861dfa91e0a08da30
2010-09-17 13:02:48 -07:00
97e54ef573 am 1dcd2fd0: (-s ours) am 792b0071: do not merge - update to match ext4utils api
Merge commit '1dcd2fd0c7cc44cae279a5088241bdf15f084cb8'

* commit '1dcd2fd0c7cc44cae279a5088241bdf15f084cb8':
  do not merge - update to match ext4utils api
2010-09-15 19:49:56 -07:00
1dcd2fd0c7 am 792b0071: do not merge - update to match ext4utils api
Merge commit '792b00712bb1411d3b0583bcea95b43b3107fb95' into gingerbread-plus-aosp

* commit '792b00712bb1411d3b0583bcea95b43b3107fb95':
  do not merge - update to match ext4utils api
2010-09-15 18:07:22 -07:00
dc49ce453e add missing sparseness parameter
Change-Id: Ie6e309b127e80cd6475f1deaa5dbadf9f5cc2746
2010-09-15 18:05:10 -07:00
792b00712b do not merge - update to match ext4utils api
Change-Id: I9d34e491022d7dfed653a861b0728a0a656f1fbe
2010-09-15 18:03:58 -07:00
6c3e03b3c5 resolved conflicts for merge of 85bcf776 to master
Change-Id: Iab4f25702a5a62b9172f81fd543a8240a0e603c3
2010-09-15 17:51:50 -07:00
a66c32ab1d resolved conflicts for merge of 9f89b0e4 to master
Change-Id: Id458df96fd56830fdb35397e95a80274761ecff5
2010-09-15 17:40:14 -07:00
d7693c4c8e resolved conflicts for merge of 76445f3a to master
Change-Id: I658894dcaddbf0de428e3c51dbcdc306d3f47a52
2010-09-15 17:03:51 -07:00
6b1ff61f62 am 858f0a76: am 8e5e4dad: close update package before installing; allow remount
Merge commit '858f0a763d0f736eb721f54257b6164886bfcbfc'

* commit '858f0a763d0f736eb721f54257b6164886bfcbfc':
  close update package before installing; allow remount
2010-09-15 16:32:52 -07:00
4f69afdb63 am bd4bc088: am d12560aa: add the ability to seek to a raw location while reading MTD partition
Merge commit 'bd4bc088e286b87a5d1469598644125ecc0fd547'

* commit 'bd4bc088e286b87a5d1469598644125ecc0fd547':
  add the ability to seek to a raw location while reading MTD partition
2010-09-15 12:32:22 -07:00
85bcf776e1 am 8a8e6cc3: (cherry-pick) EMMC support in applypatch
Merge commit '8a8e6cc33cc0dcfe7e184b59d5ef1f1c29095509' into gingerbread-plus-aosp

* commit '8a8e6cc33cc0dcfe7e184b59d5ef1f1c29095509':
  (cherry-pick) EMMC support in applypatch
2010-09-15 11:17:34 -07:00
9f89b0e467 am 56c5105b: support for ext4/EMMC filesystems in updater binary
Merge commit '56c5105bd7096704eaed35329b2c8c84cc282867' into gingerbread-plus-aosp

* commit '56c5105bd7096704eaed35329b2c8c84cc282867':
  support for ext4/EMMC filesystems in updater binary
2010-09-15 11:14:51 -07:00
76445f3aef am 8674a726: (cherry-pick) support installing any .zip file on the sdcard
Merge commit '8674a726ff05a4a6c09c6934778c251635f130a8' into gingerbread-plus-aosp

* commit '8674a726ff05a4a6c09c6934778c251635f130a8':
  (cherry-pick) support installing any .zip file on the sdcard
2010-09-15 11:12:34 -07:00
8a8e6cc33c (cherry-pick) EMMC support in applypatch
Let applypatch read and write EMMC partitions as well as MTD ones.
This enables incremental updates that include boot image changes, as
well as OTA of new recovery partitions.

Change-Id: Ib1861219c7ca66dff29ad02d6a0a14e5f03eb4d8
2010-09-15 11:12:11 -07:00
56c5105bd7 support for ext4/EMMC filesystems in updater binary
Make the mount and format functions take extra parameters describing
the filesystem type and add support for mounting and formatting ext4
filesystems on EMMC.

Change recovery to consistently use stdout for status messages instead
of mixing stdout and stderr.
2010-09-15 11:10:02 -07:00
8674a726ff (cherry-pick) support installing any .zip file on the sdcard
Replaces the "install sdcard:update zip" menu option with one that
displays a menu of zip files (and subdirs) on the sdcard and lets you
pick which one to install.

Change-Id: Icff541525f2fdfc8939a91af626ecc386ac9dd07
2010-09-15 11:08:23 -07:00
858f0a763d am 8e5e4dad: close update package before installing; allow remount
Merge commit '8e5e4dada713609c9b2c45ea9cf4572bb89ef761' into gingerbread-plus-aosp

* commit '8e5e4dada713609c9b2c45ea9cf4572bb89ef761':
  close update package before installing; allow remount
2010-09-14 21:32:14 -07:00
8e5e4dada7 close update package before installing; allow remount
Close the update package before invoking the binary, to allow the
installer to unmount /cache if it wants to.  Add a function to allow
remounting of a mount as read-only.

Change-Id: Idfcc96c3da66083295177f729263560be58034e4
2010-09-14 21:26:38 -07:00
bd4bc088e2 am d12560aa: add the ability to seek to a raw location while reading MTD partition
Merge commit 'd12560aa2134d3af21a1220cd4873553f9c51743' into gingerbread-plus-aosp

* commit 'd12560aa2134d3af21a1220cd4873553f9c51743':
  add the ability to seek to a raw location while reading MTD partition
2010-09-14 15:32:07 -07:00
d12560aa21 add the ability to seek to a raw location while reading MTD partition
Change-Id: Id1563ca667c50e61cf1bb15d2cf783a50937eece
2010-09-14 15:28:54 -07:00
6a84721c76 am f94a3575: am 61ba7a83: stop treating all-zero blocks as bad
Merge commit 'f94a3575d76f1fd6df20f82ca28fff688d53cfbc'

* commit 'f94a3575d76f1fd6df20f82ca28fff688d53cfbc':
  stop treating all-zero blocks as bad
2010-09-12 14:28:45 -07:00
f94a3575d7 am 61ba7a83: stop treating all-zero blocks as bad
Merge commit '61ba7a83ef46494689801ddaad569d7d174153b1' into gingerbread-plus-aosp

* commit '61ba7a83ef46494689801ddaad569d7d174153b1':
  stop treating all-zero blocks as bad
2010-09-12 14:23:25 -07:00
61ba7a83ef stop treating all-zero blocks as bad
Change-Id: If49fa6485f66598d16a7e44fce3129de55fab422
2010-09-12 13:36:40 -07:00
0b519b25c3 am a2c9a1e8: am aaf3f56c: block is bad if ioctl() returns nonzero
Merge commit 'a2c9a1e8a2b99bd8197c83b2f749ec61bc0312f8'

* commit 'a2c9a1e8a2b99bd8197c83b2f749ec61bc0312f8':
  block is bad if ioctl() returns nonzero
2010-09-09 17:01:49 -07:00
a2c9a1e8a2 am aaf3f56c: block is bad if ioctl() returns nonzero
Merge commit 'aaf3f56c44c37dca4ef9cc9efde68727ca26105f' into gingerbread-plus-aosp

* commit 'aaf3f56c44c37dca4ef9cc9efde68727ca26105f':
  block is bad if ioctl() returns nonzero
2010-09-09 16:59:05 -07:00
aaf3f56c44 block is bad if ioctl() returns nonzero
Change-Id: I6fc4ce796bc663d05035927c0af0ce7ab6d07218
2010-09-09 16:54:35 -07:00
b56db27d08 am 28cae98c: am 4bc98062: add --show_text option to recovery
Merge commit '28cae98c834fb4bc47588b34dc3fe19811d5162b'

* commit '28cae98c834fb4bc47588b34dc3fe19811d5162b':
  add --show_text option to recovery
2010-09-03 11:23:21 -07:00
28cae98c83 am 4bc98062: add --show_text option to recovery
Merge commit '4bc980626c1cf6f1ea7d36e4b54e0023c896c9de' into gingerbread-plus-aosp

* commit '4bc980626c1cf6f1ea7d36e4b54e0023c896c9de':
  add --show_text option to recovery
2010-09-03 11:20:50 -07:00
4bc980626c add --show_text option to recovery
Change-Id: Ie6c6c920260dfa759fbb15b1f352d6bb0fa7146c
2010-09-03 11:18:36 -07:00
5200114fe8 am 4c7c2f73: (-s ours) am 532c8600: Revert 21f0f97eba
Merge commit '4c7c2f73af773872faf5a65167d74900865d96ba'

* commit '4c7c2f73af773872faf5a65167d74900865d96ba':
  Revert 21f0f97eba
2010-09-01 17:03:23 -07:00
3e115b81a4 am 17b44ee3: (-s ours) am 21f0f97e: Fix for crespo.
Merge commit '17b44ee3d82d7b8efa8dc3bc17d78fee11d72e01'

* commit '17b44ee3d82d7b8efa8dc3bc17d78fee11d72e01':
  Fix for crespo.
2010-09-01 17:01:06 -07:00
4c7c2f73af am 532c8600: Revert 21f0f97eba
Merge commit '532c86002bb89db43094b27ec50f001ae173c650' into gingerbread-plus-aosp

* commit '532c86002bb89db43094b27ec50f001ae173c650':
  Revert 21f0f97eba
2010-09-01 14:56:27 -07:00
17b44ee3d8 am 21f0f97e: Fix for crespo.
Merge commit '21f0f97ebabb47adcbfe8d38b02685f2019b4eb3' into gingerbread-plus-aosp

* commit '21f0f97ebabb47adcbfe8d38b02685f2019b4eb3':
  Fix for crespo.
2010-09-01 14:53:32 -07:00
532c86002b Revert 21f0f97eba
Change-Id: I46e4d7fe76e4219207e46f19e50188e38bb932b7
2010-09-01 14:52:22 -07:00
21f0f97eba Fix for crespo.
Change-Id: I008510bf614606a46a630c7adc39464ce1143ec3
2010-08-30 17:26:53 -07:00
37d58711f6 am 97900287: am 965f9dc4: merge -s ours from froyo-release so that upgrading to gingerbread is a git fast-forward
Merge commit '979002871ddc417dfdfb6a6542b9018626af7883'

* commit '979002871ddc417dfdfb6a6542b9018626af7883':
  fix bug in applying patches
  remove shadowed variable declaration
2010-08-24 11:54:52 -07:00
979002871d am 965f9dc4: merge -s ours from froyo-release so that upgrading to gingerbread is a git fast-forward
Merge commit '965f9dc45345486e885b59b4776f0ca5e765ec20' into gingerbread-plus-aosp

* commit '965f9dc45345486e885b59b4776f0ca5e765ec20':
  fix bug in applying patches
  remove shadowed variable declaration
2010-08-23 19:10:18 -07:00
965f9dc453 merge -s ours from froyo-release so that upgrading to gingerbread is a git fast-forward
Change-Id: I4d56dc0235f3df1306736c42144dccb26b876b74
2010-08-23 19:07:40 -07:00
baf6e35473 am c080bc54: am fbd7ae7a: am 201cd466: remove shadowed variable declaration
Merge commit 'c080bc549aaf272c77fe7903e52c2a2c0d8de1bb'

* commit 'c080bc549aaf272c77fe7903e52c2a2c0d8de1bb':
  remove shadowed variable declaration
2010-08-16 07:44:51 -07:00
8101125ee5 Changes to work with updated make_ext4fs tool that supports creating sparse images.
An extra parameter was added to the make_ext4fs() function, we these tools need
to be updated to match.

Change-Id: Id640a7f2b03153eb333b00337f0f991ff5332349
2010-08-13 19:22:47 -07:00
dff87121ad fix bug in applying patches
When restarting a patch from crashing in the middle of a large file,
we're not finding the correct patch to apply to the copy saved in
cache.

Change-Id: I41cb2b87d096bb7a28a10c4cf3902facd45d4c9d
2010-08-13 11:50:54 -07:00
beecac49da remove shadowed variable declaration
An accidental variable declaration ("int enough_space = ..." instead
of "enough_space = " inside a block) shadowing the real one meant we
were always using the copy-to-cache path for patching, even when not
necessary.  Remove it.  Enforce an absolute minimum of free space as
well, to avoid running into problems patching small files, now that
the copy-to-cache path is (inadvertently) well-tested.

Change-Id: Idb7d57241a9adcda2e11001fa44f0cd67ce40d19
2010-08-13 11:47:56 -07:00
c080bc549a am fbd7ae7a: am 201cd466: remove shadowed variable declaration
Merge commit 'fbd7ae7a1ce0060221241ed02c576983c1f48d34' into gingerbread-plus-aosp

* commit 'fbd7ae7a1ce0060221241ed02c576983c1f48d34':
  remove shadowed variable declaration
2010-08-13 10:02:51 -07:00
fbd7ae7a1c am 201cd466: remove shadowed variable declaration
Merge commit '201cd46680f5789e21a57fb4476ab0ba0c0ed4c0' into gingerbread

* commit '201cd46680f5789e21a57fb4476ab0ba0c0ed4c0':
  remove shadowed variable declaration
2010-08-13 09:59:52 -07:00
201cd46680 remove shadowed variable declaration
An accidental variable declaration ("int enough_space = ..." instead
of "enough_space = " inside a block) shadowing the real one meant we
were always using the copy-to-cache path for patching, even when not
necessary.  Remove it.  Enforce an absolute minimum of free space as
well, to avoid running into problems patching small files, now that
the copy-to-cache path is (inadvertently) well-tested.

Change-Id: Idb7d57241a9adcda2e11001fa44f0cd67ce40d19
2010-08-13 09:41:21 -07:00
80dcee145f am c4e32005: am 17986e6b: am 8cd9e4f3: fix bug in applying patches
Merge commit 'c4e3200578ad670bee9f5a88e90e7a77089d5df7'

* commit 'c4e3200578ad670bee9f5a88e90e7a77089d5df7':
  fix bug in applying patches
2010-08-12 17:57:45 -07:00
c4e3200578 am 17986e6b: am 8cd9e4f3: fix bug in applying patches
Merge commit '17986e6b8766ef9bdaa49efc7099e3867ca1978a' into gingerbread-plus-aosp

* commit '17986e6b8766ef9bdaa49efc7099e3867ca1978a':
  fix bug in applying patches
2010-08-12 17:55:24 -07:00
17986e6b87 am 8cd9e4f3: fix bug in applying patches
Merge commit '8cd9e4f3d4eba481b411482331293c8079ab24b2' into gingerbread

* commit '8cd9e4f3d4eba481b411482331293c8079ab24b2':
  fix bug in applying patches
2010-08-12 17:52:34 -07:00
8cd9e4f3d4 fix bug in applying patches
When restarting a patch from crashing in the middle of a large file,
we're not finding the correct patch to apply to the copy saved in
cache.

Change-Id: I41cb2b87d096bb7a28a10c4cf3902facd45d4c9d
2010-08-12 17:38:09 -07:00
04611da55b support using an EMMC misc partition to store recovery arguments
Change-Id: I9f912857cfc6afb8ba764f5541af7f01df029a77
2010-08-12 15:35:29 -07:00
db314d69f0 Working ASLR implementation
Separate files for retouch functionality are in minelf/*

ASLR for shared libraries is controlled by "-a" in ota_from_target_files.
Binary files are self-contained. Retouch logic can recover from crashes.

Signed-off-by: Hristo Bojinov <hristo@google.com>
Change-Id: I76c596abf4febd68c14f9d807ac62e8751e0b1bd
2010-08-02 14:17:33 -07:00
f635d2e910 don't go into file select menu when mounting external storage fails
Change-Id: If0efeddc28e1dbb52d9e52abf53323e2cc97c8f0
2010-08-02 11:34:46 -07:00
dc9e87c44b generalize "install from sdcard" to "install from external storage"
Allow sideloading of OTA packages from USB drives that appear as
/dev/block/sda1.

Change-Id: I1908576c24547cd0088475d8c8917699cd906868
2010-07-29 17:08:50 -07:00
b4277c25c6 Mute unwanted error message
This CL removes the following line from the top of build logs:
"diff: out/target/product/*/obj/PACKAGING/updater_extensions_intermediates/register.inc.list: No such file or directory"

Change-Id: I79c15a69a0b1b0da0e45620b45a7a0fea5625250
2010-07-20 17:31:04 -07:00
050d0f7fec resolved conflicts for merge of c02c37a1 to master
Change-Id: Iafb9cb4adf27a7086d587d95e94ab1bd050099dc
2010-07-09 09:13:51 -07:00
c02c37a1e6 am 23ceeea8: make a copy of sideloaded packages in /tmp before verifying
Merge commit '23ceeea85e6a3555dd3d7140128e310954cadf7f' into gingerbread-plus-aosp

* commit '23ceeea85e6a3555dd3d7140128e310954cadf7f':
  make a copy of sideloaded packages in /tmp before verifying
2010-07-08 17:50:26 -07:00
23ceeea85e make a copy of sideloaded packages in /tmp before verifying
Copy a sideloaded package into /tmp, then verify and install the copy,
to prevent malicious users from overwriting the package between
verification and install.

Bug: 2826890 package can be replaced during verification
Bug: 2058160 Recovery should copy sideloaded (sd card) update ...
Change-Id: I3de148b0f1a671f1974782b6855527caeaefda23
2010-07-08 17:27:55 -07:00
f291d858f8 EMMC support in applypatch
Let applypatch read and write EMMC partitions as well as MTD ones.
This enables incremental updates that include boot image changes, as
well as OTA of new recovery partitions.

Change-Id: I3766b9e77c639769ddf693b675da51d57f6e6b1d
2010-07-07 15:18:27 -07:00
3d177d055c support for ext4/EMMC filesystems in updater binary
Make the mount and format functions take extra parameters describing
the filesystem type and add support for mounting and formatting ext4
filesystems on EMMC.

Change recovery to consistently use stdout for status messages instead
of mixing stdout and stderr.
2010-07-01 15:42:28 -07:00
b442b45bdd Merge "support userdata and cache partitions using emmc/ext4 instead of mtd/yaffs" 2010-07-01 09:21:12 -07:00
42cfc2cc05 am 60faafcf: merge from open-source master
Merge commit '60faafcf01ff7f4179cdcaefd24b10ac4ee7f692'

* commit '60faafcf01ff7f4179cdcaefd24b10ac4ee7f692':
2010-06-30 15:54:38 -07:00
60faafcf01 merge from open-source master
Change-Id: I9d0122dbf1a9c2bd1898c41766c5bf4320f2313a
2010-06-30 15:51:09 -07:00
49c73a76a3 support userdata and cache partitions using emmc/ext4 instead of mtd/yaffs
Change-Id: I827af624c9ec7c64decb702de8c0310cf19b4141
2010-06-29 17:36:28 -07:00
ba634dc9f7 am c78a9698: am ecc76ba5: Set adbd to be disabled by default in recovery
Merge commit 'c78a9698dd55a165c2206c380f87f173bacba2aa'

* commit 'c78a9698dd55a165c2206c380f87f173bacba2aa':
  Set adbd to be disabled by default in recovery
2010-06-28 12:28:45 -07:00
4fef81a5a9 am ecc76ba5: Set adbd to be disabled by default in recovery
Merge commit 'ecc76ba5516d62a886f9c290906e0ca50702c9ab' into froyo-plus-aosp

* commit 'ecc76ba5516d62a886f9c290906e0ca50702c9ab':
  Set adbd to be disabled by default in recovery
2010-06-28 12:24:46 -07:00
c78a9698dd am ecc76ba5: Set adbd to be disabled by default in recovery
Merge commit 'ecc76ba5516d62a886f9c290906e0ca50702c9ab' into gingerbread

* commit 'ecc76ba5516d62a886f9c290906e0ca50702c9ab':
  Set adbd to be disabled by default in recovery
2010-06-28 12:24:16 -07:00
ecc76ba551 Set adbd to be disabled by default in recovery
Change-Id: I74fa6edc4b001247b20be52e8301d18407fede2c
2010-06-28 09:01:22 -07:00
9e6513f145 am 21b97ed5: Add __attribute__((format(printf, a, b))) to printf like functions.
Merge commit '21b97ed5693d039e8b9dea57a160d3307f412682'

* commit '21b97ed5693d039e8b9dea57a160d3307f412682':
  Add __attribute__((format(printf, a, b))) to printf like functions.
2010-06-24 17:16:49 -07:00
21b97ed569 Add __attribute__((format(printf, a, b))) to printf like functions.
Fix potential string format bug.

Change-Id: Ie05aac53b2c45a48bd68e340b76ccb21edfd28b7
2010-06-24 16:11:17 -07:00
b3d9a15b66 am dd6a0412: recovery: Add ueventd service 2010-05-14 14:35:50 -07:00
dd6a0412b5 recovery: Add ueventd service
Change-Id: Iad448bc1608f88c5db2108475f35b88ea2877b07
2010-05-14 13:44:13 -07:00
eb681fd491 am be42930f: am 97ca48e7: generic_x86 support 2010-05-03 16:17:50 -07:00
be42930f0b am 97ca48e7: generic_x86 support
Merge commit '97ca48e7f4ac8d3842f74f92b8f40d0e74733f38' into kraken

* commit '97ca48e7f4ac8d3842f74f92b8f40d0e74733f38':
  generic_x86 support
2010-05-03 16:14:51 -07:00
97ca48e7f4 generic_x86 support
Add in Makefiles and support files for x86 builds
  Based on changes by: wonjong.lee <wonjong.lee@windriver.com>
  Additional changes by: Mark Gross <mark.gross@intel.com>
  Additional changes by: Bruce Beare <brucex.j.beare@intel.com>

Change-Id: I71fcf58f116e4e9047e7d03fdb28e3308553ce5c
2010-05-03 15:58:50 -07:00
be598881d0 support installing any .zip file on the sdcard
Replaces the "install sdcard:update zip" menu option with one that
displays a menu of zip files (and subdirs) on the sdcard and lets you
pick which one to install.

Change-Id: I85c94c0e9bc8e05ca52031fc29ca2624c2695ced
2010-04-08 14:36:55 -07:00
6102227b0b am 52219a68: (-s ours) DO NOT MERGE Encrypted File Systems integration. Recovery changes. 2010-04-01 17:42:37 -07:00
52219a68a8 DO NOT MERGE
Encrypted File Systems integration. Recovery changes.

Change-Id: I932f73a6f937aac061128e1134eab08c30f0471d
2010-04-01 17:14:57 -07:00
f33e24645b Merge "Encrypted File Systems part 3. Recovery changes." 2010-03-31 10:06:27 -07:00
be17b1c0d7 am 51282faa: (-s ours) am 2654f5aa: (-s ours) DO NOT MERGE Removing unused recovey options. Please refer to Bug#2502219 for more info. 2010-03-29 16:31:06 -07:00
51282faa8c am 2654f5aa: (-s ours) DO NOT MERGE Removing unused recovey options. Please refer to Bug#2502219 for more info.
Merge commit '2654f5aae18c67ad9aff6dbcdf9bc67b62e37d2d' into kraken

* commit '2654f5aae18c67ad9aff6dbcdf9bc67b62e37d2d':
  DO NOT MERGE
2010-03-29 16:19:49 -07:00
31f6ee88ce Encrypted File Systems part 3. Recovery changes.
Change-Id: I932f73a6f937aac061128e1134eab08c30f0471d
2010-03-15 09:45:49 -07:00
167 changed files with 6306 additions and 8561 deletions

View File

@ -1,6 +1,3 @@
ifneq ($(TARGET_SIMULATOR),true)
ifeq ($(TARGET_ARCH),arm)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
@ -8,43 +5,51 @@ commands_recovery_local_path := $(LOCAL_PATH)
# LOCAL_CPP_EXTENSION := .c
LOCAL_SRC_FILES := \
recovery.c \
bootloader.c \
install.c \
roots.c \
ui.c \
mounts.c \
extendedcommands.c \
nandroid.c \
legacy.c \
commands.c \
recovery.c \
install.c \
roots.c \
ui.c \
verifier.c
extendedcommands.c \
nandroid.c \
../../system/core/toolbox/reboot.c \
firmware.c \
edifyscripting.c \
setprop.c \
default_recovery_ui.c \
verifier.c
LOCAL_SRC_FILES += \
reboot.c \
setprop.c
ifndef BOARD_HAS_NO_MISC_PARTITION
LOCAL_SRC_FILES += \
firmware.c \
bootloader.c
endif
ifdef BOARD_HIJACK_RECOVERY_PATH
LOCAL_CFLAGS += -DBOARD_HIJACK_RECOVERY_PATH=\"$(BOARD_HIJACK_RECOVERY_PATH)\"
endif
LOCAL_SRC_FILES += test_roots.c
ADDITIONAL_RECOVERY_FILES := $(shell echo $$ADDITIONAL_RECOVERY_FILES)
LOCAL_SRC_FILES += $(ADDITIONAL_RECOVERY_FILES)
LOCAL_MODULE := recovery
LOCAL_FORCE_STATIC_EXECUTABLE := true
RECOVERY_VERSION := ClockworkMod Recovery v2.5.1.8
ifdef I_AM_KOUSH
RECOVERY_NAME := ClockworkMod Recovery
LOCAL_CFLAGS += -DI_AM_KOUSH
else
RECOVERY_NAME := CWM-based Recovery
endif
RECOVERY_VERSION := $(RECOVERY_NAME) v5.5.0.4
LOCAL_CFLAGS += -DRECOVERY_VERSION="$(RECOVERY_VERSION)"
RECOVERY_API_VERSION := 2
LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION)
BOARD_RECOVERY_DEFINES := BOARD_HAS_NO_SELECT_BUTTON BOARD_SDCARD_DEVICE_PRIMARY BOARD_SDCARD_DEVICE_SECONDARY BOARD_SDEXT_DEVICE BOARD_SDEXT_FILESYSTEM BOARD_DATA_DEVICE BOARD_DATA_FILESYSTEM BOARD_DATADATA_DEVICE BOARD_DATADATA_FILESYSTEM BOARD_CACHE_DEVICE BOARD_CACHE_FILESYSTEM BOARD_SYSTEM_DEVICE BOARD_SYSTEM_FILESYSTEM BOARD_HAS_DATADATA BOARD_DATA_FILESYSTEM_OPTIONS BOARD_DATADATA_FILESYSTEM_OPTIONS BOARD_CACHE_FILESYSTEM_OPTIONS BOARD_SYSTEM_FILESYSTEM_OPTIONS BOARD_HAS_MTD_CACHE BOARD_USES_BMLUTILS BOARD_USES_MMCUTILS BOARD_HAS_SMALL_RECOVERY BOARD_LDPI_RECOVERY BOARD_RECOVERY_IGNORE_BOOTABLES BOARD_HAS_NO_MISC_PARTITION BOARD_HAS_SDCARD_INTERNAL BOARD_SDCARD_DEVICE_INTERNAL
ifneq ($(BOARD_USE_CUSTOM_RECOVERY_FONT),)
BOARD_RECOVERY_CHAR_WIDTH := $(shell echo $(BOARD_USE_CUSTOM_RECOVERY_FONT) | cut -d _ -f 2 | cut -d . -f 1 | cut -d x -f 1)
BOARD_RECOVERY_CHAR_HEIGHT := $(shell echo $(BOARD_USE_CUSTOM_RECOVERY_FONT) | cut -d _ -f 2 | cut -d . -f 1 | cut -d x -f 2)
else
BOARD_RECOVERY_CHAR_WIDTH := 10
BOARD_RECOVERY_CHAR_HEIGHT := 18
endif
LOCAL_CFLAGS += -DBOARD_RECOVERY_CHAR_WIDTH=$(BOARD_RECOVERY_CHAR_WIDTH) -DBOARD_RECOVERY_CHAR_HEIGHT=$(BOARD_RECOVERY_CHAR_HEIGHT)
BOARD_RECOVERY_DEFINES := BOARD_HAS_NO_SELECT_BUTTON BOARD_UMS_LUNFILE BOARD_RECOVERY_ALWAYS_WIPES BOARD_RECOVERY_HANDLES_MOUNT BOARD_TOUCH_RECOVERY
$(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
$(if $($(board_define)), \
@ -52,6 +57,12 @@ $(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
) \
)
LOCAL_STATIC_LIBRARIES :=
LOCAL_CFLAGS += -DUSE_EXT4
LOCAL_C_INCLUDES += system/extras/ext4_utils
LOCAL_STATIC_LIBRARIES += libext4_utils libz
# This binary is in the recovery ramdisk, which is otherwise a copy of root.
# It gets copied there in config/Makefile. LOCAL_MODULE_TAGS suppresses
# a (redundant) copy of the binary in /system/bin for user builds.
@ -59,51 +70,59 @@ $(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
LOCAL_MODULE_TAGS := eng
LOCAL_STATIC_LIBRARIES :=
ifeq ($(BOARD_CUSTOM_RECOVERY_KEYMAPPING),)
LOCAL_SRC_FILES += default_recovery_ui.c
LOCAL_SRC_FILES += default_recovery_keys.c
else
LOCAL_SRC_FILES += $(BOARD_CUSTOM_RECOVERY_KEYMAPPING)
endif
LOCAL_STATIC_LIBRARIES += libbusybox libclearsilverregex libmkyaffs2image libunyaffs liberase_image libdump_image libflash_image
LOCAL_STATIC_LIBRARIES += libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_STATIC_LIBRARIES += libamend
LOCAL_STATIC_LIBRARIES += libext4_utils libz
LOCAL_STATIC_LIBRARIES += libminzip libunz libmincrypt
LOCAL_STATIC_LIBRARIES += libedify libbusybox libmkyaffs2image libunyaffs liberase_image libdump_image libflash_image
LOCAL_STATIC_LIBRARIES += libcrecovery libflashutils libmtdutils libmmcutils libbmlutils
ifeq ($(BOARD_USES_BML_OVER_MTD),true)
LOCAL_STATIC_LIBRARIES += libbml_over_mtd
endif
LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libpng libcutils
LOCAL_STATIC_LIBRARIES += libstdc++ libc
LOCAL_C_INCLUDES += system/extras/ext4_utils
include $(BUILD_EXECUTABLE)
RECOVERY_LINKS := amend busybox flash_image dump_image mkyaffs2image unyaffs erase_image nandroid reboot
RECOVERY_LINKS := edify busybox flash_image dump_image mkyaffs2image unyaffs erase_image nandroid reboot volume setprop
# nc is provided by external/netcat
SYMLINKS := $(addprefix $(TARGET_RECOVERY_ROOT_OUT)/sbin/,$(RECOVERY_LINKS))
$(SYMLINKS): RECOVERY_BINARY := $(LOCAL_MODULE)
$(SYMLINKS): $(LOCAL_INSTALLED_MODULE)
RECOVERY_SYMLINKS := $(addprefix $(TARGET_RECOVERY_ROOT_OUT)/sbin/,$(RECOVERY_LINKS))
$(RECOVERY_SYMLINKS): RECOVERY_BINARY := $(LOCAL_MODULE)
$(RECOVERY_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
@echo "Symlink: $@ -> $(RECOVERY_BINARY)"
@mkdir -p $(dir $@)
@rm -rf $@
$(hide) ln -sf $(RECOVERY_BINARY) $@
ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS)
ALL_DEFAULT_INSTALLED_MODULES += $(RECOVERY_SYMLINKS)
# Now let's do recovery symlinks
BUSYBOX_LINKS := $(shell cat external/busybox/busybox-minimal.links)
SYMLINKS := $(addprefix $(TARGET_RECOVERY_ROOT_OUT)/sbin/,$(filter-out $(exclude),$(notdir $(BUSYBOX_LINKS))))
$(SYMLINKS): BUSYBOX_BINARY := busybox
$(SYMLINKS): $(LOCAL_INSTALLED_MODULE)
exclude := tune2fs mke2fs
RECOVERY_BUSYBOX_SYMLINKS := $(addprefix $(TARGET_RECOVERY_ROOT_OUT)/sbin/,$(filter-out $(exclude),$(notdir $(BUSYBOX_LINKS))))
$(RECOVERY_BUSYBOX_SYMLINKS): BUSYBOX_BINARY := busybox
$(RECOVERY_BUSYBOX_SYMLINKS): $(LOCAL_INSTALLED_MODULE)
@echo "Symlink: $@ -> $(BUSYBOX_BINARY)"
@mkdir -p $(dir $@)
@rm -rf $@
$(hide) ln -sf $(BUSYBOX_BINARY) $@
ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS)
ALL_DEFAULT_INSTALLED_MODULES += $(RECOVERY_BUSYBOX_SYMLINKS)
include $(CLEAR_VARS)
LOCAL_MODULE := nandroid-md5.sh
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := nandroid-md5.sh
@ -111,7 +130,7 @@ include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_MODULE := killrecovery.sh
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_SRC_FILES := killrecovery.sh
@ -131,11 +150,11 @@ LOCAL_STATIC_LIBRARIES := libmincrypt libcutils libstdc++ libc
include $(BUILD_EXECUTABLE)
include $(commands_recovery_local_path)/amend/Android.mk
include $(commands_recovery_local_path)/bmlutils/Android.mk
include $(commands_recovery_local_path)/flashutils/Android.mk
include $(commands_recovery_local_path)/libcrecovery/Android.mk
include $(commands_recovery_local_path)/minui/Android.mk
include $(commands_recovery_local_path)/minelf/Android.mk
include $(commands_recovery_local_path)/minzip/Android.mk
include $(commands_recovery_local_path)/mtdutils/Android.mk
include $(commands_recovery_local_path)/mmcutils/Android.mk
@ -145,7 +164,3 @@ include $(commands_recovery_local_path)/updater/Android.mk
include $(commands_recovery_local_path)/applypatch/Android.mk
include $(commands_recovery_local_path)/utilities/Android.mk
commands_recovery_local_path :=
endif # TARGET_ARCH == arm
endif # !TARGET_SIMULATOR

View File

@ -1,53 +0,0 @@
# Copyright 2007 The Android Open Source Project
#
LOCAL_PATH := $(call my-dir)
amend_src_files := \
amend.c \
lexer.l \
parser_y.y \
ast.c \
symtab.c \
commands.c \
permissions.c \
execute.c
amend_test_files := \
test_symtab.c \
test_commands.c \
test_permissions.c
# "-x c" forces the lex/yacc files to be compiled as c;
# the build system otherwise forces them to be c++.
amend_cflags := -Wall -x c
#
# Build the host-side command line tool
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
$(amend_src_files) \
$(amend_test_files) \
register.c \
main.c
LOCAL_CFLAGS := $(amend_cflags) -g -O0
LOCAL_MODULE := amend
LOCAL_YACCFLAGS := -v
include $(BUILD_HOST_EXECUTABLE)
#
# Build the device-side library
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(amend_src_files)
LOCAL_SRC_FILES += $(amend_test_files)
LOCAL_CFLAGS := $(amend_cflags)
LOCAL_MODULE := libamend
include $(BUILD_STATIC_LIBRARY)

View File

@ -1,32 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "amend.h"
#include "lexer.h"
extern const AmCommandList *gCommands;
const AmCommandList *
parseAmendScript(const char *buf, size_t bufLen)
{
setLexerInputBuffer(buf, bufLen);
int ret = yyparse();
if (ret != 0) {
return NULL;
}
return gCommands;
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AMEND_H_
#define AMEND_H_
#include "ast.h"
#include "execute.h"
const AmCommandList *parseAmendScript(const char *buf, size_t bufLen);
#endif // AMEND_H_

View File

@ -1,198 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "ast.h"
static const char gSpaces[] =
" "
" "
" "
" "
" "
" "
" ";
const int gSpacesMax = sizeof(gSpaces) - 1;
static const char *
pad(int level)
{
level *= 4;
if (level > gSpacesMax) {
level = gSpacesMax;
}
return gSpaces + gSpacesMax - level;
}
void dumpBooleanValue(int level, const AmBooleanValue *booleanValue);
void dumpStringValue(int level, const AmStringValue *stringValue);
void
dumpBooleanExpression(int level, const AmBooleanExpression *booleanExpression)
{
const char *op;
bool unary = false;
switch (booleanExpression->op) {
case AM_BOP_NOT:
op = "NOT";
unary = true;
break;
case AM_BOP_EQ:
op = "EQ";
break;
case AM_BOP_NE:
op = "NE";
break;
case AM_BOP_AND:
op = "AND";
break;
case AM_BOP_OR:
op = "OR";
break;
default:
op = "??";
break;
}
printf("%sBOOLEAN %s {\n", pad(level), op);
dumpBooleanValue(level + 1, booleanExpression->arg1);
if (!unary) {
dumpBooleanValue(level + 1, booleanExpression->arg2);
}
printf("%s}\n", pad(level));
}
void
dumpFunctionArguments(int level, const AmFunctionArguments *functionArguments)
{
int i;
for (i = 0; i < functionArguments->argc; i++) {
dumpStringValue(level, &functionArguments->argv[i]);
}
}
void
dumpFunctionCall(int level, const AmFunctionCall *functionCall)
{
printf("%sFUNCTION %s (\n", pad(level), functionCall->name);
dumpFunctionArguments(level + 1, functionCall->args);
printf("%s)\n", pad(level));
}
void
dumpStringValue(int level, const AmStringValue *stringValue)
{
switch (stringValue->type) {
case AM_SVAL_LITERAL:
printf("%s\"%s\"\n", pad(level), stringValue->u.literal);
break;
case AM_SVAL_FUNCTION:
dumpFunctionCall(level, stringValue->u.function);
break;
default:
printf("%s<UNKNOWN SVAL TYPE %d>\n", pad(level), stringValue->type);
break;
}
}
void
dumpStringComparisonExpression(int level,
const AmStringComparisonExpression *stringComparisonExpression)
{
const char *op;
switch (stringComparisonExpression->op) {
case AM_SOP_LT:
op = "LT";
break;
case AM_SOP_LE:
op = "LE";
break;
case AM_SOP_GT:
op = "GT";
break;
case AM_SOP_GE:
op = "GE";
break;
case AM_SOP_EQ:
op = "EQ";
break;
case AM_SOP_NE:
op = "NE";
break;
default:
op = "??";
break;
}
printf("%sSTRING %s {\n", pad(level), op);
dumpStringValue(level + 1, stringComparisonExpression->arg1);
dumpStringValue(level + 1, stringComparisonExpression->arg2);
printf("%s}\n", pad(level));
}
void
dumpBooleanValue(int level, const AmBooleanValue *booleanValue)
{
switch (booleanValue->type) {
case AM_BVAL_EXPRESSION:
dumpBooleanExpression(level, &booleanValue->u.expression);
break;
case AM_BVAL_STRING_COMPARISON:
dumpStringComparisonExpression(level,
&booleanValue->u.stringComparison);
break;
default:
printf("%s<UNKNOWN BVAL TYPE %d>\n", pad(1), booleanValue->type);
break;
}
}
void
dumpWordList(const AmWordList *wordList)
{
int i;
for (i = 0; i < wordList->argc; i++) {
printf("%s\"%s\"\n", pad(1), wordList->argv[i]);
}
}
void
dumpCommandArguments(const AmCommandArguments *commandArguments)
{
if (commandArguments->booleanArgs) {
dumpBooleanValue(1, commandArguments->u.b);
} else {
dumpWordList(commandArguments->u.w);
}
}
void
dumpCommand(const AmCommand *command)
{
printf("command \"%s\" {\n", command->name);
dumpCommandArguments(command->args);
printf("}\n");
}
void
dumpCommandList(const AmCommandList *commandList)
{
int i;
for (i = 0; i < commandList->commandCount; i++) {
dumpCommand(commandList->commands[i]);
}
}

View File

@ -1,165 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AMEND_AST_H_
#define AMEND_AST_H_
#include "commands.h"
typedef struct AmStringValue AmStringValue;
typedef struct {
int argc;
AmStringValue *argv;
} AmFunctionArguments;
/* An internal structure used only by the parser;
* will not appear in the output AST.
xxx try to move this into parser.h
*/
typedef struct AmFunctionArgumentBuilder AmFunctionArgumentBuilder;
struct AmFunctionArgumentBuilder {
AmFunctionArgumentBuilder *next;
AmStringValue *arg;
int argCount;
};
typedef struct AmWordListBuilder AmWordListBuilder;
struct AmWordListBuilder {
AmWordListBuilder *next;
const char *word;
int wordCount;
};
typedef struct {
const char *name;
Function *fn;
AmFunctionArguments *args;
} AmFunctionCall;
/* <string-value> ::=
* <literal-string> |
* <function-call>
*/
struct AmStringValue {
unsigned int line;
enum {
AM_SVAL_LITERAL,
AM_SVAL_FUNCTION,
} type;
union {
const char *literal;
//xxx inline instead of using pointers
AmFunctionCall *function;
} u;
};
/* <string-comparison-expression> ::=
* <string-value> <string-comparison-operator> <string-value>
*/
typedef struct {
unsigned int line;
enum {
AM_SOP_LT,
AM_SOP_LE,
AM_SOP_GT,
AM_SOP_GE,
AM_SOP_EQ,
AM_SOP_NE,
} op;
AmStringValue *arg1;
AmStringValue *arg2;
} AmStringComparisonExpression;
/* <boolean-expression> ::=
* ! <boolean-value> |
* <boolean-value> <binary-boolean-operator> <boolean-value>
*/
typedef struct AmBooleanValue AmBooleanValue;
typedef struct {
unsigned int line;
enum {
AM_BOP_NOT,
AM_BOP_EQ,
AM_BOP_NE,
AM_BOP_AND,
AM_BOP_OR,
} op;
AmBooleanValue *arg1;
AmBooleanValue *arg2;
} AmBooleanExpression;
/* <boolean-value> ::=
* <boolean-expression> |
* <string-comparison-expression>
*/
struct AmBooleanValue {
unsigned int line;
enum {
AM_BVAL_EXPRESSION,
AM_BVAL_STRING_COMPARISON,
} type;
union {
AmBooleanExpression expression;
AmStringComparisonExpression stringComparison;
} u;
};
typedef struct {
unsigned int line;
int argc;
const char **argv;
} AmWordList;
typedef struct {
bool booleanArgs;
union {
AmWordList *w;
AmBooleanValue *b;
} u;
} AmCommandArguments;
typedef struct {
unsigned int line;
const char *name;
Command *cmd;
AmCommandArguments *args;
} AmCommand;
typedef struct {
AmCommand **commands;
int commandCount;
int arraySize;
} AmCommandList;
void dumpCommandList(const AmCommandList *commandList);
#endif // AMEND_AST_H_

View File

@ -1,273 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "symtab.h"
#include "commands.h"
#if 1
#define TRACE(...) printf(__VA_ARGS__)
#else
#define TRACE(...) /**/
#endif
typedef enum {
CMD_TYPE_UNKNOWN = -1,
CMD_TYPE_COMMAND = 0,
CMD_TYPE_FUNCTION
} CommandType;
typedef struct {
const char *name;
void *cookie;
CommandType type;
CommandArgumentType argType;
CommandHook hook;
} CommandEntry;
static struct {
SymbolTable *symbolTable;
bool commandStateInitialized;
} gCommandState;
int
commandInit()
{
if (gCommandState.commandStateInitialized) {
return -1;
}
gCommandState.symbolTable = createSymbolTable();
if (gCommandState.symbolTable == NULL) {
return -1;
}
gCommandState.commandStateInitialized = true;
return 0;
}
void
commandCleanup()
{
if (gCommandState.commandStateInitialized) {
gCommandState.commandStateInitialized = false;
deleteSymbolTable(gCommandState.symbolTable);
gCommandState.symbolTable = NULL;
//xxx need to free the entries and names in the symbol table
}
}
static int
registerCommandInternal(const char *name, CommandType type,
CommandArgumentType argType, CommandHook hook, void *cookie)
{
CommandEntry *entry;
if (!gCommandState.commandStateInitialized) {
return -1;
}
if (name == NULL || hook == NULL) {
return -1;
}
if (type != CMD_TYPE_COMMAND && type != CMD_TYPE_FUNCTION) {
return -1;
}
if (argType != CMD_ARGS_BOOLEAN && argType != CMD_ARGS_WORDS) {
return -1;
}
entry = (CommandEntry *)malloc(sizeof(CommandEntry));
if (entry != NULL) {
entry->name = strdup(name);
if (entry->name != NULL) {
int ret;
entry->cookie = cookie;
entry->type = type;
entry->argType = argType;
entry->hook = hook;
ret = addToSymbolTable(gCommandState.symbolTable,
entry->name, entry->type, entry);
if (ret == 0) {
return 0;
}
}
free(entry);
}
return -1;
}
int
registerCommand(const char *name,
CommandArgumentType argType, CommandHook hook, void *cookie)
{
return registerCommandInternal(name,
CMD_TYPE_COMMAND, argType, hook, cookie);
}
int
registerFunction(const char *name, FunctionHook hook, void *cookie)
{
return registerCommandInternal(name,
CMD_TYPE_FUNCTION, CMD_ARGS_WORDS, (CommandHook)hook, cookie);
}
Command *
findCommand(const char *name)
{
return (Command *)findInSymbolTable(gCommandState.symbolTable,
name, CMD_TYPE_COMMAND);
}
Function *
findFunction(const char *name)
{
return (Function *)findInSymbolTable(gCommandState.symbolTable,
name, CMD_TYPE_FUNCTION);
}
CommandArgumentType
getCommandArgumentType(Command *cmd)
{
CommandEntry *entry = (CommandEntry *)cmd;
if (entry != NULL) {
return entry->argType;
}
return CMD_ARGS_UNKNOWN;
}
static int
callCommandInternal(CommandEntry *entry, int argc, const char *argv[],
PermissionRequestList *permissions)
{
if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
(argc == 0 || (argc > 0 && argv != NULL)))
{
if (permissions == NULL) {
int i;
for (i = 0; i < argc; i++) {
if (argv[i] == NULL) {
goto bail;
}
}
}
TRACE("calling command %s\n", entry->name);
return entry->hook(entry->name, entry->cookie, argc, argv, permissions);
//xxx if permissions, make sure the entry has added at least one element.
}
bail:
return -1;
}
static int
callBooleanCommandInternal(CommandEntry *entry, bool arg,
PermissionRequestList *permissions)
{
if (entry != NULL && entry->argType == CMD_ARGS_BOOLEAN) {
TRACE("calling boolean command %s\n", entry->name);
return entry->hook(entry->name, entry->cookie, arg ? 1 : 0, NULL,
permissions);
//xxx if permissions, make sure the entry has added at least one element.
}
return -1;
}
int
callCommand(Command *cmd, int argc, const char *argv[])
{
return callCommandInternal((CommandEntry *)cmd, argc, argv, NULL);
}
int
callBooleanCommand(Command *cmd, bool arg)
{
return callBooleanCommandInternal((CommandEntry *)cmd, arg, NULL);
}
int
getCommandPermissions(Command *cmd, int argc, const char *argv[],
PermissionRequestList *permissions)
{
if (permissions != NULL) {
return callCommandInternal((CommandEntry *)cmd, argc, argv,
permissions);
}
return -1;
}
int
getBooleanCommandPermissions(Command *cmd, bool arg,
PermissionRequestList *permissions)
{
if (permissions != NULL) {
return callBooleanCommandInternal((CommandEntry *)cmd, arg,
permissions);
}
return -1;
}
int
callFunctionInternal(CommandEntry *entry, int argc, const char *argv[],
char **result, size_t *resultLen, PermissionRequestList *permissions)
{
if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
(argc == 0 || (argc > 0 && argv != NULL)))
{
if ((permissions == NULL && result != NULL) ||
(permissions != NULL && result == NULL))
{
if (permissions == NULL) {
/* This is the actual invocation of the function,
* which means that none of the arguments are allowed
* to be NULL.
*/
int i;
for (i = 0; i < argc; i++) {
if (argv[i] == NULL) {
goto bail;
}
}
}
TRACE("calling function %s\n", entry->name);
return ((FunctionHook)entry->hook)(entry->name, entry->cookie,
argc, argv, result, resultLen, permissions);
//xxx if permissions, make sure the entry has added at least one element.
}
}
bail:
return -1;
}
int
callFunction(Function *fn, int argc, const char *argv[],
char **result, size_t *resultLen)
{
return callFunctionInternal((CommandEntry *)fn, argc, argv,
result, resultLen, NULL);
}
int
getFunctionPermissions(Function *fn, int argc, const char *argv[],
PermissionRequestList *permissions)
{
if (permissions != NULL) {
return callFunctionInternal((CommandEntry *)fn, argc, argv,
NULL, NULL, permissions);
}
return -1;
}

View File

@ -1,96 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AMEND_COMMANDS_H_
#define AMEND_COMMANDS_H_
#include "permissions.h"
/* Invoke or dry-run a command. If "permissions" is non-NULL,
* the hook should fill it out with the list of files and operations that
* it would need to complete its operation. If "permissions" is NULL,
* the hook should do the actual work specified by its arguments.
*
* When a command is called with non-NULL "permissions", some arguments
* may be NULL. A NULL argument indicates that the argument is actually
* the output of another function, so is not known at permissions time.
* The permissions of leaf-node functions (those that have only literal
* strings as arguments) will get appended to the permissions of the
* functions that call them. However, to be completely safe, functions
* that receive a NULL argument should request the broadest-possible
* permissions for the range of the input argument.
*
* When a boolean command is called, "argc" is the boolean value and
* "argv" is NULL.
*/
typedef int (*CommandHook)(const char *name, void *cookie,
int argc, const char *argv[],
PermissionRequestList *permissions);
int commandInit(void);
void commandCleanup(void);
/*
* Command management
*/
struct Command;
typedef struct Command Command;
typedef enum {
CMD_ARGS_UNKNOWN = -1,
CMD_ARGS_BOOLEAN = 0,
CMD_ARGS_WORDS
} CommandArgumentType;
int registerCommand(const char *name,
CommandArgumentType argType, CommandHook hook, void *cookie);
Command *findCommand(const char *name);
CommandArgumentType getCommandArgumentType(Command *cmd);
int callCommand(Command *cmd, int argc, const char *argv[]);
int callBooleanCommand(Command *cmd, bool arg);
int getCommandPermissions(Command *cmd, int argc, const char *argv[],
PermissionRequestList *permissions);
int getBooleanCommandPermissions(Command *cmd, bool arg,
PermissionRequestList *permissions);
/*
* Function management
*/
typedef int (*FunctionHook)(const char *name, void *cookie,
int argc, const char *argv[],
char **result, size_t *resultLen,
PermissionRequestList *permissions);
struct Function;
typedef struct Function Function;
int registerFunction(const char *name, FunctionHook hook, void *cookie);
Function *findFunction(const char *name);
int callFunction(Function *fn, int argc, const char *argv[],
char **result, size_t *resultLen);
int getFunctionPermissions(Function *fn, int argc, const char *argv[],
PermissionRequestList *permissions);
#endif // AMEND_COMMANDS_H_

View File

@ -1,315 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#undef NDEBUG
#include <assert.h>
#include "ast.h"
#include "execute.h"
typedef struct {
int c;
const char **v;
} StringList;
static int execBooleanValue(ExecContext *ctx,
const AmBooleanValue *booleanValue, bool *result);
static int execStringValue(ExecContext *ctx, const AmStringValue *stringValue,
const char **result);
static int
execBooleanExpression(ExecContext *ctx,
const AmBooleanExpression *booleanExpression, bool *result)
{
int ret;
bool arg1, arg2;
bool unary;
assert(ctx != NULL);
assert(booleanExpression != NULL);
assert(result != NULL);
if (ctx == NULL || booleanExpression == NULL || result == NULL) {
return -__LINE__;
}
if (booleanExpression->op == AM_BOP_NOT) {
unary = true;
} else {
unary = false;
}
ret = execBooleanValue(ctx, booleanExpression->arg1, &arg1);
if (ret != 0) return ret;
if (!unary) {
ret = execBooleanValue(ctx, booleanExpression->arg2, &arg2);
if (ret != 0) return ret;
} else {
arg2 = false;
}
switch (booleanExpression->op) {
case AM_BOP_NOT:
*result = !arg1;
break;
case AM_BOP_EQ:
*result = (arg1 == arg2);
break;
case AM_BOP_NE:
*result = (arg1 != arg2);
break;
case AM_BOP_AND:
*result = (arg1 && arg2);
break;
case AM_BOP_OR:
*result = (arg1 || arg2);
break;
default:
return -__LINE__;
}
return 0;
}
static int
execFunctionArguments(ExecContext *ctx,
const AmFunctionArguments *functionArguments, StringList *result)
{
int ret;
assert(ctx != NULL);
assert(functionArguments != NULL);
assert(result != NULL);
if (ctx == NULL || functionArguments == NULL || result == NULL) {
return -__LINE__;
}
result->c = functionArguments->argc;
result->v = (const char **)malloc(result->c * sizeof(const char *));
if (result->v == NULL) {
result->c = 0;
return -__LINE__;
}
int i;
for (i = 0; i < functionArguments->argc; i++) {
ret = execStringValue(ctx, &functionArguments->argv[i], &result->v[i]);
if (ret != 0) {
result->c = 0;
free(result->v);
//TODO: free the individual args, if we're responsible for them.
result->v = NULL;
return ret;
}
}
return 0;
}
static int
execFunctionCall(ExecContext *ctx, const AmFunctionCall *functionCall,
const char **result)
{
int ret;
assert(ctx != NULL);
assert(functionCall != NULL);
assert(result != NULL);
if (ctx == NULL || functionCall == NULL || result == NULL) {
return -__LINE__;
}
StringList args;
ret = execFunctionArguments(ctx, functionCall->args, &args);
if (ret != 0) {
return ret;
}
ret = callFunction(functionCall->fn, args.c, args.v, (char **)result, NULL);
if (ret != 0) {
return ret;
}
//TODO: clean up args
return 0;
}
static int
execStringValue(ExecContext *ctx, const AmStringValue *stringValue,
const char **result)
{
int ret;
assert(ctx != NULL);
assert(stringValue != NULL);
assert(result != NULL);
if (ctx == NULL || stringValue == NULL || result == NULL) {
return -__LINE__;
}
switch (stringValue->type) {
case AM_SVAL_LITERAL:
*result = strdup(stringValue->u.literal);
break;
case AM_SVAL_FUNCTION:
ret = execFunctionCall(ctx, stringValue->u.function, result);
if (ret != 0) {
return ret;
}
break;
default:
return -__LINE__;
}
return 0;
}
static int
execStringComparisonExpression(ExecContext *ctx,
const AmStringComparisonExpression *stringComparisonExpression,
bool *result)
{
int ret;
assert(ctx != NULL);
assert(stringComparisonExpression != NULL);
assert(result != NULL);
if (ctx == NULL || stringComparisonExpression == NULL || result == NULL) {
return -__LINE__;
}
const char *arg1, *arg2;
ret = execStringValue(ctx, stringComparisonExpression->arg1, &arg1);
if (ret != 0) {
return ret;
}
ret = execStringValue(ctx, stringComparisonExpression->arg2, &arg2);
if (ret != 0) {
return ret;
}
int cmp = strcmp(arg1, arg2);
switch (stringComparisonExpression->op) {
case AM_SOP_LT:
*result = (cmp < 0);
break;
case AM_SOP_LE:
*result = (cmp <= 0);
break;
case AM_SOP_GT:
*result = (cmp > 0);
break;
case AM_SOP_GE:
*result = (cmp >= 0);
break;
case AM_SOP_EQ:
*result = (cmp == 0);
break;
case AM_SOP_NE:
*result = (cmp != 0);
break;
default:
return -__LINE__;
break;
}
return 0;
}
static int
execBooleanValue(ExecContext *ctx, const AmBooleanValue *booleanValue,
bool *result)
{
int ret;
assert(ctx != NULL);
assert(booleanValue != NULL);
assert(result != NULL);
if (ctx == NULL || booleanValue == NULL || result == NULL) {
return -__LINE__;
}
switch (booleanValue->type) {
case AM_BVAL_EXPRESSION:
ret = execBooleanExpression(ctx, &booleanValue->u.expression, result);
break;
case AM_BVAL_STRING_COMPARISON:
ret = execStringComparisonExpression(ctx,
&booleanValue->u.stringComparison, result);
break;
default:
ret = -__LINE__;
break;
}
return ret;
}
static int
execCommand(ExecContext *ctx, const AmCommand *command)
{
int ret;
assert(ctx != NULL);
assert(command != NULL);
if (ctx == NULL || command == NULL) {
return -__LINE__;
}
CommandArgumentType argType;
argType = getCommandArgumentType(command->cmd);
switch (argType) {
case CMD_ARGS_BOOLEAN:
{
bool bVal;
ret = execBooleanValue(ctx, command->args->u.b, &bVal);
if (ret == 0) {
ret = callBooleanCommand(command->cmd, bVal);
}
}
break;
case CMD_ARGS_WORDS:
{
AmWordList *words = command->args->u.w;
ret = callCommand(command->cmd, words->argc, words->argv);
}
break;
default:
ret = -__LINE__;
break;
}
return ret;
}
int
execCommandList(ExecContext *ctx, const AmCommandList *commandList)
{
int i;
for (i = 0; i < commandList->commandCount; i++) {
int ret = execCommand(ctx, commandList->commands[i]);
if (ret != 0) {
int line = commandList->commands[i]->line;
return line > 0 ? line : ret;
}
}
return 0;
}

View File

@ -1,25 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AMEND_EXECUTE_H_
#define AMEND_EXECUTE_H_
typedef struct ExecContext ExecContext;
/* Returns 0 on success, otherwise the line number that failed. */
int execCommandList(ExecContext *ctx, const AmCommandList *commandList);
#endif // AMEND_EXECUTE_H_

View File

@ -1,43 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AMEND_LEXER_H_
#define AMEND_LEXER_H_
#define AMEND_LEXER_BUFFER_INPUT 1
void yyerror(const char *msg);
int yylex(void);
#if AMEND_LEXER_BUFFER_INPUT
void setLexerInputBuffer(const char *buf, size_t buflen);
#else
#include <stdio.h>
void yyset_in(FILE *in_str);
#endif
const char *tokenToString(int token);
typedef enum {
AM_UNKNOWN_ARGS,
AM_WORD_ARGS,
AM_BOOLEAN_ARGS,
} AmArgumentType;
void setLexerArgumentType(AmArgumentType type);
int getLexerLineNumber(void);
#endif // AMEND_LEXER_H_

View File

@ -1,299 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
%{
#include <stdio.h>
#include <stdlib.h>
#include "ast.h"
#include "lexer.h"
#include "parser.h"
const char *tokenToString(int token)
{
static char scratch[128];
switch (token) {
case TOK_AND:
return "&&";
case TOK_OR:
return "||";
case TOK_EQ:
return "==";
case TOK_NE:
return "!=";
case TOK_GE:
return ">=";
case TOK_LE:
return "<=";
case TOK_EOF:
return "EOF";
case TOK_EOL:
return "EOL\n";
case TOK_STRING:
snprintf(scratch, sizeof(scratch),
"STRING<%s>", yylval.literalString);
return scratch;
case TOK_IDENTIFIER:
snprintf(scratch, sizeof(scratch), "IDENTIFIER<%s>",
yylval.literalString);
return scratch;
case TOK_WORD:
snprintf(scratch, sizeof(scratch), "WORD<%s>",
yylval.literalString);
return scratch;
default:
if (token > ' ' && token <= '~') {
scratch[0] = (char)token;
scratch[1] = '\0';
} else {
snprintf(scratch, sizeof(scratch), "??? <%d>", token);
}
return scratch;
}
}
typedef struct {
char *value;
char *nextc;
unsigned int alloc_size;
} AmString;
static int addCharToString(AmString *str, char c)
{
if ((unsigned int)(str->nextc - str->value) >= str->alloc_size) {
char *new_value;
unsigned int new_size;
new_size = (str->alloc_size + 1) * 2;
if (new_size < 64) {
new_size = 64;
}
new_value = (char *)realloc(str->value, new_size);
if (new_value == NULL) {
yyerror("out of memory");
return -1;
}
str->nextc = str->nextc - str->value + new_value;
str->value = new_value;
str->alloc_size = new_size;
}
*str->nextc++ = c;
return 0;
}
static int setString(AmString *str, const char *p)
{
str->nextc = str->value;
while (*p != '\0') {
//TODO: add the whole string at once
addCharToString(str, *p++);
}
return addCharToString(str, '\0');
}
static AmString gStr = { NULL, NULL, 0 };
static int gLineNumber = 1;
static AmArgumentType gArgumentType = AM_UNKNOWN_ARGS;
static const char *gErrorMessage = NULL;
#if AMEND_LEXER_BUFFER_INPUT
static const char *gInputBuffer;
static const char *gInputBufferNext;
static const char *gInputBufferEnd;
# define YY_INPUT(buf, result, max_size) \
do { \
int nbytes = gInputBufferEnd - gInputBufferNext; \
if (nbytes > 0) { \
if (nbytes > max_size) { \
nbytes = max_size; \
} \
memcpy(buf, gInputBufferNext, nbytes); \
gInputBufferNext += nbytes; \
result = nbytes; \
} else { \
result = YY_NULL; \
} \
} while (false)
#endif // AMEND_LEXER_BUFFER_INPUT
%}
%option noyywrap
%x QUOTED_STRING BOOLEAN WORDS
ident [a-zA-Z_][a-zA-Z_0-9]*
word [^ \t\r\n"]+
%%
/* This happens at the beginning of each call to yylex().
*/
if (gArgumentType == AM_WORD_ARGS) {
BEGIN(WORDS);
} else if (gArgumentType == AM_BOOLEAN_ARGS) {
BEGIN(BOOLEAN);
}
/*xxx require everything to be 7-bit-clean, printable characters */
<INITIAL>{
{ident}/[ \t\r\n] {
/* The only token we recognize in the initial
* state is an identifier followed by whitespace.
*/
setString(&gStr, yytext);
yylval.literalString = gStr.value;
return TOK_IDENTIFIER;
}
}
<BOOLEAN>{
{ident} {
/* Non-quoted identifier-style string */
setString(&gStr, yytext);
yylval.literalString = gStr.value;
return TOK_IDENTIFIER;
}
"&&" return TOK_AND;
"||" return TOK_OR;
"==" return TOK_EQ;
"!=" return TOK_NE;
">=" return TOK_GE;
"<=" return TOK_LE;
[<>()!,] return yytext[0];
}
/* Double-quoted string handling */
<WORDS,BOOLEAN>\" {
/* Initial quote */
gStr.nextc = gStr.value;
BEGIN(QUOTED_STRING);
}
<QUOTED_STRING>{
\" {
/* Closing quote */
BEGIN(INITIAL);
addCharToString(&gStr, '\0');
yylval.literalString = gStr.value;
if (gArgumentType == AM_WORD_ARGS) {
return TOK_WORD;
} else {
return TOK_STRING;
}
}
<<EOF>> |
\n {
/* Unterminated string */
yyerror("unterminated string");
return TOK_ERROR;
}
\\\" {
/* Escaped quote */
addCharToString(&gStr, '"');
}
\\\\ {
/* Escaped backslash */
addCharToString(&gStr, '\\');
}
\\. {
/* No other escapes allowed. */
gErrorMessage = "illegal escape";
return TOK_ERROR;
}
[^\\\n\"]+ {
/* String contents */
char *p = yytext;
while (*p != '\0') {
/* TODO: add the whole string at once */
addCharToString(&gStr, *p++);
}
}
}
<WORDS>{
/*xxx look out for backslashes; escape backslashes and quotes */
/*xxx if a quote is right against a char, we should append */
{word} {
/* Whitespace-separated word */
setString(&gStr, yytext);
yylval.literalString = gStr.value;
return TOK_WORD;
}
}
<INITIAL,WORDS,BOOLEAN>{
\n {
/* Count lines */
gLineNumber++;
gArgumentType = AM_UNKNOWN_ARGS;
BEGIN(INITIAL);
return TOK_EOL;
}
/*xxx backslashes to extend lines? */
/* Skip whitespace and comments.
*/
[ \t\r]+ ;
#.* ;
. {
/* Fail on anything we didn't expect. */
gErrorMessage = "unexpected character";
return TOK_ERROR;
}
}
%%
void
yyerror(const char *msg)
{
if (!strcmp(msg, "syntax error") && gErrorMessage != NULL) {
msg = gErrorMessage;
gErrorMessage = NULL;
}
fprintf(stderr, "line %d: %s at '%s'\n", gLineNumber, msg, yytext);
}
#if AMEND_LEXER_BUFFER_INPUT
void
setLexerInputBuffer(const char *buf, size_t buflen)
{
gLineNumber = 1;
gInputBuffer = buf;
gInputBufferNext = gInputBuffer;
gInputBufferEnd = gInputBuffer + buflen;
}
#endif // AMEND_LEXER_BUFFER_INPUT
void
setLexerArgumentType(AmArgumentType type)
{
gArgumentType = type;
}
int
getLexerLineNumber(void)
{
return gLineNumber;
}

View File

@ -1,195 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ast.h"
#include "lexer.h"
#include "parser.h"
#include "register.h"
#include "execute.h"
void
lexTest()
{
int token;
do {
token = yylex();
if (token == 0) {
printf(" EOF");
fflush(stdout);
break;
} else {
printf(" %s", tokenToString(token));
fflush(stdout);
if (token == TOK_IDENTIFIER) {
if (strcmp(yylval.literalString, "assert") == 0) {
setLexerArgumentType(AM_BOOLEAN_ARGS);
} else {
setLexerArgumentType(AM_WORD_ARGS);
}
do {
token = yylex();
printf(" %s", tokenToString(token));
fflush(stdout);
} while (token != TOK_EOL && token != TOK_EOF && token != 0);
} else if (token != TOK_EOL) {
fprintf(stderr, "syntax error: expected identifier\n");
break;
}
}
} while (token != 0);
printf("\n");
}
void
usage()
{
printf("usage: amend [--debug-lex|--debug-ast] [<filename>]\n");
exit(1);
}
extern const AmCommandList *gCommands;
int
main(int argc, char *argv[])
{
FILE *inputFile = NULL;
bool debugLex = false;
bool debugAst = false;
const char *fileName = NULL;
int err;
#if 1
extern int test_symtab(void);
int ret = test_symtab();
if (ret != 0) {
fprintf(stderr, "test_symtab() failed: %d\n", ret);
exit(ret);
}
extern int test_cmd_fn(void);
ret = test_cmd_fn();
if (ret != 0) {
fprintf(stderr, "test_cmd_fn() failed: %d\n", ret);
exit(ret);
}
extern int test_permissions(void);
ret = test_permissions();
if (ret != 0) {
fprintf(stderr, "test_permissions() failed: %d\n", ret);
exit(ret);
}
#endif
argc--;
argv++;
while (argc > 0) {
if (strcmp("--debug-lex", argv[0]) == 0) {
debugLex = true;
} else if (strcmp("--debug-ast", argv[0]) == 0) {
debugAst = true;
} else if (argv[0][0] == '-') {
fprintf(stderr, "amend: Unknown option \"%s\"\n", argv[0]);
usage();
} else {
fileName = argv[0];
}
argc--;
argv++;
}
if (fileName != NULL) {
inputFile = fopen(fileName, "r");
if (inputFile == NULL) {
fprintf(stderr, "amend: Can't open input file '%s'\n", fileName);
usage();
}
}
commandInit();
//xxx clean up
err = registerUpdateCommands();
if (err < 0) {
fprintf(stderr, "amend: Error registering commands: %d\n", err);
exit(-err);
}
err = registerUpdateFunctions();
if (err < 0) {
fprintf(stderr, "amend: Error registering functions: %d\n", err);
exit(-err);
}
#if AMEND_LEXER_BUFFER_INPUT
if (inputFile == NULL) {
fprintf(stderr, "amend: No input file\n");
usage();
}
char *fileData;
int fileDataLen;
fseek(inputFile, 0, SEEK_END);
fileDataLen = ftell(inputFile);
rewind(inputFile);
if (fileDataLen < 0) {
fprintf(stderr, "amend: Can't get file length\n");
exit(2);
} else if (fileDataLen == 0) {
printf("amend: Empty input file\n");
exit(0);
}
fileData = (char *)malloc(fileDataLen + 1);
if (fileData == NULL) {
fprintf(stderr, "amend: Can't allocate %d bytes\n", fileDataLen + 1);
exit(2);
}
size_t nread = fread(fileData, 1, fileDataLen, inputFile);
if (nread != (size_t)fileDataLen) {
fprintf(stderr, "amend: Didn't read %d bytes, only %zd\n", fileDataLen,
nread);
exit(2);
}
fileData[fileDataLen] = '\0';
setLexerInputBuffer(fileData, fileDataLen);
#else
if (inputFile == NULL) {
inputFile = stdin;
}
yyset_in(inputFile);
#endif
if (debugLex) {
lexTest();
} else {
int ret = yyparse();
if (ret != 0) {
fprintf(stderr, "amend: Parse failed (%d)\n", ret);
exit(2);
} else {
if (debugAst) {
dumpCommandList(gCommands);
}
printf("amend: Parse successful.\n");
ret = execCommandList((ExecContext *)1, gCommands);
if (ret != 0) {
fprintf(stderr, "amend: Execution failed (%d)\n", ret);
exit(3);
}
printf("amend: Execution successful.\n");
}
}
return 0;
}

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AMEND_PARSER_H_
#define AMEND_PARSER_H_
#include "parser_y.h"
int yyparse(void);
#endif // AMEND_PARSER_H_

View File

@ -1,430 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
%{
#undef NDEBUG
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include "ast.h"
#include "lexer.h"
#include "commands.h"
void yyerror(const char *msg);
int yylex(void);
#define STRING_COMPARISON(out, a1, sop, a2) \
do { \
out = (AmBooleanValue *)malloc(sizeof(AmBooleanValue)); \
if (out == NULL) { \
YYABORT; \
} \
out->type = AM_BVAL_STRING_COMPARISON; \
out->u.stringComparison.op = sop; \
out->u.stringComparison.arg1 = a1; \
out->u.stringComparison.arg2 = a2; \
} while (false)
#define BOOLEAN_EXPRESSION(out, a1, bop, a2) \
do { \
out = (AmBooleanValue *)malloc(sizeof(AmBooleanValue)); \
if (out == NULL) { \
YYABORT; \
} \
out->type = AM_BVAL_EXPRESSION; \
out->u.expression.op = bop; \
out->u.expression.arg1 = a1; \
out->u.expression.arg2 = a2; \
} while (false)
AmCommandList *gCommands = NULL;
%}
%start lines
%union {
char *literalString;
AmFunctionArgumentBuilder *functionArgumentBuilder;
AmFunctionArguments *functionArguments;
AmFunctionCall *functionCall;
AmStringValue *stringValue;
AmBooleanValue *booleanValue;
AmWordListBuilder *wordListBuilder;
AmCommandArguments *commandArguments;
AmCommand *command;
AmCommandList *commandList;
}
%token TOK_AND TOK_OR TOK_EQ TOK_NE TOK_GE TOK_LE TOK_EOF TOK_EOL TOK_ERROR
%token <literalString> TOK_STRING TOK_IDENTIFIER TOK_WORD
%type <commandList> lines
%type <command> command line
%type <functionArgumentBuilder> function_arguments
%type <functionArguments> function_arguments_or_empty
%type <functionCall> function_call
%type <literalString> function_name
%type <stringValue> string_value
%type <booleanValue> boolean_expression
%type <wordListBuilder> word_list
%type <commandArguments> arguments
/* Operator precedence, weakest to strongest.
* Same as C/Java precedence.
*/
%left TOK_OR
%left TOK_AND
%left TOK_EQ TOK_NE
%left '<' '>' TOK_LE TOK_GE
%right '!'
%%
lines : /* empty */
{
$$ = (AmCommandList *)malloc(sizeof(AmCommandList));
if ($$ == NULL) {
YYABORT;
}
gCommands = $$;
$$->arraySize = 64;
$$->commandCount = 0;
$$->commands = (AmCommand **)malloc(
sizeof(AmCommand *) * $$->arraySize);
if ($$->commands == NULL) {
YYABORT;
}
}
| lines line
{
if ($2 != NULL) {
if ($1->commandCount >= $1->arraySize) {
AmCommand **newArray;
newArray = (AmCommand **)realloc($$->commands,
sizeof(AmCommand *) * $$->arraySize * 2);
if (newArray == NULL) {
YYABORT;
}
$$->commands = newArray;
$$->arraySize *= 2;
}
$1->commands[$1->commandCount++] = $2;
}
}
;
line : line_ending
{
$$ = NULL; /* ignore blank lines */
}
| command arguments line_ending
{
$$ = $1;
$$->args = $2;
setLexerArgumentType(AM_UNKNOWN_ARGS);
}
;
command : TOK_IDENTIFIER
{
Command *cmd = findCommand($1);
if (cmd == NULL) {
fprintf(stderr, "Unknown command \"%s\"\n", $1);
YYABORT;
}
$$ = (AmCommand *)malloc(sizeof(AmCommand));
if ($$ == NULL) {
YYABORT;
}
$$->line = getLexerLineNumber();
$$->name = strdup($1);
if ($$->name == NULL) {
YYABORT;
}
$$->args = NULL;
CommandArgumentType argType = getCommandArgumentType(cmd);
if (argType == CMD_ARGS_BOOLEAN) {
setLexerArgumentType(AM_BOOLEAN_ARGS);
} else {
setLexerArgumentType(AM_WORD_ARGS);
}
$$->cmd = cmd;
}
;
line_ending :
TOK_EOL
| TOK_EOF
;
arguments : boolean_expression
{
$$ = (AmCommandArguments *)malloc(
sizeof(AmCommandArguments));
if ($$ == NULL) {
YYABORT;
}
$$->booleanArgs = true;
$$->u.b = $1;
}
| word_list
{
/* Convert the builder list into an array.
* Do it in reverse order; the words were pushed
* onto the list in LIFO order.
*/
AmWordList *w = (AmWordList *)malloc(sizeof(AmWordList));
if (w == NULL) {
YYABORT;
}
if ($1 != NULL) {
AmWordListBuilder *words = $1;
w->argc = words->wordCount;
w->argv = (const char **)malloc(w->argc *
sizeof(char *));
if (w->argv == NULL) {
YYABORT;
}
int i;
for (i = w->argc; words != NULL && i > 0; --i) {
AmWordListBuilder *f = words;
w->argv[i-1] = words->word;
words = words->next;
free(f);
}
assert(i == 0);
assert(words == NULL);
} else {
w->argc = 0;
w->argv = NULL;
}
$$ = (AmCommandArguments *)malloc(
sizeof(AmCommandArguments));
if ($$ == NULL) {
YYABORT;
}
$$->booleanArgs = false;
$$->u.w = w;
}
;
word_list : /* empty */
{ $$ = NULL; }
| word_list TOK_WORD
{
if ($1 == NULL) {
$$ = (AmWordListBuilder *)malloc(
sizeof(AmWordListBuilder));
if ($$ == NULL) {
YYABORT;
}
$$->next = NULL;
$$->wordCount = 1;
} else {
$$ = (AmWordListBuilder *)malloc(
sizeof(AmWordListBuilder));
if ($$ == NULL) {
YYABORT;
}
$$->next = $1;
$$->wordCount = $$->next->wordCount + 1;
}
$$->word = strdup($2);
if ($$->word == NULL) {
YYABORT;
}
}
;
boolean_expression :
'!' boolean_expression
{
$$ = (AmBooleanValue *)malloc(sizeof(AmBooleanValue));
if ($$ == NULL) {
YYABORT;
}
$$->type = AM_BVAL_EXPRESSION;
$$->u.expression.op = AM_BOP_NOT;
$$->u.expression.arg1 = $2;
$$->u.expression.arg2 = NULL;
}
/* TODO: if both expressions are literals, evaluate now */
| boolean_expression TOK_AND boolean_expression
{ BOOLEAN_EXPRESSION($$, $1, AM_BOP_AND, $3); }
| boolean_expression TOK_OR boolean_expression
{ BOOLEAN_EXPRESSION($$, $1, AM_BOP_OR, $3); }
| boolean_expression TOK_EQ boolean_expression
{ BOOLEAN_EXPRESSION($$, $1, AM_BOP_EQ, $3); }
| boolean_expression TOK_NE boolean_expression
{ BOOLEAN_EXPRESSION($$, $1, AM_BOP_NE, $3); }
| '(' boolean_expression ')'
{ $$ = $2; }
/* TODO: if both strings are literals, evaluate now */
| string_value '<' string_value
{ STRING_COMPARISON($$, $1, AM_SOP_LT, $3); }
| string_value '>' string_value
{ STRING_COMPARISON($$, $1, AM_SOP_GT, $3); }
| string_value TOK_EQ string_value
{ STRING_COMPARISON($$, $1, AM_SOP_EQ, $3); }
| string_value TOK_NE string_value
{ STRING_COMPARISON($$, $1, AM_SOP_NE, $3); }
| string_value TOK_LE string_value
{ STRING_COMPARISON($$, $1, AM_SOP_LE, $3); }
| string_value TOK_GE string_value
{ STRING_COMPARISON($$, $1, AM_SOP_GE, $3); }
;
string_value :
TOK_IDENTIFIER
{
$$ = (AmStringValue *)malloc(sizeof(AmStringValue));
if ($$ == NULL) {
YYABORT;
}
$$->type = AM_SVAL_LITERAL;
$$->u.literal = strdup($1);
if ($$->u.literal == NULL) {
YYABORT;
}
}
| TOK_STRING
{
$$ = (AmStringValue *)malloc(sizeof(AmStringValue));
if ($$ == NULL) {
YYABORT;
}
$$->type = AM_SVAL_LITERAL;
$$->u.literal = strdup($1);
if ($$->u.literal == NULL) {
YYABORT;
}
}
| function_call
{
$$ = (AmStringValue *)malloc(sizeof(AmStringValue));
if ($$ == NULL) {
YYABORT;
}
$$->type = AM_SVAL_FUNCTION;
$$->u.function = $1;
}
;
/* We can't just say
* TOK_IDENTIFIER '(' function_arguments_or_empty ')'
* because parsing function_arguments_or_empty will clobber
* the underlying string that yylval.literalString points to.
*/
function_call :
function_name '(' function_arguments_or_empty ')'
{
Function *fn = findFunction($1);
if (fn == NULL) {
fprintf(stderr, "Unknown function \"%s\"\n", $1);
YYABORT;
}
$$ = (AmFunctionCall *)malloc(sizeof(AmFunctionCall));
if ($$ == NULL) {
YYABORT;
}
$$->name = $1;
if ($$->name == NULL) {
YYABORT;
}
$$->fn = fn;
$$->args = $3;
}
;
function_name :
TOK_IDENTIFIER
{
$$ = strdup($1);
}
;
function_arguments_or_empty :
/* empty */
{
$$ = (AmFunctionArguments *)malloc(
sizeof(AmFunctionArguments));
if ($$ == NULL) {
YYABORT;
}
$$->argc = 0;
$$->argv = NULL;
}
| function_arguments
{
AmFunctionArgumentBuilder *args = $1;
assert(args != NULL);
/* Convert the builder list into an array.
* Do it in reverse order; the args were pushed
* onto the list in LIFO order.
*/
$$ = (AmFunctionArguments *)malloc(
sizeof(AmFunctionArguments));
if ($$ == NULL) {
YYABORT;
}
$$->argc = args->argCount;
$$->argv = (AmStringValue *)malloc(
$$->argc * sizeof(AmStringValue));
if ($$->argv == NULL) {
YYABORT;
}
int i;
for (i = $$->argc; args != NULL && i > 0; --i) {
AmFunctionArgumentBuilder *f = args;
$$->argv[i-1] = *args->arg;
args = args->next;
free(f->arg);
free(f);
}
assert(i == 0);
assert(args == NULL);
}
;
function_arguments :
string_value
{
$$ = (AmFunctionArgumentBuilder *)malloc(
sizeof(AmFunctionArgumentBuilder));
if ($$ == NULL) {
YYABORT;
}
$$->next = NULL;
$$->argCount = 1;
$$->arg = $1;
}
| function_arguments ',' string_value
{
$$ = (AmFunctionArgumentBuilder *)malloc(
sizeof(AmFunctionArgumentBuilder));
if ($$ == NULL) {
YYABORT;
}
$$->next = $1;
$$->argCount = $$->next->argCount + 1;
$$->arg = $3;
}
;
/* xxx this whole tool needs to be hardened */

View File

@ -1,270 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include "permissions.h"
int
initPermissionRequestList(PermissionRequestList *list)
{
if (list != NULL) {
list->requests = NULL;
list->numRequests = 0;
list->requestsAllocated = 0;
return 0;
}
return -1;
}
int
addPermissionRequestToList(PermissionRequestList *list,
const char *path, bool recursive, unsigned int permissions)
{
if (list == NULL || list->numRequests < 0 ||
list->requestsAllocated < list->numRequests || path == NULL)
{
return -1;
}
if (list->numRequests == list->requestsAllocated) {
int newSize;
PermissionRequest *newRequests;
newSize = list->requestsAllocated * 2;
if (newSize < 16) {
newSize = 16;
}
newRequests = (PermissionRequest *)realloc(list->requests,
newSize * sizeof(PermissionRequest));
if (newRequests == NULL) {
return -2;
}
list->requests = newRequests;
list->requestsAllocated = newSize;
}
PermissionRequest *req;
req = &list->requests[list->numRequests++];
req->path = strdup(path);
if (req->path == NULL) {
list->numRequests--;
return -3;
}
req->recursive = recursive;
req->requested = permissions;
req->allowed = 0;
return 0;
}
void
freePermissionRequestListElements(PermissionRequestList *list)
{
if (list != NULL && list->numRequests >= 0 &&
list->requestsAllocated >= list->numRequests)
{
int i;
for (i = 0; i < list->numRequests; i++) {
free((void *)list->requests[i].path);
}
free(list->requests);
initPermissionRequestList(list);
}
}
/*
* Global permission table
*/
static struct {
Permission *permissions;
int numPermissionEntries;
int allocatedPermissionEntries;
bool permissionStateInitialized;
} gPermissionState = {
#if 1
NULL, 0, 0, false
#else
.permissions = NULL,
.numPermissionEntries = 0,
.allocatedPermissionEntries = 0,
.permissionStateInitialized = false
#endif
};
int
permissionInit()
{
if (gPermissionState.permissionStateInitialized) {
return -1;
}
gPermissionState.permissions = NULL;
gPermissionState.numPermissionEntries = 0;
gPermissionState.allocatedPermissionEntries = 0;
gPermissionState.permissionStateInitialized = true;
//xxx maybe add an "namespace root gets no permissions" fallback by default
return 0;
}
void
permissionCleanup()
{
if (gPermissionState.permissionStateInitialized) {
gPermissionState.permissionStateInitialized = false;
if (gPermissionState.permissions != NULL) {
int i;
for (i = 0; i < gPermissionState.numPermissionEntries; i++) {
free((void *)gPermissionState.permissions[i].path);
}
free(gPermissionState.permissions);
}
}
}
int
getPermissionCount()
{
if (gPermissionState.permissionStateInitialized) {
return gPermissionState.numPermissionEntries;
}
return -1;
}
const Permission *
getPermissionAt(int index)
{
if (!gPermissionState.permissionStateInitialized) {
return NULL;
}
if (index < 0 || index >= gPermissionState.numPermissionEntries) {
return NULL;
}
return &gPermissionState.permissions[index];
}
int
getAllowedPermissions(const char *path, bool recursive,
unsigned int *outAllowed)
{
if (!gPermissionState.permissionStateInitialized) {
return -2;
}
if (outAllowed == NULL) {
return -1;
}
*outAllowed = 0;
if (path == NULL) {
return -1;
}
//TODO: implement this for real.
recursive = false;
*outAllowed = PERMSET_ALL;
return 0;
}
int
countPermissionConflicts(PermissionRequestList *requests, bool updateAllowed)
{
if (!gPermissionState.permissionStateInitialized) {
return -2;
}
if (requests == NULL || requests->requests == NULL ||
requests->numRequests < 0 ||
requests->requestsAllocated < requests->numRequests)
{
return -1;
}
int conflicts = 0;
int i;
for (i = 0; i < requests->numRequests; i++) {
PermissionRequest *req;
unsigned int allowed;
int ret;
req = &requests->requests[i];
ret = getAllowedPermissions(req->path, req->recursive, &allowed);
if (ret < 0) {
return ret;
}
if ((req->requested & ~allowed) != 0) {
conflicts++;
}
if (updateAllowed) {
req->allowed = allowed;
}
}
return conflicts;
}
int
registerPermissionSet(int count, Permission *set)
{
if (!gPermissionState.permissionStateInitialized) {
return -2;
}
if (count < 0 || (count > 0 && set == NULL)) {
return -1;
}
if (count == 0) {
return 0;
}
if (gPermissionState.numPermissionEntries + count >=
gPermissionState.allocatedPermissionEntries)
{
Permission *newList;
int newSize;
newSize = (gPermissionState.allocatedPermissionEntries + count) * 2;
if (newSize < 16) {
newSize = 16;
}
newList = (Permission *)realloc(gPermissionState.permissions,
newSize * sizeof(Permission));
if (newList == NULL) {
return -3;
}
gPermissionState.permissions = newList;
gPermissionState.allocatedPermissionEntries = newSize;
}
Permission *p = &gPermissionState.permissions[
gPermissionState.numPermissionEntries];
int i;
for (i = 0; i < count; i++) {
*p = set[i];
//TODO: cache the strlen of the path
//TODO: normalize; strip off trailing /
p->path = strdup(p->path);
if (p->path == NULL) {
/* If we can't add all of the entries, we don't
* add any of them.
*/
Permission *pp = &gPermissionState.permissions[
gPermissionState.numPermissionEntries];
while (pp != p) {
free((void *)pp->path);
pp++;
}
return -4;
}
p++;
}
gPermissionState.numPermissionEntries += count;
return 0;
}

View File

@ -1,111 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AMEND_PERMISSIONS_H_
#define AMEND_PERMISSIONS_H_
#include <stdbool.h>
#define PERM_NONE (0)
#define PERM_STAT (1<<0)
#define PERM_READ (1<<1)
#define PERM_WRITE (1<<2) // including create, delete, mkdir, rmdir
#define PERM_CHMOD (1<<3)
#define PERM_CHOWN (1<<4)
#define PERM_CHGRP (1<<5)
#define PERM_SETUID (1<<6)
#define PERM_SETGID (1<<7)
#define PERMSET_READ (PERM_STAT | PERM_READ)
#define PERMSET_WRITE (PERMSET_READ | PERM_WRITE)
#define PERMSET_ALL \
(PERM_STAT | PERM_READ | PERM_WRITE | PERM_CHMOD | \
PERM_CHOWN | PERM_CHGRP | PERM_SETUID | PERM_SETGID)
typedef struct {
unsigned int requested;
unsigned int allowed;
const char *path;
bool recursive;
} PermissionRequest;
typedef struct {
PermissionRequest *requests;
int numRequests;
int requestsAllocated;
} PermissionRequestList;
/* Properly clear out a PermissionRequestList.
*
* @return 0 if list is non-NULL, negative otherwise.
*/
int initPermissionRequestList(PermissionRequestList *list);
/* Add a permission request to the list, allocating more space
* if necessary.
*
* @return 0 on success or a negative value on failure.
*/
int addPermissionRequestToList(PermissionRequestList *list,
const char *path, bool recursive, unsigned int permissions);
/* Free anything allocated by addPermissionRequestToList(). The caller
* is responsible for freeing the actual PermissionRequestList.
*/
void freePermissionRequestListElements(PermissionRequestList *list);
/*
* Global permission table
*/
typedef struct {
const char *path;
unsigned int allowed;
} Permission;
int permissionInit(void);
void permissionCleanup(void);
/* Returns the allowed permissions for the path in "outAllowed".
* Returns 0 if successful, negative if a parameter or global state
* is bad.
*/
int getAllowedPermissions(const char *path, bool recursive,
unsigned int *outAllowed);
/* More-recently-registered permissions override older permissions.
*/
int registerPermissionSet(int count, Permission *set);
/* Check to make sure that each request is allowed.
*
* @param requests The list of permission requests
* @param updateAllowed If true, update the "allowed" field in each
* element of the list
* @return the number of requests that were denied, or negative if
* an error occurred.
*/
int countPermissionConflicts(PermissionRequestList *requests,
bool updateAllowed);
/* Inspection/testing/debugging functions
*/
int getPermissionCount(void);
const Permission *getPermissionAt(int index);
#endif // AMEND_PERMISSIONS_H_

View File

@ -1,410 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#undef NDEBUG
#include <assert.h>
#include "commands.h"
#include "register.h"
#define UNUSED(p) ((void)(p))
#define CHECK_BOOL() \
do { \
assert(argv == NULL); \
if (argv != NULL) return -1; \
assert(argc == true || argc == false); \
if (argc != true && argc != false) return -1; \
} while (false)
#define CHECK_WORDS() \
do { \
assert(argc >= 0); \
if (argc < 0) return -1; \
assert(argc == 0 || argv != NULL); \
if (argc != 0 && argv == NULL) return -1; \
if (permissions != NULL) { \
int CW_I_; \
for (CW_I_ = 0; CW_I_ < argc; CW_I_++) { \
assert(argv[CW_I_] != NULL); \
if (argv[CW_I_] == NULL) return -1; \
} \
} \
} while (false)
#define CHECK_FN() \
do { \
CHECK_WORDS(); \
if (permissions != NULL) { \
assert(result == NULL); \
if (result != NULL) return -1; \
} else { \
assert(result != NULL); \
if (result == NULL) return -1; \
} \
} while (false)
#define NO_PERMS(perms) \
do { \
PermissionRequestList *NP_PRL_ = (perms); \
if (NP_PRL_ != NULL) { \
int NP_RET_ = addPermissionRequestToList(NP_PRL_, \
"", false, PERM_NONE); \
if (NP_RET_ < 0) { \
/* Returns from the calling function. \
*/ \
return NP_RET_; \
} \
} \
} while (false)
/*
* Command definitions
*/
/* assert <boolexpr>
*/
static int
cmd_assert(const char *name, void *cookie, int argc, const char *argv[],
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_BOOL();
NO_PERMS(permissions);
/* If our argument is false, return non-zero (failure)
* If our argument is true, return zero (success)
*/
if (argc) {
return 0;
} else {
return 1;
}
}
/* format <root>
*/
static int
cmd_format(const char *name, void *cookie, int argc, const char *argv[],
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_WORDS();
//xxx
return -1;
}
/* copy_dir <srcdir> <dstdir>
*/
static int
cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[],
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_WORDS();
//xxx
return -1;
}
/* delete <srcdir> <dstdir>
*/
static int
cmd_delete(const char *name, void *cookie, int argc, const char *argv[],
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_WORDS();
//xxx
return -1;
}
/* mark <resource> dirty|clean
*/
static int
cmd_mark(const char *name, void *cookie, int argc, const char *argv[],
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_WORDS();
//xxx when marking, save the top-level hash at the mark point
// so we can retry on failure. Otherwise the hashes won't match,
// or someone could intentionally dirty the FS to force a downgrade
//xxx
return -1;
}
/* done
*/
static int
cmd_done(const char *name, void *cookie, int argc, const char *argv[],
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_WORDS();
//xxx
return -1;
}
int
registerUpdateCommands()
{
int ret;
ret = registerCommand("assert", CMD_ARGS_BOOLEAN, cmd_assert, NULL);
if (ret < 0) return ret;
ret = registerCommand("copy_dir", CMD_ARGS_WORDS, cmd_copy_dir, NULL);
if (ret < 0) return ret;
ret = registerCommand("delete", CMD_ARGS_WORDS, cmd_delete, NULL);
if (ret < 0) return ret;
ret = registerCommand("format", CMD_ARGS_WORDS, cmd_format, NULL);
if (ret < 0) return ret;
ret = registerCommand("mark", CMD_ARGS_WORDS, cmd_mark, NULL);
if (ret < 0) return ret;
ret = registerCommand("done", CMD_ARGS_WORDS, cmd_done, NULL);
if (ret < 0) return ret;
//xxx some way to fix permissions
//xxx could have "installperms" commands that build the fs_config list
//xxx along with a "commitperms", and any copy_dir etc. needs to see
// a commitperms before it will work
return 0;
}
/*
* Function definitions
*/
/* update_forced()
*
* Returns "true" if some system setting has determined that
* the update should happen no matter what.
*/
static int
fn_update_forced(const char *name, void *cookie, int argc, const char *argv[],
char **result, size_t *resultLen,
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_FN();
NO_PERMS(permissions);
if (argc != 0) {
fprintf(stderr, "%s: wrong number of arguments (%d)\n",
name, argc);
return 1;
}
//xxx check some global or property
bool force = true;
if (force) {
*result = strdup("true");
} else {
*result = strdup("");
}
if (resultLen != NULL) {
*resultLen = strlen(*result);
}
return 0;
}
/* get_mark(<resource>)
*
* Returns the current mark associated with the provided resource.
*/
static int
fn_get_mark(const char *name, void *cookie, int argc, const char *argv[],
char **result, size_t *resultLen,
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_FN();
NO_PERMS(permissions);
if (argc != 1) {
fprintf(stderr, "%s: wrong number of arguments (%d)\n",
name, argc);
return 1;
}
//xxx look up the value
*result = strdup("");
if (resultLen != NULL) {
*resultLen = strlen(*result);
}
return 0;
}
/* hash_dir(<path-to-directory>)
*/
static int
fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
char **result, size_t *resultLen,
PermissionRequestList *permissions)
{
int ret = -1;
UNUSED(name);
UNUSED(cookie);
CHECK_FN();
const char *dir;
if (argc != 1) {
fprintf(stderr, "%s: wrong number of arguments (%d)\n",
name, argc);
return 1;
} else {
dir = argv[0];
}
if (permissions != NULL) {
if (dir == NULL) {
/* The argument is the result of another function.
* Assume the worst case, where the function returns
* the root.
*/
dir = "/";
}
ret = addPermissionRequestToList(permissions, dir, true, PERM_READ);
} else {
//xxx build and return the string
*result = strdup("hashvalue");
if (resultLen != NULL) {
*resultLen = strlen(*result);
}
ret = 0;
}
return ret;
}
/* matches(<str>, <str1> [, <strN>...])
* If <str> matches (strcmp) any of <str1>...<strN>, returns <str>,
* otherwise returns "".
*
* E.g., assert matches(hash_dir("/path"), "hash1", "hash2")
*/
static int
fn_matches(const char *name, void *cookie, int argc, const char *argv[],
char **result, size_t *resultLen,
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_FN();
NO_PERMS(permissions);
if (argc < 2) {
fprintf(stderr, "%s: not enough arguments (%d < 2)\n",
name, argc);
return 1;
}
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[0], argv[i]) == 0) {
*result = strdup(argv[0]);
if (resultLen != NULL) {
*resultLen = strlen(*result);
}
return 0;
}
}
*result = strdup("");
if (resultLen != NULL) {
*resultLen = 1;
}
return 0;
}
/* concat(<str>, <str1> [, <strN>...])
* Returns the concatenation of all strings.
*/
static int
fn_concat(const char *name, void *cookie, int argc, const char *argv[],
char **result, size_t *resultLen,
PermissionRequestList *permissions)
{
UNUSED(name);
UNUSED(cookie);
CHECK_FN();
NO_PERMS(permissions);
size_t totalLen = 0;
int i;
for (i = 0; i < argc; i++) {
totalLen += strlen(argv[i]);
}
char *s = (char *)malloc(totalLen + 1);
if (s == NULL) {
return -1;
}
s[totalLen] = '\0';
for (i = 0; i < argc; i++) {
//TODO: keep track of the end to avoid walking the string each time
strcat(s, argv[i]);
}
*result = s;
if (resultLen != NULL) {
*resultLen = strlen(s);
}
return 0;
}
int
registerUpdateFunctions()
{
int ret;
ret = registerFunction("update_forced", fn_update_forced, NULL);
if (ret < 0) return ret;
ret = registerFunction("get_mark", fn_get_mark, NULL);
if (ret < 0) return ret;
ret = registerFunction("hash_dir", fn_hash_dir, NULL);
if (ret < 0) return ret;
ret = registerFunction("matches", fn_matches, NULL);
if (ret < 0) return ret;
ret = registerFunction("concat", fn_concat, NULL);
if (ret < 0) return ret;
return 0;
}

View File

@ -1,23 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AMEND_REGISTER_H_
#define AMEND_REGISTER_H_
int registerUpdateCommands(void);
int registerUpdateFunctions(void);
#endif // AMEND_REGISTER_H_

View File

@ -1,132 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include "symtab.h"
#define DEFAULT_TABLE_SIZE 16
typedef struct {
char *symbol;
const void *cookie;
unsigned int flags;
} SymbolTableEntry;
struct SymbolTable {
SymbolTableEntry *table;
int numEntries;
int maxSize;
};
SymbolTable *
createSymbolTable()
{
SymbolTable *tab;
tab = (SymbolTable *)malloc(sizeof(SymbolTable));
if (tab != NULL) {
tab->numEntries = 0;
tab->maxSize = DEFAULT_TABLE_SIZE;
tab->table = (SymbolTableEntry *)malloc(
tab->maxSize * sizeof(SymbolTableEntry));
if (tab->table == NULL) {
free(tab);
tab = NULL;
}
}
return tab;
}
void
deleteSymbolTable(SymbolTable *tab)
{
if (tab != NULL) {
while (tab->numEntries > 0) {
free(tab->table[--tab->numEntries].symbol);
}
free(tab->table);
}
}
void *
findInSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags)
{
int i;
if (tab == NULL || symbol == NULL) {
return NULL;
}
// TODO: Sort the table and binary search
for (i = 0; i < tab->numEntries; i++) {
if (strcmp(tab->table[i].symbol, symbol) == 0 &&
tab->table[i].flags == flags)
{
return (void *)tab->table[i].cookie;
}
}
return NULL;
}
int
addToSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags,
const void *cookie)
{
if (tab == NULL || symbol == NULL || cookie == NULL) {
return -1;
}
/* Make sure that this symbol isn't already in the table.
*/
if (findInSymbolTable(tab, symbol, flags) != NULL) {
return -2;
}
/* Make sure there's enough space for the new entry.
*/
if (tab->numEntries == tab->maxSize) {
SymbolTableEntry *newTable;
int newSize;
newSize = tab->numEntries * 2;
if (newSize < DEFAULT_TABLE_SIZE) {
newSize = DEFAULT_TABLE_SIZE;
}
newTable = (SymbolTableEntry *)realloc(tab->table,
newSize * sizeof(SymbolTableEntry));
if (newTable == NULL) {
return -1;
}
tab->maxSize = newSize;
tab->table = newTable;
}
/* Insert the new entry.
*/
symbol = strdup(symbol);
if (symbol == NULL) {
return -1;
}
// TODO: Sort the table
tab->table[tab->numEntries].symbol = (char *)symbol;
tab->table[tab->numEntries].cookie = cookie;
tab->table[tab->numEntries].flags = flags;
tab->numEntries++;
return 0;
}

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AMEND_SYMTAB_H_
#define AMEND_SYMTAB_H_
typedef struct SymbolTable SymbolTable;
SymbolTable *createSymbolTable(void);
void deleteSymbolTable(SymbolTable *tab);
/* symbol and cookie must be non-NULL.
*/
int addToSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags,
const void *cookie);
void *findInSymbolTable(SymbolTable *tab, const char *symbol,
unsigned int flags);
#endif // AMEND_SYMTAB_H_

View File

@ -1,538 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#undef NDEBUG
#include <assert.h>
#include "commands.h"
static struct {
bool called;
const char *name;
void *cookie;
int argc;
const char **argv;
PermissionRequestList *permissions;
int returnValue;
char *functionResult;
} gTestCommandState;
static int
testCommand(const char *name, void *cookie, int argc, const char *argv[],
PermissionRequestList *permissions)
{
gTestCommandState.called = true;
gTestCommandState.name = name;
gTestCommandState.cookie = cookie;
gTestCommandState.argc = argc;
gTestCommandState.argv = argv;
gTestCommandState.permissions = permissions;
return gTestCommandState.returnValue;
}
static int
testFunction(const char *name, void *cookie, int argc, const char *argv[],
char **result, size_t *resultLen, PermissionRequestList *permissions)
{
gTestCommandState.called = true;
gTestCommandState.name = name;
gTestCommandState.cookie = cookie;
gTestCommandState.argc = argc;
gTestCommandState.argv = argv;
gTestCommandState.permissions = permissions;
if (result != NULL) {
*result = gTestCommandState.functionResult;
if (resultLen != NULL) {
*resultLen = strlen(*result);
}
}
return gTestCommandState.returnValue;
}
static int
test_commands()
{
Command *cmd;
int ret;
CommandArgumentType argType;
ret = commandInit();
assert(ret == 0);
/* Make sure we can't initialize twice.
*/
ret = commandInit();
assert(ret < 0);
/* Try calling with some bad values.
*/
ret = registerCommand(NULL, CMD_ARGS_UNKNOWN, NULL, NULL);
assert(ret < 0);
ret = registerCommand("hello", CMD_ARGS_UNKNOWN, NULL, NULL);
assert(ret < 0);
ret = registerCommand("hello", CMD_ARGS_WORDS, NULL, NULL);
assert(ret < 0);
cmd = findCommand(NULL);
assert(cmd == NULL);
argType = getCommandArgumentType(NULL);
assert((int)argType < 0);
ret = callCommand(NULL, -1, NULL);
assert(ret < 0);
ret = callBooleanCommand(NULL, false);
assert(ret < 0);
/* Register some commands.
*/
ret = registerCommand("one", CMD_ARGS_WORDS, testCommand,
&gTestCommandState);
assert(ret == 0);
ret = registerCommand("two", CMD_ARGS_WORDS, testCommand,
&gTestCommandState);
assert(ret == 0);
ret = registerCommand("bool", CMD_ARGS_BOOLEAN, testCommand,
&gTestCommandState);
assert(ret == 0);
/* Make sure that all of those commands exist and that their
* argument types are correct.
*/
cmd = findCommand("one");
assert(cmd != NULL);
argType = getCommandArgumentType(cmd);
assert(argType == CMD_ARGS_WORDS);
cmd = findCommand("two");
assert(cmd != NULL);
argType = getCommandArgumentType(cmd);
assert(argType == CMD_ARGS_WORDS);
cmd = findCommand("bool");
assert(cmd != NULL);
argType = getCommandArgumentType(cmd);
assert(argType == CMD_ARGS_BOOLEAN);
/* Make sure that no similar commands exist.
*/
cmd = findCommand("on");
assert(cmd == NULL);
cmd = findCommand("onee");
assert(cmd == NULL);
/* Make sure that a double insertion fails.
*/
ret = registerCommand("one", CMD_ARGS_WORDS, testCommand,
&gTestCommandState);
assert(ret < 0);
/* Make sure that bad args fail.
*/
cmd = findCommand("one");
assert(cmd != NULL);
ret = callCommand(cmd, -1, NULL); // argc must be non-negative
assert(ret < 0);
ret = callCommand(cmd, 1, NULL); // argv can't be NULL if argc > 0
assert(ret < 0);
/* Make sure that you can't make a boolean call on a regular command.
*/
cmd = findCommand("one");
assert(cmd != NULL);
ret = callBooleanCommand(cmd, false);
assert(ret < 0);
/* Make sure that you can't make a regular call on a boolean command.
*/
cmd = findCommand("bool");
assert(cmd != NULL);
ret = callCommand(cmd, 0, NULL);
assert(ret < 0);
/* Set up some arguments.
*/
int argc = 4;
const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
/* Make a call and make sure that it occurred.
*/
cmd = findCommand("one");
assert(cmd != NULL);
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
gTestCommandState.called = false;
gTestCommandState.returnValue = 25;
gTestCommandState.permissions = (PermissionRequestList *)1;
ret = callCommand(cmd, argc, argv);
//xxx also try calling with a null argv element (should fail)
assert(ret == 25);
assert(gTestCommandState.called);
assert(strcmp(gTestCommandState.name, "one") == 0);
assert(gTestCommandState.cookie == &gTestCommandState);
assert(gTestCommandState.argc == argc);
assert(gTestCommandState.argv == argv);
assert(gTestCommandState.permissions == NULL);
/* Make a boolean call and make sure that it occurred.
*/
cmd = findCommand("bool");
assert(cmd != NULL);
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
gTestCommandState.called = false;
gTestCommandState.returnValue = 12;
gTestCommandState.permissions = (PermissionRequestList *)1;
ret = callBooleanCommand(cmd, false);
assert(ret == 12);
assert(gTestCommandState.called);
assert(strcmp(gTestCommandState.name, "bool") == 0);
assert(gTestCommandState.cookie == &gTestCommandState);
assert(gTestCommandState.argc == 0);
assert(gTestCommandState.argv == NULL);
assert(gTestCommandState.permissions == NULL);
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
gTestCommandState.called = false;
gTestCommandState.returnValue = 13;
gTestCommandState.permissions = (PermissionRequestList *)1;
ret = callBooleanCommand(cmd, true);
assert(ret == 13);
assert(gTestCommandState.called);
assert(strcmp(gTestCommandState.name, "bool") == 0);
assert(gTestCommandState.cookie == &gTestCommandState);
assert(gTestCommandState.argc == 1);
assert(gTestCommandState.argv == NULL);
assert(gTestCommandState.permissions == NULL);
/* Try looking up permissions.
*/
PermissionRequestList permissions;
cmd = findCommand("one");
assert(cmd != NULL);
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
gTestCommandState.called = false;
gTestCommandState.returnValue = 27;
gTestCommandState.permissions = (PermissionRequestList *)1;
argv[1] = NULL; // null out an arg, which should be ok
ret = getCommandPermissions(cmd, argc, argv, &permissions);
assert(ret == 27);
assert(gTestCommandState.called);
assert(strcmp(gTestCommandState.name, "one") == 0);
assert(gTestCommandState.cookie == &gTestCommandState);
assert(gTestCommandState.argc == argc);
assert(gTestCommandState.argv == argv);
assert(gTestCommandState.permissions == &permissions);
/* Boolean command permissions
*/
cmd = findCommand("bool");
assert(cmd != NULL);
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
gTestCommandState.called = false;
gTestCommandState.returnValue = 55;
gTestCommandState.permissions = (PermissionRequestList *)1;
// argv[1] is still NULL
ret = getBooleanCommandPermissions(cmd, true, &permissions);
assert(ret == 55);
assert(gTestCommandState.called);
assert(strcmp(gTestCommandState.name, "bool") == 0);
assert(gTestCommandState.cookie == &gTestCommandState);
assert(gTestCommandState.argc == 1);
assert(gTestCommandState.argv == NULL);
assert(gTestCommandState.permissions == &permissions);
/* Smoke test commandCleanup().
*/
commandCleanup();
return 0;
}
static int
test_functions()
{
Function *fn;
int ret;
ret = commandInit();
assert(ret == 0);
/* Try calling with some bad values.
*/
ret = registerFunction(NULL, NULL, NULL);
assert(ret < 0);
ret = registerFunction("hello", NULL, NULL);
assert(ret < 0);
fn = findFunction(NULL);
assert(fn == NULL);
ret = callFunction(NULL, -1, NULL, NULL, NULL);
assert(ret < 0);
/* Register some functions.
*/
ret = registerFunction("one", testFunction, &gTestCommandState);
assert(ret == 0);
ret = registerFunction("two", testFunction, &gTestCommandState);
assert(ret == 0);
ret = registerFunction("three", testFunction, &gTestCommandState);
assert(ret == 0);
/* Make sure that all of those functions exist.
* argument types are correct.
*/
fn = findFunction("one");
assert(fn != NULL);
fn = findFunction("two");
assert(fn != NULL);
fn = findFunction("three");
assert(fn != NULL);
/* Make sure that no similar functions exist.
*/
fn = findFunction("on");
assert(fn == NULL);
fn = findFunction("onee");
assert(fn == NULL);
/* Make sure that a double insertion fails.
*/
ret = registerFunction("one", testFunction, &gTestCommandState);
assert(ret < 0);
/* Make sure that bad args fail.
*/
fn = findFunction("one");
assert(fn != NULL);
// argc must be non-negative
ret = callFunction(fn, -1, NULL, (char **)1, NULL);
assert(ret < 0);
// argv can't be NULL if argc > 0
ret = callFunction(fn, 1, NULL, (char **)1, NULL);
assert(ret < 0);
// result can't be NULL
ret = callFunction(fn, 0, NULL, NULL, NULL);
assert(ret < 0);
/* Set up some arguments.
*/
int argc = 4;
const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
/* Make a call and make sure that it occurred.
*/
char *functionResult;
size_t functionResultLen;
fn = findFunction("one");
assert(fn != NULL);
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
gTestCommandState.called = false;
gTestCommandState.returnValue = 25;
gTestCommandState.functionResult = "1234";
gTestCommandState.permissions = (PermissionRequestList *)1;
functionResult = NULL;
functionResultLen = 55;
ret = callFunction(fn, argc, argv,
&functionResult, &functionResultLen);
//xxx also try calling with a null resultLen arg (should succeed)
//xxx also try calling with a null argv element (should fail)
assert(ret == 25);
assert(gTestCommandState.called);
assert(strcmp(gTestCommandState.name, "one") == 0);
assert(gTestCommandState.cookie == &gTestCommandState);
assert(gTestCommandState.argc == argc);
assert(gTestCommandState.argv == argv);
assert(gTestCommandState.permissions == NULL);
assert(strcmp(functionResult, "1234") == 0);
assert(functionResultLen == strlen(functionResult));
/* Try looking up permissions.
*/
PermissionRequestList permissions;
fn = findFunction("one");
assert(fn != NULL);
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
gTestCommandState.called = false;
gTestCommandState.returnValue = 27;
gTestCommandState.permissions = (PermissionRequestList *)1;
argv[1] = NULL; // null out an arg, which should be ok
ret = getFunctionPermissions(fn, argc, argv, &permissions);
assert(ret == 27);
assert(gTestCommandState.called);
assert(strcmp(gTestCommandState.name, "one") == 0);
assert(gTestCommandState.cookie == &gTestCommandState);
assert(gTestCommandState.argc == argc);
assert(gTestCommandState.argv == argv);
assert(gTestCommandState.permissions == &permissions);
/* Smoke test commandCleanup().
*/
commandCleanup();
return 0;
}
static int
test_interaction()
{
Command *cmd;
Function *fn;
int ret;
ret = commandInit();
assert(ret == 0);
/* Register some commands.
*/
ret = registerCommand("one", CMD_ARGS_WORDS, testCommand, (void *)0xc1);
assert(ret == 0);
ret = registerCommand("two", CMD_ARGS_WORDS, testCommand, (void *)0xc2);
assert(ret == 0);
/* Register some functions, one of which shares a name with a command.
*/
ret = registerFunction("one", testFunction, (void *)0xf1);
assert(ret == 0);
ret = registerFunction("three", testFunction, (void *)0xf3);
assert(ret == 0);
/* Look up each of the commands, and make sure no command exists
* with the name used only by our function.
*/
cmd = findCommand("one");
assert(cmd != NULL);
cmd = findCommand("two");
assert(cmd != NULL);
cmd = findCommand("three");
assert(cmd == NULL);
/* Look up each of the functions, and make sure no function exists
* with the name used only by our command.
*/
fn = findFunction("one");
assert(fn != NULL);
fn = findFunction("two");
assert(fn == NULL);
fn = findFunction("three");
assert(fn != NULL);
/* Set up some arguments.
*/
int argc = 4;
const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
/* Call the overlapping command and make sure that the cookie is correct.
*/
cmd = findCommand("one");
assert(cmd != NULL);
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
gTestCommandState.called = false;
gTestCommandState.returnValue = 123;
gTestCommandState.permissions = (PermissionRequestList *)1;
ret = callCommand(cmd, argc, argv);
assert(ret == 123);
assert(gTestCommandState.called);
assert(strcmp(gTestCommandState.name, "one") == 0);
assert((int)gTestCommandState.cookie == 0xc1);
assert(gTestCommandState.argc == argc);
assert(gTestCommandState.argv == argv);
assert(gTestCommandState.permissions == NULL);
/* Call the overlapping function and make sure that the cookie is correct.
*/
char *functionResult;
size_t functionResultLen;
fn = findFunction("one");
assert(fn != NULL);
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
gTestCommandState.called = false;
gTestCommandState.returnValue = 125;
gTestCommandState.functionResult = "5678";
gTestCommandState.permissions = (PermissionRequestList *)2;
functionResult = NULL;
functionResultLen = 66;
ret = callFunction(fn, argc, argv, &functionResult, &functionResultLen);
assert(ret == 125);
assert(gTestCommandState.called);
assert(strcmp(gTestCommandState.name, "one") == 0);
assert((int)gTestCommandState.cookie == 0xf1);
assert(gTestCommandState.argc == argc);
assert(gTestCommandState.argv == argv);
assert(gTestCommandState.permissions == NULL);
assert(strcmp(functionResult, "5678") == 0);
assert(functionResultLen == strlen(functionResult));
/* Clean up.
*/
commandCleanup();
return 0;
}
int
test_cmd_fn()
{
int ret;
ret = test_commands();
if (ret != 0) {
fprintf(stderr, "test_commands() failed: %d\n", ret);
return ret;
}
ret = test_functions();
if (ret != 0) {
fprintf(stderr, "test_functions() failed: %d\n", ret);
return ret;
}
ret = test_interaction();
if (ret != 0) {
fprintf(stderr, "test_interaction() failed: %d\n", ret);
return ret;
}
return 0;
}

View File

@ -1,347 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#undef NDEBUG
#include <assert.h>
#include "permissions.h"
static int
test_permission_list()
{
PermissionRequestList list;
int ret;
int numRequests;
/* Bad parameter
*/
ret = initPermissionRequestList(NULL);
assert(ret < 0);
/* Good parameter
*/
ret = initPermissionRequestList(&list);
assert(ret == 0);
/* Bad parameters
*/
ret = addPermissionRequestToList(NULL, NULL, false, 0);
assert(ret < 0);
ret = addPermissionRequestToList(&list, NULL, false, 0);
assert(ret < 0);
/* Good parameters
*/
numRequests = 0;
ret = addPermissionRequestToList(&list, "one", false, 1);
assert(ret == 0);
numRequests++;
ret = addPermissionRequestToList(&list, "two", false, 2);
assert(ret == 0);
numRequests++;
ret = addPermissionRequestToList(&list, "three", false, 3);
assert(ret == 0);
numRequests++;
ret = addPermissionRequestToList(&list, "recursive", true, 55);
assert(ret == 0);
numRequests++;
/* Validate the list
*/
assert(list.requests != NULL);
assert(list.numRequests == numRequests);
assert(list.numRequests <= list.requestsAllocated);
bool sawOne = false;
bool sawTwo = false;
bool sawThree = false;
bool sawRecursive = false;
int i;
for (i = 0; i < list.numRequests; i++) {
PermissionRequest *req = &list.requests[i];
assert(req->allowed == 0);
/* Order isn't guaranteed, so we have to switch every time.
*/
if (strcmp(req->path, "one") == 0) {
assert(!sawOne);
assert(req->requested == 1);
assert(!req->recursive);
sawOne = true;
} else if (strcmp(req->path, "two") == 0) {
assert(!sawTwo);
assert(req->requested == 2);
assert(!req->recursive);
sawTwo = true;
} else if (strcmp(req->path, "three") == 0) {
assert(!sawThree);
assert(req->requested == 3);
assert(!req->recursive);
sawThree = true;
} else if (strcmp(req->path, "recursive") == 0) {
assert(!sawRecursive);
assert(req->requested == 55);
assert(req->recursive);
sawRecursive = true;
} else {
assert(false);
}
}
assert(sawOne);
assert(sawTwo);
assert(sawThree);
assert(sawRecursive);
/* Smoke test the teardown
*/
freePermissionRequestListElements(&list);
return 0;
}
static int
test_permission_table()
{
int ret;
/* Test the global permissions table.
* Try calling functions without initializing first.
*/
ret = registerPermissionSet(0, NULL);
assert(ret < 0);
ret = countPermissionConflicts((PermissionRequestList *)16, false);
assert(ret < 0);
ret = getPermissionCount();
assert(ret < 0);
const Permission *p;
p = getPermissionAt(0);
assert(p == NULL);
/* Initialize.
*/
ret = permissionInit();
assert(ret == 0);
/* Make sure we can't initialize twice.
*/
ret = permissionInit();
assert(ret < 0);
/* Test the inspection functions.
*/
ret = getPermissionCount();
assert(ret == 0);
p = getPermissionAt(-1);
assert(p == NULL);
p = getPermissionAt(0);
assert(p == NULL);
p = getPermissionAt(1);
assert(p == NULL);
/* Test registerPermissionSet().
* Try some bad parameter values.
*/
ret = registerPermissionSet(-1, NULL);
assert(ret < 0);
ret = registerPermissionSet(1, NULL);
assert(ret < 0);
/* Register some permissions.
*/
Permission p1;
p1.path = "one";
p1.allowed = 1;
ret = registerPermissionSet(1, &p1);
assert(ret == 0);
ret = getPermissionCount();
assert(ret == 1);
Permission p2[2];
p2[0].path = "two";
p2[0].allowed = 2;
p2[1].path = "three";
p2[1].allowed = 3;
ret = registerPermissionSet(2, p2);
assert(ret == 0);
ret = getPermissionCount();
assert(ret == 3);
ret = registerPermissionSet(0, NULL);
assert(ret == 0);
ret = getPermissionCount();
assert(ret == 3);
p1.path = "four";
p1.allowed = 4;
ret = registerPermissionSet(1, &p1);
assert(ret == 0);
/* Make sure the table looks correct.
* Order is important; more-recent additions
* should appear at higher indices.
*/
ret = getPermissionCount();
assert(ret == 4);
int i;
for (i = 0; i < ret; i++) {
const Permission *p;
p = getPermissionAt(i);
assert(p != NULL);
assert(p->allowed == (unsigned int)(i + 1));
switch (i) {
case 0:
assert(strcmp(p->path, "one") == 0);
break;
case 1:
assert(strcmp(p->path, "two") == 0);
break;
case 2:
assert(strcmp(p->path, "three") == 0);
break;
case 3:
assert(strcmp(p->path, "four") == 0);
break;
default:
assert(!"internal error");
break;
}
}
p = getPermissionAt(ret);
assert(p == NULL);
/* Smoke test the teardown
*/
permissionCleanup();
return 0;
}
static int
test_allowed_permissions()
{
int ret;
int numPerms;
/* Make sure these fail before initialization.
*/
ret = countPermissionConflicts((PermissionRequestList *)1, false);
assert(ret < 0);
ret = getAllowedPermissions((const char *)1, false, (unsigned int *)1);
assert(ret < 0);
/* Initialize.
*/
ret = permissionInit();
assert(ret == 0);
/* Make sure countPermissionConflicts() fails with bad parameters.
*/
ret = countPermissionConflicts(NULL, false);
assert(ret < 0);
/* Register a set of permissions.
*/
Permission perms[] = {
{ "/", PERM_NONE },
{ "/stat", PERM_STAT },
{ "/read", PERMSET_READ },
{ "/write", PERMSET_WRITE },
{ "/.stat", PERM_STAT },
{ "/.stat/.read", PERMSET_READ },
{ "/.stat/.read/.write", PERMSET_WRITE },
{ "/.stat/.write", PERMSET_WRITE },
};
numPerms = sizeof(perms) / sizeof(perms[0]);
ret = registerPermissionSet(numPerms, perms);
assert(ret == 0);
/* Build a permission request list.
*/
PermissionRequestList list;
ret = initPermissionRequestList(&list);
assert(ret == 0);
ret = addPermissionRequestToList(&list, "/stat", false, PERM_STAT);
assert(ret == 0);
ret = addPermissionRequestToList(&list, "/read", false, PERM_READ);
assert(ret == 0);
ret = addPermissionRequestToList(&list, "/write", false, PERM_WRITE);
assert(ret == 0);
//TODO: cover more cases once the permission stuff has been implemented
/* All of the requests in the list should be allowed.
*/
ret = countPermissionConflicts(&list, false);
assert(ret == 0);
/* Add a request that will be denied.
*/
ret = addPermissionRequestToList(&list, "/stat", false, 1<<31 | PERM_STAT);
assert(ret == 0);
ret = countPermissionConflicts(&list, false);
assert(ret == 1);
//TODO: more tests
permissionCleanup();
return 0;
}
int
test_permissions()
{
int ret;
ret = test_permission_list();
if (ret != 0) {
fprintf(stderr, "test_permission_list() failed: %d\n", ret);
return ret;
}
ret = test_permission_table();
if (ret != 0) {
fprintf(stderr, "test_permission_table() failed: %d\n", ret);
return ret;
}
ret = test_allowed_permissions();
if (ret != 0) {
fprintf(stderr, "test_permission_table() failed: %d\n", ret);
return ret;
}
return 0;
}

View File

@ -1,146 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#undef NDEBUG
#include <assert.h>
#include "symtab.h"
int
test_symtab()
{
SymbolTable *tab;
void *cookie;
int ret;
/* Test creation */
tab = createSymbolTable();
assert(tab != NULL);
/* Smoke-test deletion */
deleteSymbolTable(tab);
tab = createSymbolTable();
assert(tab != NULL);
/* table parameter must be non-NULL. */
ret = addToSymbolTable(NULL, NULL, 0, NULL);
assert(ret < 0);
/* symbol parameter must be non-NULL. */
ret = addToSymbolTable(tab, NULL, 0, NULL);
assert(ret < 0);
/* cookie parameter must be non-NULL. */
ret = addToSymbolTable(tab, "null", 0, NULL);
assert(ret < 0);
/* table parameter must be non-NULL. */
cookie = findInSymbolTable(NULL, NULL, 0);
assert(cookie == NULL);
/* symbol parameter must be non-NULL. */
cookie = findInSymbolTable(tab, NULL, 0);
assert(cookie == NULL);
/* Try some actual inserts.
*/
ret = addToSymbolTable(tab, "one", 0, (void *)1);
assert(ret == 0);
ret = addToSymbolTable(tab, "two", 0, (void *)2);
assert(ret == 0);
ret = addToSymbolTable(tab, "three", 0, (void *)3);
assert(ret == 0);
/* Try some lookups.
*/
cookie = findInSymbolTable(tab, "one", 0);
assert((int)cookie == 1);
cookie = findInSymbolTable(tab, "two", 0);
assert((int)cookie == 2);
cookie = findInSymbolTable(tab, "three", 0);
assert((int)cookie == 3);
/* Try to insert something that's already there.
*/
ret = addToSymbolTable(tab, "one", 0, (void *)1111);
assert(ret < 0);
/* Make sure that the failed duplicate insert didn't
* clobber the original cookie value.
*/
cookie = findInSymbolTable(tab, "one", 0);
assert((int)cookie == 1);
/* Try looking up something that isn't there.
*/
cookie = findInSymbolTable(tab, "FOUR", 0);
assert(cookie == NULL);
/* Try looking up something that's similar to an existing entry.
*/
cookie = findInSymbolTable(tab, "on", 0);
assert(cookie == NULL);
cookie = findInSymbolTable(tab, "onee", 0);
assert(cookie == NULL);
/* Test flags.
* Try inserting something with a different flag.
*/
ret = addToSymbolTable(tab, "ten", 333, (void *)10);
assert(ret == 0);
/* Make sure it's there.
*/
cookie = findInSymbolTable(tab, "ten", 333);
assert((int)cookie == 10);
/* Make sure it's not there when looked up with a different flag.
*/
cookie = findInSymbolTable(tab, "ten", 0);
assert(cookie == NULL);
/* Try inserting something that has the same name as something
* with a different flag.
*/
ret = addToSymbolTable(tab, "one", 333, (void *)11);
assert(ret == 0);
/* Make sure the new entry exists.
*/
cookie = findInSymbolTable(tab, "one", 333);
assert((int)cookie == 11);
/* Make sure the old entry still has the right value.
*/
cookie = findInSymbolTable(tab, "one", 0);
assert((int)cookie == 1);
/* Try deleting again, now that there's stuff in the table.
*/
deleteSymbolTable(tab);
return 0;
}

View File

@ -1 +0,0 @@
I am a jelly donut.

View File

@ -1,2 +0,0 @@
This is a sample no-op test, which does at least serve to verify that the
test harness is working.

View File

@ -1,17 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
echo 'I am a jelly donut.'

View File

@ -1 +0,0 @@
EOF

View File

@ -1 +0,0 @@
Test to make sure that an empty file is accepted properly.

View File

@ -1,17 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
amend --debug-lex input

View File

@ -1,13 +0,0 @@
IDENTIFIER<this_identifier_is_not_assert> EOL
IDENTIFIER<NEITHER_IS_THIS_123> EOL
IDENTIFIER<but_the_next_one_is> EOL
IDENTIFIER<assert> EOL
IDENTIFIER<next_one_is_not_an_identifier> EOL
line 6: unexpected character at '1'
EOF
line 1: unexpected character at '"'
EOF
line 1: unexpected character at '='
EOF
line 1: unexpected character at '9'
EOF

View File

@ -1 +0,0 @@
Test to make sure that simple command names are tokenized properly.

View File

@ -1,6 +0,0 @@
this_identifier_is_not_assert
NEITHER_IS_THIS_123
but_the_next_one_is
assert
next_one_is_not_an_identifier
12not_an_identifier

View File

@ -1 +0,0 @@
"quoted"

View File

@ -1 +0,0 @@
==

View File

@ -1 +0,0 @@
99

View File

@ -1,20 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
amend --debug-lex input
amend --debug-lex input2
amend --debug-lex input3
amend --debug-lex input4

View File

@ -1,5 +0,0 @@
IDENTIFIER<comment_on_this_line> EOL
IDENTIFIER<none_on_this_one> EOL
EOL
EOL
EOF

View File

@ -1 +0,0 @@
Test to make sure that comments are stripped out.

View File

@ -1,4 +0,0 @@
comment_on_this_line # this is a "comment" (with / a bunch) # \\ of stuff \
none_on_this_one
# beginning of line
# preceded by whitespace

View File

@ -1,13 +0,0 @@
IDENTIFIER<test> WORD<string> EOL
IDENTIFIER<test> WORD<string with spaces> EOL
IDENTIFIER<test> WORD<string with "escaped" quotes> EOL
IDENTIFIER<test> WORD<string with \escaped\ backslashes> EOL
IDENTIFIER<test> WORD<string with # a comment character> EOL
EOF
EOL
IDENTIFIER<test1>line 2: unterminated string at '
'
??? <0>
EOL
IDENTIFIER<test1>line 2: illegal escape at '\n'
??? <0>

View File

@ -1 +0,0 @@
Test to make sure that quoted strings are tokenized properly.

View File

@ -1,5 +0,0 @@
test "string"
test "string with spaces"
test "string with \"escaped\" quotes"
test "string with \\escaped\\ backslashes"
test "string with # a comment character"

View File

@ -1,2 +0,0 @@
# This should fail
test1 "unterminated string

View File

@ -1,2 +0,0 @@
# This should fail
test1 "string with illegal escape \n in the middle"

View File

@ -1,19 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
amend --debug-lex input
amend --debug-lex input2
amend --debug-lex input3

View File

@ -1,6 +0,0 @@
IDENTIFIER<test> WORD<this> WORD<has> WORD<a> WORD<bunch> WORD<of> WORD<BARE> WORD<ALPHA> WORD<WORDS> EOL
IDENTIFIER<test> WORD<12> WORD<this> WORD<has(some> WORD<)> WORD<ALPHANUMER1C> WORD<and> WORD<\\> WORD<whatever> WORD<characters> EOL
IDENTIFIER<test> WORD<this> WORD<has> WORD<mixed> WORD<bare> WORD<and quoted> WORD<words> EOL
IDENTIFIER<test> WORD<what> WORD<about> WORD<quotesin the middle?> EOL
IDENTIFIER<test> WORD<"""shouldn't> WORD<be> WORD<a> WORD<quoted> WORD<string> EOL
EOF

View File

@ -1 +0,0 @@
Test to make sure that argument words are tokenized properly.

View File

@ -1,5 +0,0 @@
test this has a bunch of BARE ALPHA WORDS
test 12 this has(some ) ALPHANUMER1C and \\ whatever characters
test this has mixed bare "and quoted" words
test what about quotes"in the middle?"
test \"\"\"shouldn't be a quoted string

View File

@ -1,2 +0,0 @@
# This should fail
test1 "unterminated string

View File

@ -1,2 +0,0 @@
# This should fail
test1 "string with illegal escape \n in the middle"

View File

@ -1,17 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
amend --debug-lex input

View File

@ -1,11 +0,0 @@
IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<112345oldhashvalue1234123> EOL
IDENTIFIER<mark> WORD<SYS:> WORD<dirty> EOL
IDENTIFIER<copy_dir> WORD<PKG:android-files> WORD<SYS:> EOL
IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<667890newhashvalue6678909> EOL
IDENTIFIER<mark> WORD<SYS:> WORD<clean> EOL
IDENTIFIER<done> EOL
IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> , STRING<blah> ) == STRING<112345oldhashvalue1234123> EOL
IDENTIFIER<assert> STRING<true> == STRING<false> EOL
IDENTIFIER<assert> IDENTIFIER<one> ( STRING<abc> , IDENTIFIER<two> ( STRING<def> ) ) == STRING<five> EOL
IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<667890newhashvalue6678909> || IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<667890newhashvalue6678909> EOL
EOF

View File

@ -1 +0,0 @@
An input script similar to one that will actually be used in practice.

View File

@ -1,10 +0,0 @@
assert hash_dir("SYS:") == "112345oldhashvalue1234123"
mark SYS: dirty
copy_dir "PKG:android-files" SYS:
assert hash_dir("SYS:") == "667890newhashvalue6678909"
mark SYS: clean
done
assert hash_dir("SYS:", "blah") == "112345oldhashvalue1234123"
assert "true" == "false"
assert one("abc", two("def")) == "five"
assert hash_dir("SYS:") == "667890newhashvalue6678909" || hash_dir("SYS:") == "667890newhashvalue6678909"

View File

@ -1,17 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
amend --debug-lex input

View File

@ -1,74 +0,0 @@
command "assert" {
STRING EQ {
FUNCTION hash_dir (
"SYS:"
)
"112345oldhashvalue1234123"
}
}
command "mark" {
"SYS:"
"dirty"
}
command "copy_dir" {
"PKG:android-files"
"SYS:"
}
command "assert" {
STRING EQ {
FUNCTION hash_dir (
"SYS:"
)
"667890newhashvalue6678909"
}
}
command "mark" {
"SYS:"
"clean"
}
command "done" {
}
command "assert" {
STRING EQ {
FUNCTION hash_dir (
"SYS:"
"blah"
)
"112345oldhashvalue1234123"
}
}
command "assert" {
STRING EQ {
"true"
"false"
}
}
command "assert" {
STRING NE {
FUNCTION matches (
FUNCTION hash_dir (
"SYS:"
)
"667890newhashvalue6678909"
"999999newhashvalue6678909"
)
""
}
}
command "assert" {
BOOLEAN OR {
STRING EQ {
FUNCTION hash_dir (
"SYS:"
)
"667890newhashvalue6678909"
}
STRING EQ {
FUNCTION hash_dir (
"SYS:"
)
"999999newhashvalue6678909"
}
}
}
amend: Parse successful.

View File

@ -1 +0,0 @@
An input script similar to one that will actually be used in practice.

View File

@ -1,10 +0,0 @@
assert hash_dir("SYS:") == "112345oldhashvalue1234123"
mark SYS: dirty
copy_dir "PKG:android-files" SYS:
assert hash_dir("SYS:") == "667890newhashvalue6678909"
mark SYS: clean
done
assert hash_dir("SYS:", "blah") == "112345oldhashvalue1234123"
assert "true" == "false"
assert matches(hash_dir("SYS:"), "667890newhashvalue6678909", "999999newhashvalue6678909") != ""
assert hash_dir("SYS:") == "667890newhashvalue6678909" || hash_dir("SYS:") == "999999newhashvalue6678909"

View File

@ -1,17 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
amend --debug-ast input

View File

@ -1,150 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Set up prog to be the path of this script, including following symlinks,
# and set up progdir to be the fully-qualified pathname of its directory.
prog="$0"
while [ -h "${prog}" ]; do
newProg=`/bin/ls -ld "${prog}"`
newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
if expr "x${newProg}" : 'x/' >/dev/null; then
prog="${newProg}"
else
progdir=`dirname "${prog}"`
prog="${progdir}/${newProg}"
fi
done
oldwd=`pwd`
progdir=`dirname "${prog}"`
cd "${progdir}"
progdir=`pwd`
prog="${progdir}"/`basename "${prog}"`
info="info.txt"
run="run"
expected="expected.txt"
output="out.txt"
skip="SKIP"
dev_mode="no"
if [ "x$1" = "x--dev" ]; then
dev_mode="yes"
shift
fi
update_mode="no"
if [ "x$1" = "x--update" ]; then
update_mode="yes"
shift
fi
usage="no"
if [ "x$1" = "x--help" ]; then
usage="yes"
else
if [ "x$1" = "x" ]; then
testdir=`basename "$oldwd"`
else
testdir="$1"
fi
if [ '!' -d "$testdir" ]; then
td2=`echo ${testdir}-*`
if [ '!' -d "$td2" ]; then
echo "${testdir}: no such test directory" 1>&2
usage="yes"
fi
testdir="$td2"
fi
fi
if [ "$usage" = "yes" ]; then
prog=`basename $prog`
(
echo "usage:"
echo " $prog --help Print this message."
echo " $prog testname Run test normally."
echo " $prog --dev testname Development mode (dump to stdout)."
echo " $prog --update testname Update mode (replace expected.txt)."
echo " Omitting the test name uses the current directory as the test."
) 1>&2
exit 1
fi
td_info="$testdir"/"$info"
td_run="$testdir"/"$run"
td_expected="$testdir"/"$expected"
td_skip="$testdir"/"$skip"
if [ -r "$td_skip" ]; then
exit 2
fi
tmpdir=/tmp/test-$$
if [ '!' '(' -r "$td_info" -a -r "$td_run" -a -r "$td_expected" ')' ]; then
echo "${testdir}: missing files" 1>&2
exit 1
fi
# copy the test to a temp dir and run it
echo "${testdir}: running..." 1>&2
rm -rf "$tmpdir"
cp -Rp "$testdir" "$tmpdir"
cd "$tmpdir"
chmod 755 "$run"
#PATH="${progdir}/../build/bin:${PATH}"
good="no"
if [ "$dev_mode" = "yes" ]; then
"./$run" 2>&1
echo "exit status: $?" 1>&2
good="yes"
elif [ "$update_mode" = "yes" ]; then
"./$run" >"${progdir}/$td_expected" 2>&1
good="yes"
else
"./$run" >"$output" 2>&1
cmp -s "$expected" "$output"
if [ "$?" = "0" ]; then
# output == expected
good="yes"
echo "$testdir"': succeeded!' 1>&2
fi
fi
if [ "$good" = "yes" ]; then
cd "$oldwd"
rm -rf "$tmpdir"
exit 0
fi
(
echo "${testdir}: FAILED!"
echo ' '
echo '#################### info'
cat "$info" | sed 's/^/# /g'
echo '#################### diffs'
diff -u "$expected" "$output"
echo '####################'
echo ' '
echo "files left in $tmpdir"
) 1>&2
exit 1

View File

@ -1,69 +0,0 @@
#!/bin/bash
#
# Copyright (C) 2007 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Set up prog to be the path of this script, including following symlinks,
# and set up progdir to be the fully-qualified pathname of its directory.
prog="$0"
while [ -h "${prog}" ]; do
newProg=`/bin/ls -ld "${prog}"`
newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
if expr "x${newProg}" : 'x/' >/dev/null; then
prog="${newProg}"
else
progdir=`dirname "${prog}"`
prog="${progdir}/${newProg}"
fi
done
oldwd=`pwd`
progdir=`dirname "${prog}"`
cd "${progdir}"
progdir=`pwd`
prog="${progdir}"/`basename "${prog}"`
passed=0
skipped=0
skipNames=""
failed=0
failNames=""
for i in *; do
if [ -d "$i" -a -r "$i" ]; then
./one-test "$i"
status=$?
if [ "$status" = "0" ]; then
((passed += 1))
elif [ "$status" = "2" ]; then
((skipped += 1))
skipNames="$skipNames $i"
else
((failed += 1))
failNames="$failNames $i"
fi
fi
done
echo "passed: $passed test(s)"
echo "skipped: $skipped test(s)"
for i in $skipNames; do
echo "skipped: $i"
done
echo "failed: $failed test(s)"
for i in $failNames; do
echo "failed: $i"
done

View File

@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ifneq ($(TARGET_SIMULATOR),true)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
@ -30,7 +28,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := main.c
LOCAL_MODULE := applypatch
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz libminelf
LOCAL_SHARED_LIBRARIES += libz libcutils libstdc++ libc
include $(BUILD_EXECUTABLE)
@ -42,7 +40,7 @@ LOCAL_MODULE := applypatch_static
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_TAGS := eng
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz
LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz libminelf
LOCAL_STATIC_LIBRARIES += libz libcutils libstdc++ libc
include $(BUILD_EXECUTABLE)
@ -57,5 +55,3 @@ LOCAL_C_INCLUDES += external/zlib external/bzip2
LOCAL_STATIC_LIBRARIES += libz libbz
include $(BUILD_HOST_EXECUTABLE)
endif # !TARGET_SIMULATOR

View File

@ -31,21 +31,27 @@
#include "edify/expr.h"
int SaveFileContents(const char* filename, FileContents file);
int LoadMTDContents(const char* filename, FileContents* file);
static int LoadPartitionContents(const char* filename, FileContents* file);
int ParseSha1(const char* str, uint8_t* digest);
ssize_t FileSink(unsigned char* data, ssize_t len, void* token);
static ssize_t FileSink(unsigned char* data, ssize_t len, void* token);
static int mtd_partitions_scanned = 0;
// Read a file into memory; store it and its associated metadata in
// *file. Return 0 on success.
int LoadFileContents(const char* filename, FileContents* file) {
// Read a file into memory; optionally (retouch_flag == RETOUCH_DO_MASK) mask
// the retouched entries back to their original value (such that SHA-1 checks
// don't fail due to randomization); store the file contents and associated
// metadata in *file.
//
// Return 0 on success.
int LoadFileContents(const char* filename, FileContents* file,
int retouch_flag) {
file->data = NULL;
// A special 'filename' beginning with "MTD:" means to load the
// contents of an MTD partition.
if (strncmp(filename, "MTD:", 4) == 0) {
return LoadMTDContents(filename, file);
// A special 'filename' beginning with "MTD:" or "EMMC:" means to
// load the contents of a partition.
if (strncmp(filename, "MTD:", 4) == 0 ||
strncmp(filename, "EMMC:", 5) == 0) {
return LoadPartitionContents(filename, file);
}
if (stat(filename, &file->st) != 0) {
@ -74,6 +80,20 @@ int LoadFileContents(const char* filename, FileContents* file) {
}
fclose(f);
// apply_patch[_check] functions are blind to randomization. Randomization
// is taken care of in [Undo]RetouchBinariesFn. If there is a mismatch
// within a file, this means the file is assumed "corrupt" for simplicity.
if (retouch_flag) {
int32_t desired_offset = 0;
if (retouch_mask_data(file->data, file->size,
&desired_offset, NULL) != RETOUCH_DATA_MATCHED) {
printf("error trying to mask retouch entries\n");
free(file->data);
file->data = NULL;
return -1;
}
}
SHA(file->data, file->size, file->sha1);
return 0;
}
@ -98,27 +118,35 @@ void FreeFileContents(FileContents* file) {
free(file);
}
// Load the contents of an MTD partition into the provided
// Load the contents of an MTD or EMMC partition into the provided
// FileContents. filename should be a string of the form
// "MTD:<partition_name>:<size_1>:<sha1_1>:<size_2>:<sha1_2>:...".
// The smallest size_n bytes for which that prefix of the mtd contents
// has the corresponding sha1 hash will be loaded. It is acceptable
// for a size value to be repeated with different sha1s. Will return
// 0 on success.
// "MTD:<partition_name>:<size_1>:<sha1_1>:<size_2>:<sha1_2>:..." (or
// "EMMC:<partition_device>:..."). The smallest size_n bytes for
// which that prefix of the partition contents has the corresponding
// sha1 hash will be loaded. It is acceptable for a size value to be
// repeated with different sha1s. Will return 0 on success.
//
// This complexity is needed because if an OTA installation is
// interrupted, the partition might contain either the source or the
// target data, which might be of different lengths. We need to know
// the length in order to read from MTD (there is no "end-of-file"
// marker), so the caller must specify the possible lengths and the
// hash of the data, and we'll do the load expecting to find one of
// those hashes.
int LoadMTDContents(const char* filename, FileContents* file) {
#ifdef BOARD_USES_MTDUTILS
// the length in order to read from a partition (there is no
// "end-of-file" marker), so the caller must specify the possible
// lengths and the hash of the data, and we'll do the load expecting
// to find one of those hashes.
enum PartitionType { MTD, EMMC };
static int LoadPartitionContents(const char* filename, FileContents* file) {
char* copy = strdup(filename);
const char* magic = strtok(copy, ":");
if (strcmp(magic, "MTD") != 0) {
printf("LoadMTDContents called with bad filename (%s)\n",
enum PartitionType type;
if (strcmp(magic, "MTD") == 0) {
type = MTD;
} else if (strcmp(magic, "EMMC") == 0) {
type = EMMC;
} else {
printf("LoadPartitionContents called with bad filename (%s)\n",
filename);
return -1;
}
@ -132,7 +160,7 @@ int LoadMTDContents(const char* filename, FileContents* file) {
}
}
if (colons < 3 || colons%2 == 0) {
printf("LoadMTDContents called with bad filename (%s)\n",
printf("LoadPartitionContents called with bad filename (%s)\n",
filename);
}
@ -145,7 +173,7 @@ int LoadMTDContents(const char* filename, FileContents* file) {
const char* size_str = strtok(NULL, ":");
size[i] = strtol(size_str, NULL, 10);
if (size[i] == 0) {
printf("LoadMTDContents called with bad size (%s)\n", filename);
printf("LoadPartitionContents called with bad size (%s)\n", filename);
return -1;
}
sha1sum[i] = strtok(NULL, ":");
@ -157,23 +185,38 @@ int LoadMTDContents(const char* filename, FileContents* file) {
size_array = size;
qsort(index, pairs, sizeof(int), compare_size_indices);
if (!mtd_partitions_scanned) {
mtd_scan_partitions();
mtd_partitions_scanned = 1;
}
MtdReadContext* ctx = NULL;
FILE* dev = NULL;
const MtdPartition* mtd = mtd_find_partition_by_name(partition);
if (mtd == NULL) {
printf("mtd partition \"%s\" not found (loading %s)\n",
partition, filename);
return -1;
}
switch (type) {
case MTD:
if (!mtd_partitions_scanned) {
mtd_scan_partitions();
mtd_partitions_scanned = 1;
}
MtdReadContext* ctx = mtd_read_partition(mtd);
if (ctx == NULL) {
printf("failed to initialize read of mtd partition \"%s\"\n",
partition);
return -1;
const MtdPartition* mtd = mtd_find_partition_by_name(partition);
if (mtd == NULL) {
printf("mtd partition \"%s\" not found (loading %s)\n",
partition, filename);
return -1;
}
ctx = mtd_read_partition(mtd);
if (ctx == NULL) {
printf("failed to initialize read of mtd partition \"%s\"\n",
partition);
return -1;
}
break;
case EMMC:
dev = fopen(partition, "rb");
if (dev == NULL) {
printf("failed to open emmc partition \"%s\": %s\n",
partition, strerror(errno));
return -1;
}
}
SHA_CTX sha_ctx;
@ -192,7 +235,15 @@ int LoadMTDContents(const char* filename, FileContents* file) {
size_t next = size[index[i]] - file->size;
size_t read = 0;
if (next > 0) {
read = mtd_read_data(ctx, p, next);
switch (type) {
case MTD:
read = mtd_read_data(ctx, p, next);
break;
case EMMC:
read = fread(p, 1, next, dev);
break;
}
if (next != read) {
printf("short read (%d bytes of %d) for partition \"%s\"\n",
read, next, partition);
@ -221,7 +272,7 @@ int LoadMTDContents(const char* filename, FileContents* file) {
if (memcmp(sha_so_far, parsed_sha, SHA_DIGEST_SIZE) == 0) {
// we have a match. stop reading the partition; we'll return
// the data we've read so far.
printf("mtd read matched size %d sha %s\n",
printf("partition read matched size %d sha %s\n",
size[index[i]], sha1sum[index[i]]);
break;
}
@ -229,12 +280,21 @@ int LoadMTDContents(const char* filename, FileContents* file) {
p += read;
}
mtd_read_close(ctx);
switch (type) {
case MTD:
mtd_read_close(ctx);
break;
case EMMC:
fclose(dev);
break;
}
if (i == pairs) {
// Ran off the end of the list of (size,sha1) pairs without
// finding a match.
printf("contents of MTD partition \"%s\" didn't match %s\n",
printf("contents of partition \"%s\" didn't match %s\n",
partition, filename);
free(file->data);
file->data = NULL;
@ -257,10 +317,6 @@ int LoadMTDContents(const char* filename, FileContents* file) {
free(sha1sum);
return 0;
#else
printf("mtd utils not supported.\n");
return -1;
#endif
}
@ -297,68 +353,88 @@ int SaveFileContents(const char* filename, FileContents file) {
return 0;
}
// Write a memory buffer to target_mtd partition, a string of the form
// "MTD:<partition>[:...]". Return 0 on success.
int WriteToMTDPartition(unsigned char* data, size_t len,
const char* target_mtd) {
#ifdef BOARD_USES_MTDUTILS
char* partition = strchr(target_mtd, ':');
// Write a memory buffer to 'target' partition, a string of the form
// "MTD:<partition>[:...]" or "EMMC:<partition_device>:". Return 0 on
// success.
int WriteToPartition(unsigned char* data, size_t len,
const char* target) {
char* copy = strdup(target);
const char* magic = strtok(copy, ":");
enum PartitionType type;
if (strcmp(magic, "MTD") == 0) {
type = MTD;
} else if (strcmp(magic, "EMMC") == 0) {
type = EMMC;
} else {
printf("WriteToPartition called with bad target (%s)\n", target);
return -1;
}
const char* partition = strtok(NULL, ":");
if (partition == NULL) {
printf("bad MTD target name \"%s\"\n", target_mtd);
return -1;
}
++partition;
// Trim off anything after a colon, eg "MTD:boot:blah:blah:blah...".
// We want just the partition name "boot".
partition = strdup(partition);
char* end = strchr(partition, ':');
if (end != NULL)
*end = '\0';
if (!mtd_partitions_scanned) {
mtd_scan_partitions();
mtd_partitions_scanned = 1;
}
const MtdPartition* mtd = mtd_find_partition_by_name(partition);
if (mtd == NULL) {
printf("mtd partition \"%s\" not found for writing\n", partition);
printf("bad partition target name \"%s\"\n", target);
return -1;
}
MtdWriteContext* ctx = mtd_write_partition(mtd);
if (ctx == NULL) {
printf("failed to init mtd partition \"%s\" for writing\n",
partition);
return -1;
switch (type) {
case MTD:
if (!mtd_partitions_scanned) {
mtd_scan_partitions();
mtd_partitions_scanned = 1;
}
const MtdPartition* mtd = mtd_find_partition_by_name(partition);
if (mtd == NULL) {
printf("mtd partition \"%s\" not found for writing\n",
partition);
return -1;
}
MtdWriteContext* ctx = mtd_write_partition(mtd);
if (ctx == NULL) {
printf("failed to init mtd partition \"%s\" for writing\n",
partition);
return -1;
}
size_t written = mtd_write_data(ctx, (char*)data, len);
if (written != len) {
printf("only wrote %d of %d bytes to MTD %s\n",
written, len, partition);
mtd_write_close(ctx);
return -1;
}
if (mtd_erase_blocks(ctx, -1) < 0) {
printf("error finishing mtd write of %s\n", partition);
mtd_write_close(ctx);
return -1;
}
if (mtd_write_close(ctx)) {
printf("error closing mtd write of %s\n", partition);
return -1;
}
break;
case EMMC:
;
FILE* f = fopen(partition, "wb");
if (fwrite(data, 1, len, f) != len) {
printf("short write writing to %s (%s)\n",
partition, strerror(errno));
return -1;
}
if (fclose(f) != 0) {
printf("error closing %s (%s)\n", partition, strerror(errno));
return -1;
}
break;
}
size_t written = mtd_write_data(ctx, (char*)data, len);
if (written != len) {
printf("only wrote %d of %d bytes to MTD %s\n",
written, len, partition);
mtd_write_close(ctx);
return -1;
}
if (mtd_erase_blocks(ctx, -1) < 0) {
printf("error finishing mtd write of %s\n", partition);
mtd_write_close(ctx);
return -1;
}
if (mtd_write_close(ctx)) {
printf("error closing mtd write of %s\n", partition);
return -1;
}
free(partition);
free(copy);
return 0;
#else
printf("mtd utils not supported.\n");
return -1;
#endif
}
@ -417,10 +493,10 @@ int applypatch_check(const char* filename,
file.data = NULL;
// It's okay to specify no sha1s; the check will pass if the
// LoadFileContents is successful. (Useful for reading MTD
// LoadFileContents is successful. (Useful for reading
// partitions, where the filename encodes the sha1s; no need to
// check them twice.)
if (LoadFileContents(filename, &file) != 0 ||
if (LoadFileContents(filename, &file, RETOUCH_DO_MASK) != 0 ||
(num_patches > 0 &&
FindMatchingPatch(file.sha1, patch_sha1_str, num_patches) < 0)) {
printf("file \"%s\" doesn't have any of expected "
@ -434,7 +510,7 @@ int applypatch_check(const char* filename,
// exists and matches the sha1 we're looking for, the check still
// passes.
if (LoadFileContents(CACHE_TEMP_SOURCE, &file) != 0) {
if (LoadFileContents(CACHE_TEMP_SOURCE, &file, RETOUCH_DO_MASK) != 0) {
printf("failed to load cache file\n");
return 1;
}
@ -529,8 +605,8 @@ int CacheSizeCheck(size_t bytes) {
// - otherwise, or if any error is encountered, exits with non-zero
// status.
//
// <source_filename> may refer to an MTD partition to read the source
// data. See the comments for the LoadMTDContents() function above
// <source_filename> may refer to a partition to read the source data.
// See the comments for the LoadPartition Contents() function above
// for the format of such a filename.
int applypatch(const char* source_filename,
@ -560,7 +636,8 @@ int applypatch(const char* source_filename,
int made_copy = 0;
// We try to load the target file into the source_file object.
if (LoadFileContents(target_filename, &source_file) == 0) {
if (LoadFileContents(target_filename, &source_file,
RETOUCH_DO_MASK) == 0) {
if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
// The early-exit case: the patch was already applied, this file
// has the desired hash, nothing for us to do.
@ -576,7 +653,8 @@ int applypatch(const char* source_filename,
// Need to load the source file: either we failed to load the
// target file, or we did but it's different from the source file.
free(source_file.data);
LoadFileContents(source_filename, &source_file);
LoadFileContents(source_filename, &source_file,
RETOUCH_DO_MASK);
}
if (source_file.data != NULL) {
@ -591,7 +669,8 @@ int applypatch(const char* source_filename,
free(source_file.data);
printf("source file is bad; trying copy\n");
if (LoadFileContents(CACHE_TEMP_SOURCE, &copy_file) < 0) {
if (LoadFileContents(CACHE_TEMP_SOURCE, &copy_file,
RETOUCH_DO_MASK) < 0) {
// fail.
printf("failed to read copy file\n");
return 1;
@ -599,7 +678,7 @@ int applypatch(const char* source_filename,
int to_use = FindMatchingPatch(copy_file.sha1,
patch_sha1_str, num_patches);
if (to_use > 0) {
if (to_use >= 0) {
copy_patch_value = patch_data[to_use];
}
@ -634,14 +713,16 @@ int applypatch(const char* source_filename,
// Is there enough room in the target filesystem to hold the patched
// file?
if (strncmp(target_filename, "MTD:", 4) == 0) {
// If the target is an MTD partition, we're actually going to
// write the output to /tmp and then copy it to the partition.
// statfs() always returns 0 blocks free for /tmp, so instead
// we'll just assume that /tmp has enough space to hold the file.
if (strncmp(target_filename, "MTD:", 4) == 0 ||
strncmp(target_filename, "EMMC:", 5) == 0) {
// If the target is a partition, we're actually going to
// write the output to /tmp and then copy it to the
// partition. statfs() always returns 0 blocks free for
// /tmp, so instead we'll just assume that /tmp has enough
// space to hold the file.
// We still write the original source to cache, in case the MTD
// write is interrupted.
// We still write the original source to cache, in case
// the partition write is interrupted.
if (MakeFreeSpaceOnCache(source_file.size) < 0) {
printf("not enough free space on /cache\n");
return 1;
@ -656,7 +737,8 @@ int applypatch(const char* source_filename,
int enough_space = 0;
if (retry > 0) {
size_t free_space = FreeSpaceForFile(target_fs);
int enough_space =
enough_space =
(free_space > (256 << 10)) && // 256k (two-block) minimum
(free_space > (target_size * 3 / 2)); // 50% margin of error
printf("target %ld bytes; free space %ld bytes; retry %d; enough %d\n",
(long)target_size, (long)free_space, retry, enough_space);
@ -671,11 +753,13 @@ int applypatch(const char* source_filename,
// copy the source file to cache, then delete it from the original
// location.
if (strncmp(source_filename, "MTD:", 4) == 0) {
if (strncmp(source_filename, "MTD:", 4) == 0 ||
strncmp(source_filename, "EMMC:", 5) == 0) {
// It's impossible to free space on the target filesystem by
// deleting the source if the source is an MTD partition. If
// deleting the source if the source is a partition. If
// we're ever in a state where we need to do this, fail.
printf("not enough free space for target but source is MTD\n");
printf("not enough free space for target but source "
"is partition\n");
return 1;
}
@ -714,7 +798,8 @@ int applypatch(const char* source_filename,
void* token = NULL;
output = -1;
outname = NULL;
if (strncmp(target_filename, "MTD:", 4) == 0) {
if (strncmp(target_filename, "MTD:", 4) == 0 ||
strncmp(target_filename, "EMMC:", 5) == 0) {
// We store the decoded output in memory.
msi.buffer = malloc(target_size);
if (msi.buffer == NULL) {
@ -790,8 +875,8 @@ int applypatch(const char* source_filename,
}
if (output < 0) {
// Copy the temp file to the MTD partition.
if (WriteToMTDPartition(msi.buffer, msi.pos, target_filename) != 0) {
// Copy the temp file to the partition.
if (WriteToPartition(msi.buffer, msi.pos, target_filename) != 0) {
printf("write of patched data to %s failed\n", target_filename);
return 1;
}

View File

@ -19,6 +19,7 @@
#include <sys/stat.h>
#include "mincrypt/sha.h"
#include "minelf/Retouch.h"
#include "edify/expr.h"
typedef struct _Patch {
@ -59,10 +60,12 @@ int applypatch_check(const char* filename,
int num_patches,
char** const patch_sha1_str);
// Read a file into memory; store it and its associated metadata in
// *file. Return 0 on success.
int LoadFileContents(const char* filename, FileContents* file);
int LoadFileContents(const char* filename, FileContents* file,
int retouch_flag);
int SaveFileContents(const char* filename, FileContents file);
void FreeFileContents(FileContents* file);
int FindMatchingPatch(uint8_t* sha1, char** const patch_sha1_str,
int num_patches);
// bsdiff.c
void ShowBSDiffLicense();

View File

@ -74,7 +74,7 @@ static int ParsePatchArgs(int argc, char** argv,
(*patches)[i] = NULL;
} else {
FileContents fc;
if (LoadFileContents(colon, &fc) != 0) {
if (LoadFileContents(colon, &fc, RETOUCH_DONT_MASK) != 0) {
goto abort;
}
(*patches)[i] = malloc(sizeof(Value));

View File

@ -1,7 +1,19 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -DBOARD_BOOT_DEVICE=\"$(BOARD_BOOT_DEVICE)\"
BOARD_RECOVERY_DEFINES := BOARD_BML_BOOT BOARD_BML_RECOVERY
$(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
$(if $($(board_define)), \
$(eval LOCAL_CFLAGS += -D$(board_define)=\"$($(board_define))\") \
) \
)
LOCAL_STATIC_LIBRARIES := libcrecovery
LOCAL_C_INCLUDES := bootable/recovery/libcrecovery
LOCAL_SRC_FILES := bmlutils.c
LOCAL_MODULE := libbmlutils
LOCAL_MODULE_TAGS := eng
include $(BUILD_STATIC_LIBRARY)

View File

@ -20,9 +20,18 @@
#include <signal.h>
#include <sys/wait.h>
extern int __system(const char *command);
#include <common.h>
#define BML_UNLOCK_ALL 0x8A29 ///< unlock all partition RO -> RW
#ifndef BOARD_BML_BOOT
#define BOARD_BML_BOOT "/dev/block/bml7"
#endif
#ifndef BOARD_BML_RECOVERY
#define BOARD_BML_RECOVERY "/dev/block/bml8"
#endif
static int restore_internal(const char* bml, const char* filename)
{
char buf[4096];
@ -57,25 +66,90 @@ static int restore_internal(const char* bml, const char* filename)
int cmd_bml_restore_raw_partition(const char *partition, const char *filename)
{
char *bml;
if (strcmp(partition, "boot") == 0 || strcmp(partition, "recovery") == 0)
bml = "/dev/block/bml7";
else
if (strcmp(partition, "boot") != 0 && strcmp(partition, "recovery") != 0 && strcmp(partition, "recoveryonly") != 0 && partition[0] != '/')
return 6;
int ret = restore_internal("/dev/block/bml7", filename);
if (ret != 0)
return ret;
int ret = -1;
if (strcmp(partition, "recoveryonly") != 0) {
// always restore boot, regardless of whether recovery or boot is flashed.
// this is because boot and recovery are the same on some samsung phones.
// unless of course, recoveryonly is explictly chosen (bml8)
ret = restore_internal(BOARD_BML_BOOT, filename);
if (ret != 0)
return ret;
}
ret = restore_internal("/dev/block/bml8", filename);
if (strcmp(partition, "recovery") == 0 || strcmp(partition, "recoveryonly") == 0)
ret = restore_internal(BOARD_BML_RECOVERY, filename);
// support explicitly provided device paths
if (partition[0] == '/')
ret = restore_internal(partition, filename);
return ret;
}
int cmd_bml_backup_raw_partition(const char *partition, const char *filename)
int cmd_bml_backup_raw_partition(const char *partition, const char *out_file)
{
char tmp[PATH_MAX];
sprintf(tmp, "dd of=%s if=/dev/block/bml7 bs=4096", filename);
return __system(tmp);
char* bml;
if (strcmp("boot", partition) == 0)
bml = BOARD_BML_BOOT;
else if (strcmp("recovery", partition) == 0)
bml = BOARD_BML_RECOVERY;
else if (partition[0] == '/') {
// support explicitly provided device paths
bml = partition;
}
else {
printf("Invalid partition.\n");
return -1;
}
int ch;
FILE *in;
FILE *out;
int val = 0;
char buf[512];
unsigned sz = 0;
unsigned i;
int ret = -1;
char *in_file = bml;
in = fopen ( in_file, "r" );
if (in == NULL)
goto ERROR3;
out = fopen ( out_file, "w" );
if (out == NULL)
goto ERROR2;
fseek(in, 0L, SEEK_END);
sz = ftell(in);
fseek(in, 0L, SEEK_SET);
if (sz % 512)
{
while ( ( ch = fgetc ( in ) ) != EOF )
fputc ( ch, out );
}
else
{
for (i=0; i< (sz/512); i++)
{
if ((fread(buf, 512, 1, in)) != 1)
goto ERROR1;
if ((fwrite(buf, 512, 1, out)) != 1)
goto ERROR1;
}
}
fsync(out);
ret = 0;
ERROR1:
fclose ( out );
ERROR2:
fclose ( in );
ERROR3:
return ret;
}
int cmd_bml_erase_raw_partition(const char *partition)
@ -98,3 +172,35 @@ int cmd_bml_get_partition_device(const char *partition, char *device)
{
return -1;
}
int format_rfs_device (const char *device, const char *path) {
const char *fatsize = "32";
const char *sectorsize = "1";
if (strcmp(path, "/datadata") == 0 || strcmp(path, "/cache") == 0) {
fatsize = "16";
}
// Just in case /data sector size needs to be altered
else if (strcmp(path, "/data") == 0 ) {
sectorsize = "1";
}
// dump 10KB of zeros to partition before format due to fat.format bug
char cmd[PATH_MAX];
sprintf(cmd, "/sbin/dd if=/dev/zero of=%s bs=4096 count=10", device);
if(__system(cmd)) {
printf("failure while zeroing rfs partition.\n");
return -1;
}
// Run fat.format
sprintf(cmd, "/sbin/fat.format -F %s -S 4096 -s %s %s", fatsize, sectorsize, device);
if(__system(cmd)) {
printf("failure while running fat.format\n");
return -1;
}
return 0;
}

6
bmlutils/bmlutils.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef BMLUTILS_H_
#define BMLUTILS_H_
int format_rfs_device (const char *device, const char *path);
#endif // BMLUTILS_H_

View File

@ -22,97 +22,114 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
static int get_bootloader_message_mtd(struct bootloader_message *out, const Volume* v);
static int set_bootloader_message_mtd(const struct bootloader_message *in, const Volume* v);
static int get_bootloader_message_block(struct bootloader_message *out, const Volume* v);
static int set_bootloader_message_block(const struct bootloader_message *in, const Volume* v);
int get_bootloader_message(struct bootloader_message *out) {
Volume* v = volume_for_path("/misc");
if(v)
{
if (strcmp(v->fs_type, "mtd") == 0) {
return get_bootloader_message_mtd(out, v);
} else if (strcmp(v->fs_type, "emmc") == 0) {
return get_bootloader_message_block(out, v);
}
LOGE("unknown misc partition fs_type \"%s\"\n", v->fs_type);
return -1;
}
return -1;
}
int set_bootloader_message(const struct bootloader_message *in) {
Volume* v = volume_for_path("/misc");
if(v)
{
if (strcmp(v->fs_type, "mtd") == 0) {
return set_bootloader_message_mtd(in, v);
} else if (strcmp(v->fs_type, "emmc") == 0) {
return set_bootloader_message_block(in, v);
}
LOGE("unknown misc partition fs_type \"%s\"\n", v->fs_type);
return -1;
}
return -1;
}
// ------------------------------
// for misc partitions on MTD
// ------------------------------
static const char *CACHE_NAME = "CACHE:";
static const char *MISC_NAME = "MISC:";
static const int MISC_PAGES = 3; // number of pages to save
static const int MISC_COMMAND_PAGE = 1; // bootloader command is this page
#ifdef LOG_VERBOSE
static void dump_data(const char *data, int len) {
int pos;
for (pos = 0; pos < len; ) {
printf("%05x: %02x", pos, data[pos]);
for (++pos; pos < len && (pos % 24) != 0; ++pos) {
printf(" %02x", data[pos]);
}
printf("\n");
}
}
#endif
int get_bootloader_message(struct bootloader_message *out) {
static int get_bootloader_message_mtd(struct bootloader_message *out,
const Volume* v) {
size_t write_size;
const MtdPartition *part = get_root_mtd_partition(MISC_NAME);
mtd_scan_partitions();
const MtdPartition *part = mtd_find_partition_by_name(v->device);
if (part == NULL || mtd_partition_info(part, NULL, NULL, &write_size)) {
LOGE("Can't find %s\n", MISC_NAME);
LOGE("Can't find %s\n", v->device);
return -1;
}
MtdReadContext *read = mtd_read_partition(part);
if (read == NULL) {
LOGE("Can't open %s\n(%s)\n", MISC_NAME, strerror(errno));
LOGE("Can't open %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
const ssize_t size = write_size * MISC_PAGES;
char data[size];
ssize_t r = mtd_read_data(read, data, size);
if (r != size) LOGE("Can't read %s\n(%s)\n", MISC_NAME, strerror(errno));
if (r != size) LOGE("Can't read %s\n(%s)\n", v->device, strerror(errno));
mtd_read_close(read);
if (r != size) return -1;
#ifdef LOG_VERBOSE
printf("\n--- get_bootloader_message ---\n");
dump_data(data, size);
printf("\n");
#endif
memcpy(out, &data[write_size * MISC_COMMAND_PAGE], sizeof(*out));
return 0;
}
int set_bootloader_message(const struct bootloader_message *in) {
static int set_bootloader_message_mtd(const struct bootloader_message *in,
const Volume* v) {
size_t write_size;
const MtdPartition *part = get_root_mtd_partition(MISC_NAME);
mtd_scan_partitions();
const MtdPartition *part = mtd_find_partition_by_name(v->device);
if (part == NULL || mtd_partition_info(part, NULL, NULL, &write_size)) {
LOGE("Can't find %s\n", MISC_NAME);
LOGE("Can't find %s\n", v->device);
return -1;
}
MtdReadContext *read = mtd_read_partition(part);
if (read == NULL) {
LOGE("Can't open %s\n(%s)\n", MISC_NAME, strerror(errno));
LOGE("Can't open %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
ssize_t size = write_size * MISC_PAGES;
char data[size];
ssize_t r = mtd_read_data(read, data, size);
if (r != size) LOGE("Can't read %s\n(%s)\n", MISC_NAME, strerror(errno));
if (r != size) LOGE("Can't read %s\n(%s)\n", v->device, strerror(errno));
mtd_read_close(read);
if (r != size) return -1;
memcpy(&data[write_size * MISC_COMMAND_PAGE], in, sizeof(*in));
#ifdef LOG_VERBOSE
printf("\n--- set_bootloader_message ---\n");
dump_data(data, size);
printf("\n");
#endif
MtdWriteContext *write = mtd_write_partition(part);
if (write == NULL) {
LOGE("Can't open %s\n(%s)\n", MISC_NAME, strerror(errno));
LOGE("Can't open %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
if (mtd_write_data(write, data, size) != size) {
LOGE("Can't write %s\n(%s)\n", MISC_NAME, strerror(errno));
LOGE("Can't write %s\n(%s)\n", v->device, strerror(errno));
mtd_write_close(write);
return -1;
}
if (mtd_write_close(write)) {
LOGE("Can't finish %s\n(%s)\n", MISC_NAME, strerror(errno));
LOGE("Can't finish %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
@ -120,6 +137,70 @@ int set_bootloader_message(const struct bootloader_message *in) {
return 0;
}
// ------------------------------------
// for misc partitions on block devices
// ------------------------------------
static void wait_for_device(const char* fn) {
int tries = 0;
int ret;
struct stat buf;
do {
++tries;
ret = stat(fn, &buf);
if (ret) {
printf("stat %s try %d: %s\n", fn, tries, strerror(errno));
sleep(1);
}
} while (ret && tries < 10);
if (ret) {
printf("failed to stat %s\n", fn);
}
}
static int get_bootloader_message_block(struct bootloader_message *out,
const Volume* v) {
wait_for_device(v->device);
FILE* f = fopen(v->device, "rb");
if (f == NULL) {
LOGE("Can't open %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
struct bootloader_message temp;
int count = fread(&temp, sizeof(temp), 1, f);
if (count != 1) {
LOGE("Failed reading %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
if (fclose(f) != 0) {
LOGE("Failed closing %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
memcpy(out, &temp, sizeof(temp));
return 0;
}
static int set_bootloader_message_block(const struct bootloader_message *in,
const Volume* v) {
wait_for_device(v->device);
FILE* f = fopen(v->device, "wb");
if (f == NULL) {
LOGE("Can't open %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
int count = fwrite(in, sizeof(*in), 1, f);
if (count != 1) {
LOGE("Failed writing %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
if (fclose(f) != 0) {
LOGE("Failed closing %s\n(%s)\n", v->device, strerror(errno));
return -1;
}
return 0;
}
/* Update Image
*
* - will be stored in the "cache" partition
@ -130,27 +211,27 @@ int set_bootloader_message(const struct bootloader_message *in) {
* - two raw bitmaps will be included, the "busy" and "fail" bitmaps
* - for dream, the bitmaps will be 320x480x16bpp RGB565
*/
#define UPDATE_MAGIC "MSM-RADIO-UPDATE"
#define UPDATE_MAGIC_SIZE 16
#define UPDATE_VERSION 0x00010000
struct update_header {
unsigned char MAGIC[UPDATE_MAGIC_SIZE];
unsigned version;
unsigned size;
unsigned image_offset;
unsigned image_length;
unsigned bitmap_width;
unsigned bitmap_height;
unsigned bitmap_bpp;
unsigned busy_bitmap_offset;
unsigned busy_bitmap_length;
unsigned fail_bitmap_offset;
unsigned fail_bitmap_length;
};
@ -159,113 +240,113 @@ int write_update_for_bootloader(
const char *update, int update_length,
int bitmap_width, int bitmap_height, int bitmap_bpp,
const char *busy_bitmap, const char *fail_bitmap) {
if (ensure_root_path_unmounted(CACHE_NAME)) {
LOGE("Can't unmount %s\n", CACHE_NAME);
if (ensure_path_unmounted("/cache")) {
LOGE("Can't unmount /cache\n");
return -1;
}
const MtdPartition *part = get_root_mtd_partition(CACHE_NAME);
const MtdPartition *part = mtd_find_partition_by_name("cache");
if (part == NULL) {
LOGE("Can't find %s\n", CACHE_NAME);
LOGE("Can't find cache\n");
return -1;
}
MtdWriteContext *write = mtd_write_partition(part);
if (write == NULL) {
LOGE("Can't open %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Can't open cache\n(%s)\n", strerror(errno));
return -1;
}
/* Write an invalid (zero) header first, to disable any previous
* update and any other structured contents (like a filesystem),
* and as a placeholder for the amount of space required.
*/
struct update_header header;
memset(&header, 0, sizeof(header));
const ssize_t header_size = sizeof(header);
if (mtd_write_data(write, (char*) &header, header_size) != header_size) {
LOGE("Can't write header to %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Can't write header to cache\n(%s)\n", strerror(errno));
mtd_write_close(write);
return -1;
}
/* Write each section individually block-aligned, so we can write
* each block independently without complicated buffering.
*/
memcpy(&header.MAGIC, UPDATE_MAGIC, UPDATE_MAGIC_SIZE);
header.version = UPDATE_VERSION;
header.size = header_size;
off_t image_start_pos = mtd_erase_blocks(write, 0);
header.image_length = update_length;
if ((int) header.image_offset == -1 ||
mtd_write_data(write, update, update_length) != update_length) {
LOGE("Can't write update to %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Can't write update to cache\n(%s)\n", strerror(errno));
mtd_write_close(write);
return -1;
}
off_t busy_start_pos = mtd_erase_blocks(write, 0);
header.image_offset = mtd_find_write_start(write, image_start_pos);
header.bitmap_width = bitmap_width;
header.bitmap_height = bitmap_height;
header.bitmap_bpp = bitmap_bpp;
int bitmap_length = (bitmap_bpp + 7) / 8 * bitmap_width * bitmap_height;
header.busy_bitmap_length = busy_bitmap != NULL ? bitmap_length : 0;
if ((int) header.busy_bitmap_offset == -1 ||
mtd_write_data(write, busy_bitmap, bitmap_length) != bitmap_length) {
LOGE("Can't write bitmap to %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Can't write bitmap to cache\n(%s)\n", strerror(errno));
mtd_write_close(write);
return -1;
}
off_t fail_start_pos = mtd_erase_blocks(write, 0);
header.busy_bitmap_offset = mtd_find_write_start(write, busy_start_pos);
header.fail_bitmap_length = fail_bitmap != NULL ? bitmap_length : 0;
if ((int) header.fail_bitmap_offset == -1 ||
mtd_write_data(write, fail_bitmap, bitmap_length) != bitmap_length) {
LOGE("Can't write bitmap to %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Can't write bitmap to cache\n(%s)\n", strerror(errno));
mtd_write_close(write);
return -1;
}
mtd_erase_blocks(write, 0);
header.fail_bitmap_offset = mtd_find_write_start(write, fail_start_pos);
/* Write the header last, after all the blocks it refers to, so that
* when the magic number is installed everything is valid.
*/
if (mtd_write_close(write)) {
LOGE("Can't finish writing %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Can't finish writing cache\n(%s)\n", strerror(errno));
return -1;
}
write = mtd_write_partition(part);
if (write == NULL) {
LOGE("Can't reopen %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Can't reopen cache\n(%s)\n", strerror(errno));
return -1;
}
if (mtd_write_data(write, (char*) &header, header_size) != header_size) {
LOGE("Can't rewrite header to %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Can't rewrite header to cache\n(%s)\n", strerror(errno));
mtd_write_close(write);
return -1;
}
if (mtd_erase_blocks(write, 0) != image_start_pos) {
LOGE("Misalignment rewriting %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Misalignment rewriting cache\n(%s)\n", strerror(errno));
mtd_write_close(write);
return -1;
}
if (mtd_write_close(write)) {
LOGE("Can't finish header of %s\n(%s)\n", CACHE_NAME, strerror(errno));
LOGE("Can't finish header of cache\n(%s)\n", strerror(errno));
return -1;
}
return 0;
}

1299
commands.c

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef RECOVERY_COMMANDS_H_
#define RECOVERY_COMMANDS_H_
#include "minzip/Zip.h"
typedef struct {
ZipArchive *package;
} RecoveryCommandContext;
int register_update_commands(RecoveryCommandContext *ctx);
#endif // RECOVERY_COMMANDS_H_

View File

@ -26,12 +26,15 @@ void ui_init();
int ui_wait_key(); // waits for a key/button press, returns the code
int ui_key_pressed(int key); // returns >0 if the code is currently pressed
int ui_text_visible(); // returns >0 if text log is currently visible
int ui_text_ever_visible(); // returns >0 if text log was ever visible
void ui_show_text(int visible);
void ui_clear_key_queue();
// Write a message to the on-screen log shown with Alt-L (also to stderr).
// The screen is small, and users may need to report these messages to support,
// so keep the output short and not too cryptic.
void ui_print(const char *fmt, ...);
void ui_print(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
void ui_printlogtail(int nb_lines);
void ui_reset_text_col();
void ui_set_show_text(int value);
@ -39,7 +42,7 @@ void ui_set_show_text(int value);
// Display some header text followed by a menu of items, which appears
// at the top of the screen (in place of any scrolling ui_print()
// output, if necessary).
int ui_start_menu(char** headers, char** items);
int ui_start_menu(char** headers, char** items, int initial_selection);
// Set the menu highlight to the given index, and return it (capped to
// the range [0..numitems).
int ui_menu_select(int sel);
@ -55,6 +58,7 @@ enum {
BACKGROUND_ICON_NONE,
BACKGROUND_ICON_INSTALLING,
BACKGROUND_ICON_ERROR,
BACKGROUND_ICON_CLOCKWORK,
BACKGROUND_ICON_FIRMWARE_INSTALLING,
BACKGROUND_ICON_FIRMWARE_ERROR,
NUM_BACKGROUND_ICONS
@ -85,12 +89,12 @@ void ui_show_indeterminate_progress();
void ui_reset_progress();
#define LOGE(...) ui_print("E:" __VA_ARGS__)
#define LOGW(...) fprintf(stderr, "W:" __VA_ARGS__)
#define LOGI(...) fprintf(stderr, "I:" __VA_ARGS__)
#define LOGW(...) fprintf(stdout, "W:" __VA_ARGS__)
#define LOGI(...) fprintf(stdout, "I:" __VA_ARGS__)
#if 0
#define LOGV(...) fprintf(stderr, "V:" __VA_ARGS__)
#define LOGD(...) fprintf(stderr, "D:" __VA_ARGS__)
#define LOGV(...) fprintf(stdout, "V:" __VA_ARGS__)
#define LOGD(...) fprintf(stdout, "D:" __VA_ARGS__)
#else
#define LOGV(...) do {} while (0)
#define LOGD(...) do {} while (0)
@ -99,4 +103,51 @@ void ui_reset_progress();
#define STRINGIFY(x) #x
#define EXPAND(x) STRINGIFY(x)
typedef struct {
const char* mount_point; // eg. "/cache". must live in the root directory.
const char* fs_type; // "yaffs2" or "ext4" or "vfat"
const char* device; // MTD partition name if fs_type == "yaffs"
// block device if fs_type == "ext4" or "vfat"
const char* device2; // alternative device to try if fs_type
// == "ext4" or "vfat" and mounting
// 'device' fails
long long length; // (ext4 partition only) when
// formatting, size to use for the
// partition. 0 or negative number
// means to format all but the last
// (that much).
const char* fs_type2;
const char* fs_options;
const char* fs_options2;
} Volume;
typedef struct {
// number of frames in indeterminate progress bar animation
int indeterminate_frames;
// number of frames per second to try to maintain when animating
int update_fps;
// number of frames in installing animation. may be zero for a
// static installation icon.
int installing_frames;
// the install icon is animated by drawing images containing the
// changing part over the base icon. These specify the
// coordinates of the upper-left corner.
int install_overlay_offset_x;
int install_overlay_offset_y;
} UIParameters;
// fopen a file, mounting volumes and making parent dirs as necessary.
FILE* fopen_path(const char *path, const char *mode);
#endif // RECOVERY_COMMON_H

68
default_recovery_keys.c Normal file
View File

@ -0,0 +1,68 @@
#include <linux/input.h>
#include "recovery_ui.h"
#include "common.h"
#include "extendedcommands.h"
int device_toggle_display(volatile char* key_pressed, int key_code) {
int alt = key_pressed[KEY_LEFTALT] || key_pressed[KEY_RIGHTALT];
if (alt && key_code == KEY_L)
return 1;
// allow toggling of the display if the correct key is pressed, and the display toggle is allowed or the display is currently off
if (ui_get_showing_back_button()) {
return 0;
//return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_END);
}
return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_POWER || key_code == KEY_END);
}
int device_handle_key(int key_code, int visible) {
if (visible) {
switch (key_code) {
case KEY_CAPSLOCK:
case KEY_DOWN:
case KEY_VOLUMEDOWN:
case KEY_MENU:
return HIGHLIGHT_DOWN;
case KEY_LEFTSHIFT:
case KEY_UP:
case KEY_VOLUMEUP:
case KEY_HOME:
return HIGHLIGHT_UP;
case KEY_POWER:
if (ui_get_showing_back_button()) {
return SELECT_ITEM;
}
if (!get_allow_toggle_display() && ui_menu_level > 0) {
return GO_BACK;
}
break;
case KEY_LEFTBRACE:
case KEY_ENTER:
case BTN_MOUSE:
case KEY_CAMERA:
case KEY_F21:
case KEY_SEND:
return SELECT_ITEM;
case KEY_END:
case KEY_BACKSPACE:
case KEY_SEARCH:
if (ui_get_showing_back_button()) {
return SELECT_ITEM;
}
if (!get_allow_toggle_display() && ui_menu_level > 0) {
return GO_BACK;
}
case KEY_BACK:
if (ui_menu_level > 0) {
return GO_BACK;
}
}
}
return NO_ACTION;
}

View File

@ -23,74 +23,25 @@
char* MENU_HEADERS[] = { NULL };
char* MENU_ITEMS[] = { "reboot system now",
"apply sdcard:update.zip",
"install zip from sdcard",
"wipe data/factory reset",
"wipe cache partition",
"install zip from sdcard",
"backup and restore",
"mounts and storage",
"advanced",
NULL };
void device_ui_init(UIParameters* ui_parameters) {
}
int device_recovery_start() {
return 0;
}
int device_toggle_display(volatile char* key_pressed, int key_code) {
int alt = key_pressed[KEY_LEFTALT] || key_pressed[KEY_RIGHTALT];
if (alt && key_code == KEY_L)
return 1;
// allow toggling of the display if the correct key is pressed, and the display toggle is allowed or the display is currently off
if (ui_get_showing_back_button()) {
return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_END);
}
return get_allow_toggle_display() && (key_code == KEY_HOME || key_code == KEY_MENU || key_code == KEY_POWER || key_code == KEY_END);
}
int device_reboot_now(volatile char* key_pressed, int key_code) {
return 0;
}
int device_handle_key(int key_code, int visible) {
if (visible) {
switch (key_code) {
case KEY_CAPSLOCK:
case KEY_DOWN:
case KEY_VOLUMEDOWN:
return HIGHLIGHT_DOWN;
case KEY_LEFTSHIFT:
case KEY_UP:
case KEY_VOLUMEUP:
return HIGHLIGHT_UP;
case KEY_POWER:
if (ui_get_showing_back_button()) {
return SELECT_ITEM;
}
if (!get_allow_toggle_display())
return GO_BACK;
break;
case KEY_LEFTBRACE:
case KEY_ENTER:
case BTN_MOUSE:
case KEY_CENTER:
case KEY_CAMERA:
case KEY_F21:
case KEY_SEND:
return SELECT_ITEM;
case KEY_END:
case KEY_BACKSPACE:
case KEY_BACK:
if (!get_allow_toggle_display())
return GO_BACK;
}
}
return NO_ACTION;
}
int device_perform_action(int which) {
return which;
}

441
edifyscripting.c Normal file
View File

@ -0,0 +1,441 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/reboot.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/limits.h>
#include <dirent.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/wait.h>
#include "bootloader.h"
#include "common.h"
#include "cutils/properties.h"
#include "firmware.h"
#include "install.h"
#include "minui/minui.h"
#include "minzip/DirUtil.h"
#include "roots.h"
#include "recovery_ui.h"
#include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h"
#include "../../external/yaffs2/yaffs2/utils/unyaffs.h"
#include "extendedcommands.h"
#include "nandroid.h"
#include "mounts.h"
#include "flashutils/flashutils.h"
#include "edify/expr.h"
#include "mtdutils/mtdutils.h"
#include "mmcutils/mmcutils.h"
//#include "edify/parser.h"
Value* UIPrintFn(const char* name, State* state, int argc, Expr* argv[]) {
char** args = ReadVarArgs(state, argc, argv);
if (args == NULL) {
return NULL;
}
int size = 0;
int i;
for (i = 0; i < argc; ++i) {
size += strlen(args[i]);
}
char* buffer = malloc(size+1);
size = 0;
for (i = 0; i < argc; ++i) {
strcpy(buffer+size, args[i]);
size += strlen(args[i]);
free(args[i]);
}
free(args);
buffer[size] = '\0';
char* line = strtok(buffer, "\n");
while (line) {
ui_print("%s\n", line);
line = strtok(NULL, "\n");
}
return StringValue(buffer);
}
Value* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) {
if (argc < 1) {
return ErrorAbort(state, "%s() expects at least 1 arg", name);
}
char** args = ReadVarArgs(state, argc, argv);
if (args == NULL) {
return NULL;
}
char** args2 = malloc(sizeof(char*) * (argc+1));
memcpy(args2, args, sizeof(char*) * argc);
args2[argc] = NULL;
fprintf(stderr, "about to run program [%s] with %d args\n", args2[0], argc);
pid_t child = fork();
if (child == 0) {
execv(args2[0], args2);
fprintf(stderr, "run_program: execv failed: %s\n", strerror(errno));
_exit(1);
}
int status;
waitpid(child, &status, 0);
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0) {
fprintf(stderr, "run_program: child exited with status %d\n",
WEXITSTATUS(status));
}
} else if (WIFSIGNALED(status)) {
fprintf(stderr, "run_program: child terminated by signal %d\n",
WTERMSIG(status));
}
int i;
for (i = 0; i < argc; ++i) {
free(args[i]);
}
free(args);
free(args2);
char buffer[20];
sprintf(buffer, "%d", status);
return StringValue(strdup(buffer));
}
Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) {
char* result = NULL;
if (argc != 1) {
return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc);
}
char *path;
if (ReadArgs(state, argv, 1, &path) < 0) {
return NULL;
}
ui_print("Formatting %s...\n", path);
if (0 != format_volume(path)) {
free(path);
return StringValue(strdup(""));
}
if (strcmp(path, "/data") == 0 && has_datadata()) {
ui_print("Formatting /datadata...\n", path);
if (0 != format_volume("/datadata")) {
free(path);
return StringValue(strdup(""));
}
if (0 != format_volume("/sdcard/.android_secure")) {
free(path);
return StringValue(strdup(""));
}
}
done:
return StringValue(strdup(path));
}
Value* BackupFn(const char* name, State* state, int argc, Expr* argv[]) {
char* result = NULL;
if (argc != 1) {
return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
}
char* path;
if (ReadArgs(state, argv, 1, &path) < 0) {
return NULL;
}
if (0 != nandroid_backup(path))
return StringValue(strdup(""));
return StringValue(strdup(path));
}
Value* RestoreFn(const char* name, State* state, int argc, Expr* argv[]) {
if (argc < 1) {
return ErrorAbort(state, "%s() expects at least 1 arg", name);
}
char** args = ReadVarArgs(state, argc, argv);
if (args == NULL) {
return NULL;
}
char** args2 = malloc(sizeof(char*) * (argc+1));
memcpy(args2, args, sizeof(char*) * argc);
args2[argc] = NULL;
char* path = strdup(args2[0]);
int restoreboot = 1;
int restoresystem = 1;
int restoredata = 1;
int restorecache = 1;
int restoresdext = 1;
int i;
for (i = 1; i < argc; i++)
{
if (args2[i] == NULL)
continue;
if (strcmp(args2[i], "noboot") == 0)
restoreboot = 0;
else if (strcmp(args2[i], "nosystem") == 0)
restoresystem = 0;
else if (strcmp(args2[i], "nodata") == 0)
restoredata = 0;
else if (strcmp(args2[i], "nocache") == 0)
restorecache = 0;
else if (strcmp(args2[i], "nosd-ext") == 0)
restoresdext = 0;
}
for (i = 0; i < argc; ++i) {
free(args[i]);
}
free(args);
free(args2);
if (0 != nandroid_restore(path, restoreboot, restoresystem, restoredata, restorecache, restoresdext, 0)) {
free(path);
return StringValue(strdup(""));
}
return StringValue(path);
}
Value* InstallZipFn(const char* name, State* state, int argc, Expr* argv[]) {
char* result = NULL;
if (argc != 1) {
return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
}
char* path;
if (ReadArgs(state, argv, 1, &path) < 0) {
return NULL;
}
if (0 != install_zip(path))
return StringValue(strdup(""));
return StringValue(strdup(path));
}
Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) {
char* result = NULL;
if (argc != 1) {
return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
}
char* path;
if (ReadArgs(state, argv, 1, &path) < 0) {
return NULL;
}
if (0 != ensure_path_mounted(path))
return StringValue(strdup(""));
return StringValue(strdup(path));
}
void RegisterRecoveryHooks() {
RegisterFunction("mount", MountFn);
RegisterFunction("format", FormatFn);
RegisterFunction("ui_print", UIPrintFn);
RegisterFunction("run_program", RunProgramFn);
RegisterFunction("backup_rom", BackupFn);
RegisterFunction("restore_rom", RestoreFn);
RegisterFunction("install_zip", InstallZipFn);
}
static int hasInitializedEdify = 0;
int run_script_from_buffer(char* script_data, int script_len, char* filename)
{
if (!hasInitializedEdify) {
RegisterBuiltins();
RegisterRecoveryHooks();
FinishRegistration();
hasInitializedEdify = 1;
}
Expr* root;
int error_count = 0;
yy_scan_bytes(script_data, script_len);
int error = yyparse(&root, &error_count);
printf("parse returned %d; %d errors encountered\n", error, error_count);
if (error == 0 || error_count > 0) {
//ExprDump(0, root, buffer);
State state;
state.cookie = NULL;
state.script = script_data;
state.errmsg = NULL;
char* result = Evaluate(&state, root);
if (result == NULL) {
printf("result was NULL, message is: %s\n",
(state.errmsg == NULL ? "(NULL)" : state.errmsg));
free(state.errmsg);
return -1;
} else {
printf("result is [%s]\n", result);
}
}
return 0;
}
#define EXTENDEDCOMMAND_SCRIPT "/cache/recovery/extendedcommand"
int run_and_remove_extendedcommand()
{
char tmp[PATH_MAX];
sprintf(tmp, "cp %s /tmp/%s", EXTENDEDCOMMAND_SCRIPT, basename(EXTENDEDCOMMAND_SCRIPT));
__system(tmp);
remove(EXTENDEDCOMMAND_SCRIPT);
int i = 0;
for (i = 20; i > 0; i--) {
ui_print("Waiting for SD Card to mount (%ds)\n", i);
if (ensure_path_mounted("/sdcard") == 0) {
ui_print("SD Card mounted...\n");
break;
}
sleep(1);
}
remove("/sdcard/clockworkmod/.recoverycheckpoint");
if (i == 0) {
ui_print("Timed out waiting for SD card... continuing anyways.");
}
ui_print("Verifying SD Card marker...\n");
struct stat st;
if (stat("/sdcard/clockworkmod/.salted_hash", &st) != 0) {
ui_print("SD Card marker not found...\n");
if (volume_for_path("/emmc") != NULL) {
ui_print("Checking Internal SD Card marker...\n");
ensure_path_unmounted("/sdcard");
if (ensure_path_mounted_at_mount_point("/emmc", "/sdcard") != 0) {
ui_print("Internal SD Card marker not found... continuing anyways.\n");
// unmount everything, and remount as normal
ensure_path_unmounted("/emmc");
ensure_path_unmounted("/sdcard");
ensure_path_mounted("/sdcard");
}
}
}
sprintf(tmp, "/tmp/%s", basename(EXTENDEDCOMMAND_SCRIPT));
int ret;
#ifdef I_AM_KOUSH
if (0 != (ret = before_run_script(tmp))) {
ui_print("Error processing ROM Manager script. Please verify that you are performing the backup, restore, or ROM installation from ROM Manager v4.4.0.0 or higher.\n");
return ret;
}
#endif
return run_script(tmp);
}
int extendedcommand_file_exists()
{
struct stat file_info;
return 0 == stat(EXTENDEDCOMMAND_SCRIPT, &file_info);
}
int edify_main(int argc, char** argv) {
load_volume_table();
process_volumes();
RegisterBuiltins();
RegisterRecoveryHooks();
FinishRegistration();
if (argc != 2) {
printf("edify <filename>\n");
return 1;
}
FILE* f = fopen(argv[1], "r");
if (f == NULL) {
printf("%s: %s: No such file or directory\n", argv[0], argv[1]);
return 1;
}
char buffer[8192];
int size = fread(buffer, 1, 8191, f);
fclose(f);
buffer[size] = '\0';
Expr* root;
int error_count = 0;
yy_scan_bytes(buffer, size);
int error = yyparse(&root, &error_count);
printf("parse returned %d; %d errors encountered\n", error, error_count);
if (error == 0 || error_count > 0) {
//ExprDump(0, root, buffer);
State state;
state.cookie = NULL;
state.script = buffer;
state.errmsg = NULL;
char* result = Evaluate(&state, root);
if (result == NULL) {
printf("result was NULL, message is: %s\n",
(state.errmsg == NULL ? "(NULL)" : state.errmsg));
free(state.errmsg);
} else {
printf("result is [%s]\n", result);
}
}
return 0;
}
int run_script(char* filename)
{
struct stat file_info;
if (0 != stat(filename, &file_info)) {
printf("Error executing stat on file: %s\n", filename);
return 1;
}
int script_len = file_info.st_size;
char* script_data = (char*)malloc(script_len + 1);
FILE *file = fopen(filename, "rb");
fread(script_data, script_len, 1, file);
// supposedly not necessary, but let's be safe.
script_data[script_len] = '\0';
fclose(file);
LOGI("Running script:\n");
LOGI("\n%s\n", script_data);
int ret = run_script_from_buffer(script_data, script_len, filename);
free(script_data);
return ret;
}

View File

@ -1,3 +1,5 @@
on early-init
start ueventd
on init
export PATH /sbin
@ -7,7 +9,10 @@ on init
symlink /system/etc /etc
mkdir /boot
mkdir /sdcard
mkdir /sd-ext
mkdir /datadata
mkdir /emmc
mkdir /system
mkdir /data
@ -22,13 +27,30 @@ on boot
class_start default
service ueventd /sbin/ueventd
critical
service recovery /sbin/recovery
service adbd /sbin/adbd recovery
disabled
on property:persist.service.adb.enable=1
start adbd
# Always start adbd on userdebug and eng builds
# In recovery, always run adbd as root.
on property:ro.debuggable=1
write /sys/class/android_usb/android0/enable 0
write /sys/class/android_usb/android0/idVendor 18D1
write /sys/class/android_usb/android0/idProduct D001
write /sys/class/android_usb/android0/functions adb
#write /sys/class/android_usb/android0/enable 1
write /sys/class/android_usb/android0/iManufacturer $ro.product.manufacturer
write /sys/class/android_usb/android0/iProduct $ro.product.model
write /sys/class/android_usb/android0/iSerial $ro.serialno
#start adbd
setprop service.adb.root 1
on property:persist.service.adb.enable=0
stop adbd
# Restart adbd so it can run as root
on property:service.adb.root=1
write /sys/class/android_usb/android0/enable 0
restart adbd
write /sys/class/android_usb/android0/enable 1

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,10 @@ int
do_nandroid_restore();
void
show_nandroid_restore_menu();
show_nandroid_restore_menu(const char* path);
void
show_nandroid_advanced_restore_menu(const char* path);
void
show_nandroid_menu();
@ -37,10 +40,23 @@ __system(const char *command);
void
show_advanced_menu();
int
format_unknown_device(const char* root);
int format_unknown_device(const char *device, const char* path, const char *fs_type);
void
wipe_battery_stats();
void create_fstab();
int has_datadata();
void handle_failure(int ret);
void process_volumes();
int extendedcommand_file_exists();
void show_install_update_menu();
int confirm_selection(const char* title, const char* confirm);
int run_and_remove_extendedcommand();

View File

@ -106,7 +106,7 @@ int maybe_install_firmware_update(const char *send_intent) {
update_data, update_length,
width, height, bpp, busy_image, fail_image)) {
LOGE("Can't write %s image\n(%s)\n", update_type, strerror(errno));
format_root_device("CACHE:"); // Attempt to clean cache up, at least.
format_volume("/cache"); // Attempt to clean cache up, at least.
return -1;
}
@ -119,7 +119,7 @@ int maybe_install_firmware_update(const char *send_intent) {
*/
snprintf(boot.command, sizeof(boot.command), "update-%s", update_type);
if (set_bootloader_message(&boot)) {
format_root_device("CACHE:");
format_volume("/cache");
return -1;
}

View File

@ -6,57 +6,71 @@ ifeq ($(TARGET_ARCH),arm)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := flashutils.c
LOCAL_MODULE := libflashutils
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES += bootable/recovery
LOCAL_STATIC_LIBRARIES := libmmcutils libmtdutils libbmlutils
LOCAL_STATIC_LIBRARIES := libmmcutils libmtdutils libbmlutils libcrecovery
BOARD_RECOVERY_DEFINES := BOARD_BML_BOOT BOARD_BML_RECOVERY
$(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
$(if $($(board_define)), \
$(eval LOCAL_CFLAGS += -D$(board_define)=\"$($(board_define))\") \
) \
)
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := flash_image.c
LOCAL_MODULE := flash_image
LOCAL_MODULE_TAGS := eng
#LOCAL_STATIC_LIBRARIES += $(BOARD_FLASH_LIBRARY)
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils libcrecovery
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := dump_image.c
LOCAL_MODULE := dump_image
LOCAL_MODULE_TAGS := eng
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils libcrecovery
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := erase_image.c
LOCAL_MODULE := erase_image
LOCAL_MODULE_TAGS := eng
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES := libflashutils libmtdutils libmmcutils libbmlutils libcrecovery
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
ALL_DEFAULT_INSTALLED_MODULES += $(addprefix $(TARGET_OUT)/bin/, flash_image dump_image erase_image)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := flash_image.c
LOCAL_MODULE := libflash_image
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS += -Dmain=flash_image_main
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := dump_image.c
LOCAL_MODULE := libdump_image
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS += -Dmain=dump_image_main
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := erase_image.c
LOCAL_MODULE := liberase_image
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS += -Dmain=erase_image_main
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := dump_image.c
LOCAL_MODULE := utility_dump_image
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
@ -68,6 +82,7 @@ include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := flash_image.c
LOCAL_MODULE := utility_flash_image
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities
@ -79,6 +94,7 @@ include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := erase_image.c
LOCAL_MODULE := utility_erase_image
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities
LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities

View File

@ -146,5 +146,5 @@ int main(int argc, char **argv)
return 2;
}
return backup_raw_partition(argv[1], argv[2]);
return backup_raw_partition(NULL, argv[1], argv[2]);
}

View File

@ -99,5 +99,5 @@ int main(int argc, char **argv)
return 2;
}
return erase_raw_partition(argv[1]);
return erase_raw_partition(NULL, argv[1]);
}

View File

@ -22,6 +22,7 @@
#include <unistd.h>
#include "cutils/log.h"
#include "flashutils.h"
#if 0
#define LOG_TAG "flash_image"
@ -83,8 +84,8 @@ int main(int argc, char **argv) {
LOGW("error reading %s: %s\n", argv[1], strerror(errno));
// just assume it needs re-writing
} else if (checklen == headerlen && !memcmp(header, check, headerlen)) {
LOGI("header is the same, not flashing %s\n", argv[1]);
return 0;
LOGI("header is the same, flashing %s anyway\n", argv[1]);
//return 0;
}
mtd_read_close(in);
}
@ -147,7 +148,7 @@ int main(int argc, char **argv)
return 2;
}
int ret = restore_raw_partition(argv[1], argv[2]);
int ret = restore_raw_partition(NULL, argv[1], argv[2]);
if (ret != 0)
fprintf(stderr, "failed with error: %d\n", ret);
return ret;

View File

@ -2,15 +2,24 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include "flashutils/flashutils.h"
#ifndef BOARD_BML_BOOT
#define BOARD_BML_BOOT "/dev/block/bml7"
#endif
#ifndef BOARD_BML_RECOVERY
#define BOARD_BML_RECOVERY "/dev/block/bml8"
#endif
int the_flash_type = UNKNOWN;
int device_flash_type()
{
if (the_flash_type == UNKNOWN) {
if (access("/dev/block/bml1", F_OK) == 0) {
if (access(BOARD_BML_BOOT, F_OK) == 0) {
the_flash_type = BML;
} else if (access("/proc/emmc", F_OK) == 0) {
the_flash_type = MMC;
@ -28,50 +37,36 @@ char* get_default_filesystem()
return device_flash_type() == MMC ? "ext3" : "yaffs2";
}
// This was pulled from bionic: The default system command always looks
// for shell in /system/bin/sh. This is bad.
#define _PATH_BSHELL "/sbin/sh"
extern char **environ;
int
__system(const char *command)
{
pid_t pid;
sig_t intsave, quitsave;
sigset_t mask, omask;
int pstat;
char *argp[] = {"sh", "-c", NULL, NULL};
if (!command) /* just checking... */
return(1);
argp[2] = (char *)command;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
sigprocmask(SIG_BLOCK, &mask, &omask);
switch (pid = vfork()) {
case -1: /* error */
sigprocmask(SIG_SETMASK, &omask, NULL);
return(-1);
case 0: /* child */
sigprocmask(SIG_SETMASK, &omask, NULL);
execve(_PATH_BSHELL, argp, environ);
_exit(127);
}
intsave = (sig_t) bsd_signal(SIGINT, SIG_IGN);
quitsave = (sig_t) bsd_signal(SIGQUIT, SIG_IGN);
pid = waitpid(pid, (int *)&pstat, 0);
sigprocmask(SIG_SETMASK, &omask, NULL);
(void)bsd_signal(SIGINT, intsave);
(void)bsd_signal(SIGQUIT, quitsave);
return (pid == -1 ? -1 : pstat);
int get_flash_type(const char* partitionType) {
int type = UNSUPPORTED;
if (strcmp(partitionType, "mtd") == 0)
type = MTD;
else if (strcmp(partitionType, "emmc") == 0)
type = MMC;
else if (strcmp(partitionType, "bml") == 0)
type = BML;
return type;
}
int restore_raw_partition(const char *partition, const char *filename)
static int detect_partition(const char *partitionType, const char *partition)
{
int type = device_flash_type();
if (strstr(partition, "/dev/block/mtd") != NULL)
type = MTD;
else if (strstr(partition, "/dev/block/mmc") != NULL)
type = MMC;
else if (strstr(partition, "/dev/block/bml") != NULL)
type = BML;
if (partitionType != NULL) {
type = get_flash_type(partitionType);
}
return type;
}
int restore_raw_partition(const char* partitionType, const char *partition, const char *filename)
{
int type = detect_partition(partitionType, partition);
switch (type) {
case MTD:
return cmd_mtd_restore_raw_partition(partition, filename);
@ -84,9 +79,9 @@ int restore_raw_partition(const char *partition, const char *filename)
}
}
int backup_raw_partition(const char *partition, const char *filename)
int backup_raw_partition(const char* partitionType, const char *partition, const char *filename)
{
int type = device_flash_type();
int type = detect_partition(partitionType, partition);
switch (type) {
case MTD:
return cmd_mtd_backup_raw_partition(partition, filename);
@ -95,13 +90,14 @@ int backup_raw_partition(const char *partition, const char *filename)
case BML:
return cmd_bml_backup_raw_partition(partition, filename);
default:
printf("unable to detect device type");
return -1;
}
}
int erase_raw_partition(const char *partition)
int erase_raw_partition(const char* partitionType, const char *partition)
{
int type = device_flash_type();
int type = detect_partition(partitionType, partition);
switch (type) {
case MTD:
return cmd_mtd_erase_raw_partition(partition);
@ -116,7 +112,7 @@ int erase_raw_partition(const char *partition)
int erase_partition(const char *partition, const char *filesystem)
{
int type = device_flash_type();
int type = detect_partition(NULL, partition);
switch (type) {
case MTD:
return cmd_mtd_erase_partition(partition, filesystem);
@ -131,7 +127,7 @@ int erase_partition(const char *partition, const char *filesystem)
int mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only)
{
int type = device_flash_type();
int type = detect_partition(NULL, partition);
switch (type) {
case MTD:
return cmd_mtd_mount_partition(partition, mount_point, filesystem, read_only);

View File

@ -1,9 +1,9 @@
#ifndef FLASHUTILS_H
#define FLASHUTILS_H
int restore_raw_partition(const char *partition, const char *filename);
int backup_raw_partition(const char *partition, const char *filename);
int erase_raw_partition(const char *partition);
int restore_raw_partition(const char* partitionType, const char *partition, const char *filename);
int backup_raw_partition(const char* partitionType, const char *partition, const char *filename);
int erase_raw_partition(const char* partitionType, const char *partition);
int erase_partition(const char *partition, const char *filesystem);
int mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only);
int get_partition_device(const char *partition, char *device);
@ -15,8 +15,6 @@ int get_partition_device(const char *partition, char *device);
int is_mtd_device();
char* get_default_filesystem();
int __system(const char *command);
extern int cmd_mtd_restore_raw_partition(const char *partition, const char *filename);
extern int cmd_mtd_backup_raw_partition(const char *partition, const char *filename);
extern int cmd_mtd_erase_raw_partition(const char *partition);
@ -39,6 +37,7 @@ extern int cmd_bml_mount_partition(const char *partition, const char *mount_poin
extern int cmd_bml_get_partition_device(const char *partition, char *device);
extern int device_flash_type();
extern int get_flash_type(const char* fs_type);
enum flash_type {
UNSUPPORTED = -1,

102
install.c
View File

@ -34,12 +34,12 @@
#include "verifier.h"
#include "firmware.h"
#include "legacy.h"
#include "extendedcommands.h"
#define ASSUMED_UPDATE_BINARY_NAME "META-INF/com/google/android/update-binary"
#define ASSUMED_UPDATE_SCRIPT_NAME "META-INF/com/google/android/update-script"
#define PUBLIC_KEYS_FILE "/res/keys"
// The update binary ask us to install a firmware file on reboot. Set
@ -92,24 +92,36 @@ handle_firmware_update(char* type, char* filename, ZipArchive* zip) {
fclose(f);
}
#ifndef BOARD_HAS_NO_MISC_PARTITION
if (remember_firmware_update(type, data, data_size)) {
LOGE("Can't store %s image\n", type);
free(data);
return INSTALL_ERROR;
}
#endif
free(filename);
return INSTALL_SUCCESS;
}
static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install";
// If the package contains an update binary, extract it and run it.
static int
try_update_binary(const char *path, ZipArchive *zip) {
const ZipEntry* binary_entry =
mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
if (binary_entry == NULL) {
const ZipEntry* update_script_entry =
mzFindZipEntry(zip, ASSUMED_UPDATE_SCRIPT_NAME);
if (update_script_entry != NULL) {
ui_print("Amend scripting (update-script) is no longer supported.\n");
ui_print("Amend scripting was deprecated by Google in Android 1.5.\n");
ui_print("It was necessary to remove it when upgrading to the ClockworkMod 3.0 Gingerbread based recovery.\n");
ui_print("Please switch to Edify scripting (updater-script and update-binary) to create working update zip packages.\n");
return INSTALL_UPDATE_BINARY_MISSING;
}
mzCloseZipArchive(zip);
return INSTALL_UPDATE_BINARY_MISSING;
}
@ -117,6 +129,7 @@ try_update_binary(const char *path, ZipArchive *zip) {
unlink(binary);
int fd = creat(binary, 0755);
if (fd < 0) {
mzCloseZipArchive(zip);
LOGE("Can't make %s\n", binary);
return 1;
}
@ -125,6 +138,7 @@ try_update_binary(const char *path, ZipArchive *zip) {
if (!ok) {
LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME);
mzCloseZipArchive(zip);
return 1;
}
@ -175,9 +189,10 @@ try_update_binary(const char *path, ZipArchive *zip) {
pid_t pid = fork();
if (pid == 0) {
setenv("UPDATE_PACKAGE", path, 1);
close(pipefd[0]);
execv(binary, args);
fprintf(stderr, "E:Can't run %s (%s)\n", binary, strerror(errno));
fprintf(stdout, "E:Can't run %s (%s)\n", binary, strerror(errno));
_exit(-1);
}
close(pipefd[1]);
@ -219,7 +234,7 @@ try_update_binary(const char *path, ZipArchive *zip) {
} else if (strcmp(command, "ui_print") == 0) {
char* str = strtok(NULL, "\n");
if (str) {
ui_print(str);
ui_print("%s", str);
} else {
ui_print("\n");
}
@ -233,45 +248,18 @@ try_update_binary(const char *path, ZipArchive *zip) {
waitpid(pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status));
mzCloseZipArchive(zip);
return INSTALL_ERROR;
}
if (firmware_type != NULL) {
return handle_firmware_update(firmware_type, firmware_filename, zip);
} else {
return INSTALL_SUCCESS;
int ret = handle_firmware_update(firmware_type, firmware_filename, zip);
mzCloseZipArchive(zip);
return ret;
}
return INSTALL_SUCCESS;
}
static int
handle_update_package(const char *path, ZipArchive *zip)
{
// Update should take the rest of the progress bar.
ui_print("Installing update...\n");
LOGI("Trying update-binary.\n");
int result = try_update_binary(path, zip);
if (result == INSTALL_UPDATE_BINARY_MISSING)
{
register_package_root(NULL, NULL); // Unregister package root
if (register_package_root(zip, path) < 0) {
LOGE("Can't register package root\n");
return INSTALL_ERROR;
}
const ZipEntry *script_entry;
script_entry = find_update_script(zip);
LOGI("Trying update-script.\n");
result = handle_update_script(zip, script_entry);
if (result == INSTALL_UPDATE_SCRIPT_MISSING)
result = INSTALL_ERROR;
}
register_package_root(NULL, NULL); // Unregister package root
return result;
}
// Reads a file containing one or more public keys as produced by
// DumpPublicKey: this is an RSAPublicKey struct as it would appear
// as a C source literal, eg:
@ -346,27 +334,20 @@ exit:
return NULL;
}
int
install_package(const char *root_path)
static int
really_install_package(const char *path)
{
ui_set_background(BACKGROUND_ICON_INSTALLING);
ui_print("Finding update package...\n");
ui_show_indeterminate_progress();
LOGI("Update location: %s\n", root_path);
LOGI("Update location: %s\n", path);
if (ensure_root_path_mounted(root_path) != 0) {
LOGE("Can't mount %s\n", root_path);
return INSTALL_CORRUPT;
}
char path[PATH_MAX] = "";
if (translate_root_path(root_path, path, sizeof(path)) == NULL) {
LOGE("Bad path %s\n", root_path);
if (ensure_path_mounted(path) != 0) {
LOGE("Can't mount %s\n", path);
return INSTALL_CORRUPT;
}
ui_print("Opening update package...\n");
LOGI("Update file path: %s\n", path);
int err;
@ -405,7 +386,26 @@ install_package(const char *root_path)
/* Verify and install the contents of the package.
*/
int status = handle_update_package(path, &zip);
mzCloseZipArchive(&zip);
return status;
ui_print("Installing update...\n");
return try_update_binary(path, &zip);
}
int
install_package(const char* path)
{
FILE* install_log = fopen_path(LAST_INSTALL_FILE, "w");
if (install_log) {
fputs(path, install_log);
fputc('\n', install_log);
} else {
LOGE("failed to open last_install: %s\n", strerror(errno));
}
int result = really_install_package(path);
if (install_log) {
fputc(result == INSTALL_SUCCESS ? '1' : '0', install_log);
fputc('\n', install_log);
fclose(install_log);
chmod(LAST_INSTALL_FILE, 0644);
}
return result;
}

123
legacy.c
View File

@ -1,123 +0,0 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include "common.h"
#include "install.h"
#include "mincrypt/rsa.h"
#include "minui/minui.h"
#include "minzip/SysUtil.h"
#include "minzip/Zip.h"
#include "mtdutils/mtdutils.h"
#include "roots.h"
#include "verifier.h"
#include "firmware.h"
#include "amend/amend.h"
#include "common.h"
#include "install.h"
#include "mincrypt/rsa.h"
#include "minui/minui.h"
#include "minzip/SysUtil.h"
#include "minzip/Zip.h"
#include "mounts.h"
#include "mtdutils/mtdutils.h"
#include "roots.h"
#include "verifier.h"
static int read_data(ZipArchive *zip, const ZipEntry *entry,
char** ppData, int* pLength) {
int len = (int)mzGetZipEntryUncompLen(entry);
if (len <= 0) {
LOGE("Bad data length %d\n", len);
return -1;
}
char *data = malloc(len + 1);
if (data == NULL) {
LOGE("Can't allocate %d bytes for data\n", len + 1);
return -2;
}
bool ok = mzReadZipEntry(zip, entry, data, len);
if (!ok) {
LOGE("Error while reading data\n");
free(data);
return -3;
}
data[len] = '\0'; // not necessary, but just to be safe
*ppData = data;
if (pLength) {
*pLength = len;
}
return 0;
}
int
handle_update_script(ZipArchive *zip, const ZipEntry *update_script_entry)
{
/* Read the entire script into a buffer.
*/
int script_len;
char* script_data;
if (read_data(zip, update_script_entry, &script_data, &script_len) < 0) {
LOGE("Can't read update script\n");
return INSTALL_UPDATE_SCRIPT_MISSING;
}
/* Parse the script. Note that the script and parse tree are never freed.
*/
const AmCommandList *commands = parseAmendScript(script_data, script_len);
if (commands == NULL) {
LOGE("Syntax error in update script\n");
return INSTALL_ERROR;
} else {
UnterminatedString name = mzGetZipEntryFileName(update_script_entry);
LOGI("Parsed %.*s\n", name.len, name.str);
}
/* Execute the script.
*/
int ret = execCommandList((ExecContext *)1, commands);
if (ret != 0) {
int num = ret;
char *line, *next = script_data;
while (next != NULL && ret-- > 0) {
line = next;
next = memchr(line, '\n', script_data + script_len - line);
if (next != NULL) *next++ = '\0';
}
LOGE("Failure at line %d:\n%s\n", num, next ? line : "(not found)");
return INSTALL_ERROR;
}
ui_print("Installation complete.\n");
return INSTALL_SUCCESS;
}
#define ASSUMED_UPDATE_SCRIPT_NAME "META-INF/com/google/android/update-script"
const ZipEntry *
find_update_script(ZipArchive *zip)
{
//TODO: Get the location of this script from the MANIFEST.MF file
return mzFindZipEntry(zip, ASSUMED_UPDATE_SCRIPT_NAME);
}

View File

@ -1,5 +0,0 @@
int
handle_update_script(ZipArchive *zip, const ZipEntry *update_script_entry);
const ZipEntry *
find_update_script(ZipArchive *zip);

13
libcrecovery/Android.mk Normal file
View File

@ -0,0 +1,13 @@
LOCAL_PATH := $(call my-dir)
ifneq ($(TARGET_SIMULATOR),true)
ifeq ($(TARGET_ARCH),arm)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := system.c popen.c
LOCAL_MODULE := libcrecovery
LOCAL_MODULE_TAGS := eng
include $(BUILD_STATIC_LIBRARY)
endif
endif

10
libcrecovery/common.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef LIBCRECOVERY_COMMON_H
#define LIBCRECOVERY_COMMON_H
#include <stdio.h>
int __system(const char *command);
FILE * __popen(const char *program, const char *type);
int __pclose(FILE *iop);
#endif

2
libcrecovery/defines.h Normal file
View File

@ -0,0 +1,2 @@
#undef _PATH_BSHELL
#define _PATH_BSHELL "/sbin/sh"

169
libcrecovery/popen.c Normal file
View File

@ -0,0 +1,169 @@
/* $OpenBSD: popen.c,v 1.17 2005/08/08 08:05:34 espie Exp $ */
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software written by Ken Arnold and
* published in UNIX Review, Vol. 6, No. 8.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>
#include "defines.h"
static struct pid {
struct pid *next;
FILE *fp;
pid_t pid;
} *pidlist;
FILE *
__popen(const char *program, const char *type)
{
struct pid * volatile cur;
FILE *iop;
int pdes[2];
pid_t pid;
if ((*type != 'r' && *type != 'w') || type[1] != '\0') {
errno = EINVAL;
return (NULL);
}
if ((cur = malloc(sizeof(struct pid))) == NULL)
return (NULL);
if (pipe(pdes) < 0) {
free(cur);
return (NULL);
}
switch (pid = vfork()) {
case -1: /* Error. */
(void)close(pdes[0]);
(void)close(pdes[1]);
free(cur);
return (NULL);
/* NOTREACHED */
case 0: /* Child. */
{
struct pid *pcur;
/*
* because vfork() instead of fork(), must leak FILE *,
* but luckily we are terminally headed for an execl()
*/
for (pcur = pidlist; pcur; pcur = pcur->next)
close(fileno(pcur->fp));
if (*type == 'r') {
int tpdes1 = pdes[1];
(void) close(pdes[0]);
/*
* We must NOT modify pdes, due to the
* semantics of vfork.
*/
if (tpdes1 != STDOUT_FILENO) {
(void)dup2(tpdes1, STDOUT_FILENO);
(void)close(tpdes1);
tpdes1 = STDOUT_FILENO;
}
} else {
(void)close(pdes[1]);
if (pdes[0] != STDIN_FILENO) {
(void)dup2(pdes[0], STDIN_FILENO);
(void)close(pdes[0]);
}
}
execl(_PATH_BSHELL, "sh", "-c", program, (char *)NULL);
_exit(127);
/* NOTREACHED */
}
}
/* Parent; assume fdopen can't fail. */
if (*type == 'r') {
iop = fdopen(pdes[0], type);
(void)close(pdes[1]);
} else {
iop = fdopen(pdes[1], type);
(void)close(pdes[0]);
}
/* Link into list of file descriptors. */
cur->fp = iop;
cur->pid = pid;
cur->next = pidlist;
pidlist = cur;
return (iop);
}
/*
* pclose --
* Pclose returns -1 if stream is not associated with a `popened' command,
* if already `pclosed', or waitpid returns an error.
*/
int
__pclose(FILE *iop)
{
struct pid *cur, *last;
int pstat;
pid_t pid;
/* Find the appropriate file pointer. */
for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
if (cur->fp == iop)
break;
if (cur == NULL)
return (-1);
(void)fclose(iop);
do {
pid = waitpid(cur->pid, &pstat, 0);
} while (pid == -1 && errno == EINTR);
/* Remove the entry from the linked list. */
if (last == NULL)
pidlist = cur->next;
else
last->next = cur->next;
free(cur);
return (pid == -1 ? -1 : pstat);
}

76
libcrecovery/system.c Normal file
View File

@ -0,0 +1,76 @@
/* $OpenBSD: system.c,v 1.8 2005/08/08 08:05:37 espie Exp $ */
/*
* Copyright (c) 1988 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <paths.h>
#include <sys/wait.h>
#include "defines.h"
extern char **environ;
int
__system(const char *command)
{
pid_t pid;
sig_t intsave, quitsave;
sigset_t mask, omask;
int pstat;
char *argp[] = {"sh", "-c", NULL, NULL};
if (!command) /* just checking... */
return(1);
argp[2] = (char *)command;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
sigprocmask(SIG_BLOCK, &mask, &omask);
switch (pid = vfork()) {
case -1: /* error */
sigprocmask(SIG_SETMASK, &omask, NULL);
return(-1);
case 0: /* child */
sigprocmask(SIG_SETMASK, &omask, NULL);
execve(_PATH_BSHELL, argp, environ);
_exit(127);
}
intsave = (sig_t) bsd_signal(SIGINT, SIG_IGN);
quitsave = (sig_t) bsd_signal(SIGQUIT, SIG_IGN);
pid = waitpid(pid, (int *)&pstat, 0);
sigprocmask(SIG_SETMASK, &omask, NULL);
(void)bsd_signal(SIGINT, intsave);
(void)bsd_signal(SIGQUIT, quitsave);
return (pid == -1 ? -1 : pstat);
}

102
make-overlay.py Normal file
View File

@ -0,0 +1,102 @@
# Copyright (C) 2011 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Script to take a set of frames (PNG files) for a recovery
"installing" icon animation and turn it into a base image plus a set
of overlays, as needed by the recovery UI code. Run with the names of
all the input frames on the command line, in order."""
import sys
try:
import Image
except ImportError:
print "This script requires the Python Imaging Library to be installed."
sys.exit(1)
# Find the smallest box that contains all the pixels which change
# between images.
print "reading", sys.argv[1]
base = Image.open(sys.argv[1])
minmini = base.size[0]-1
maxmaxi = 0
minminj = base.size[1]-1
maxmaxj = 0
for top_name in sys.argv[2:]:
print "reading", top_name
top = Image.open(top_name)
assert base.size == top.size
mini = base.size[0]-1
maxi = 0
minj = base.size[1]-1
maxj = 0
h, w = base.size
for j in range(w):
for i in range(h):
b = base.getpixel((i,j))
t = top.getpixel((i,j))
if b != t:
if i < mini: mini = i
if i > maxi: maxi = i
if j < minj: minj = j
if j > maxj: maxj = j
minmini = min(minmini, mini)
maxmaxi = max(maxmaxi, maxi)
minminj = min(minminj, minj)
maxmaxj = max(maxmaxj, maxj)
w = maxmaxi - minmini + 1
h = maxmaxj - minminj + 1
# Now write out an image containing just that box, for each frame.
for num, top_name in enumerate(sys.argv[1:]):
top = Image.open(top_name)
out = Image.new("RGB", (w, h))
for i in range(w):
for j in range(h):
t = top.getpixel((i+minmini, j+minminj))
out.putpixel((i, j), t)
fn = "icon_installing_overlay%02d.png" % (num+1,)
out.save(fn)
print "saved", fn
# Write out the base icon, which is the first frame with that box
# blacked out (just to make the file smaller, since it's always
# displayed with one of the overlays on top of it).
for i in range(w):
for j in range(h):
base.putpixel((i+minmini, j+minminj), (0, 0, 0))
fn = "icon_installing.png"
base.save(fn)
print "saved", fn
# The device_ui_init() function needs to tell the recovery UI the
# position of the overlay box.
print
print "add this to your device_ui_init() function:"
print "-" * 40
print " ui_parameters->install_overlay_offset_x = %d;" % (minmini,)
print " ui_parameters->install_overlay_offset_y = %d;" % (minminj,)
print "-" * 40

Some files were not shown because too many files have changed in this diff Show More