summaryrefslogtreecommitdiffstats
path: root/fastboot
diff options
context:
space:
mode:
Diffstat (limited to 'fastboot')
-rw-r--r--fastboot/Android.mk2
-rw-r--r--fastboot/engine.c40
-rw-r--r--fastboot/fastboot.c75
-rw-r--r--fastboot/fastboot.h9
-rw-r--r--fastboot/usb_osx.c6
5 files changed, 95 insertions, 37 deletions
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 34380ec..3c5538f 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -50,7 +50,7 @@ endif
LOCAL_STATIC_LIBRARIES := $(EXTRA_STATIC_LIBS) libzipfile libunz
include $(BUILD_HOST_EXECUTABLE)
-$(call dist-for-goals,droid,$(LOCAL_BUILT_MODULE))
+$(call dist-for-goals,dist_files,$(LOCAL_BUILT_MODULE))
ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
diff --git a/fastboot/engine.c b/fastboot/engine.c
index 48073ee..6d94035 100644
--- a/fastboot/engine.c
+++ b/fastboot/engine.c
@@ -69,6 +69,7 @@ struct Action
Action *next;
char cmd[64];
+ const char *prod;
void *data;
unsigned size;
@@ -183,6 +184,16 @@ static int cb_check(Action *a, int status, char *resp, int invert)
return status;
}
+ if (a->prod) {
+ if (strcmp(a->prod, cur_product) != 0) {
+ double split = now();
+ fprintf(stderr,"IGNORE, product is %s required only for %s [%7.3fs]\n",
+ cur_product, a->prod, (split - a->start));
+ a->start = split;
+ return 0;
+ }
+ }
+
yes = match(resp, value, count);
if (invert) yes = !yes;
@@ -214,10 +225,12 @@ static int cb_reject(Action *a, int status, char *resp)
return cb_check(a, status, resp, 1);
}
-void fb_queue_require(const char *var, int invert, unsigned nvalues, const char **value)
+void fb_queue_require(const char *prod, const char *var,
+ int invert, unsigned nvalues, const char **value)
{
Action *a;
a = queue_action(OP_QUERY, "getvar:%s", var);
+ a->prod = prod;
a->data = value;
a->size = nvalues;
a->msg = mkmsg("checking %s", var);
@@ -244,6 +257,25 @@ void fb_queue_display(const char *var, const char *prettyname)
a->func = cb_display;
}
+static int cb_save(Action *a, int status, char *resp)
+{
+ if (status) {
+ fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp);
+ return status;
+ }
+ strncpy(a->data, resp, a->size);
+ return 0;
+}
+
+void fb_queue_query_save(const char *var, char *dest, unsigned dest_size)
+{
+ Action *a;
+ a = queue_action(OP_QUERY, "getvar:%s", var);
+ a->data = (void *)dest;
+ a->size = dest_size;
+ a->func = cb_save;
+}
+
static int cb_do_nothing(Action *a, int status, char *resp)
{
fprintf(stderr,"\n");
@@ -277,11 +309,11 @@ void fb_queue_notice(const char *notice)
a->data = (void*) notice;
}
-void fb_execute_queue(usb_handle *usb)
+int fb_execute_queue(usb_handle *usb)
{
Action *a;
char resp[FB_RESPONSE_SZ+1];
- int status;
+ int status = 0;
a = action_list;
resp[FB_RESPONSE_SZ] = 0;
@@ -314,5 +346,5 @@ void fb_execute_queue(usb_handle *usb)
}
fprintf(stderr,"finished. total time: %.3fs\n", (now() - start));
+ return status;
}
-
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index 14048a1..4a2de20 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -9,7 +9,7 @@
* notice, this list of conditions and the following disclaimer.
* * 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
+ * the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
@@ -19,7 +19,7 @@
* COPYRIGHT OWNER 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
+ * 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
@@ -42,6 +42,8 @@
#include "fastboot.h"
+char cur_product[FB_RESPONSE_SZ + 1];
+
void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline);
boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size,
@@ -68,7 +70,7 @@ void die(const char *fmt, ...)
fprintf(stderr,"\n");
va_end(ap);
exit(1);
-}
+}
void get_my_path(char *path);
@@ -99,13 +101,13 @@ char *find_item(const char *item, const char *product)
"../../../target/product/%s/%s", product, fn);
return strdup(path);
}
-
+
dir = getenv("ANDROID_PRODUCT_OUT");
if((dir == 0) || (dir[0] == 0)) {
die("neither -p product specified nor ANDROID_PRODUCT_OUT set");
return 0;
}
-
+
sprintf(path, "%s/%s", dir, fn);
return strdup(path);
}
@@ -189,12 +191,12 @@ usb_handle *open_device(void)
int announce = 1;
if(usb) return usb;
-
+
for(;;) {
usb = usb_open(match_fastboot);
if(usb) return usb;
if(announce) {
- announce = 0;
+ announce = 0;
fprintf(stderr,"< waiting for device >\n");
}
sleep(1);
@@ -226,6 +228,7 @@ void usage(void)
" continue continue with autoboot\n"
" reboot reboot device normally\n"
" reboot-bootloader reboot device into bootloader\n"
+ " help show this help message\n"
"\n"
"options:\n"
" -w erase userdata and cache\n"
@@ -236,7 +239,6 @@ void usage(void)
" -b <base_addr> specify a custom kernel base address\n"
" -n <page size> specify the nand page size. default: 2048\n"
);
- exit(1);
}
void *load_bootable_image(unsigned page_size, const char *kernel, const char *ramdisk,
@@ -257,16 +259,16 @@ void *load_bootable_image(unsigned page_size, const char *kernel, const char *ra
fprintf(stderr, "cannot load '%s'\n", kernel);
return 0;
}
-
+
/* is this actually a boot image? */
if(!memcmp(kdata, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
if(cmdline) bootimg_set_cmdline((boot_img_hdr*) kdata, cmdline);
-
+
if(ramdisk) {
fprintf(stderr, "cannot boot a boot.img *and* ramdisk\n");
return 0;
}
-
+
*sz = ksize;
return kdata;
}
@@ -288,7 +290,7 @@ void *load_bootable_image(unsigned page_size, const char *kernel, const char *ra
if(cmdline) bootimg_set_cmdline((boot_img_hdr*) bdata, cmdline);
fprintf(stderr,"creating boot image - %d bytes\n", bsize);
*sz = bsize;
-
+
return bdata;
}
@@ -297,7 +299,7 @@ void *unzip_file(zipfile_t zip, const char *name, unsigned *sz)
void *data;
zipentry_t entry;
unsigned datasz;
-
+
entry = lookup_zipentry(zip, name);
if (entry == NULL) {
fprintf(stderr, "archive does not contain '%s'\n", name);
@@ -340,16 +342,25 @@ static int setup_requirement_line(char *name)
{
char *val[MAX_OPTIONS];
const char **out;
+ char *prod = NULL;
unsigned n, count;
char *x;
int invert = 0;
-
+
if (!strncmp(name, "reject ", 7)) {
name += 7;
invert = 1;
} else if (!strncmp(name, "require ", 8)) {
name += 8;
invert = 0;
+ } else if (!strncmp(name, "require-for-product:", 20)) {
+ // Get the product and point name past it
+ prod = name + 20;
+ name = strchr(name, ' ');
+ if (!name) return -1;
+ *name = 0;
+ name += 1;
+ invert = 0;
}
x = strchr(name, '=');
@@ -363,10 +374,10 @@ static int setup_requirement_line(char *name)
*x = 0;
val[count] = x + 1;
}
-
+
name = strip(name);
for(n = 0; n < count; n++) val[n] = strip(val[n]);
-
+
name = strip(name);
if (name == 0) return -1;
@@ -381,7 +392,7 @@ static int setup_requirement_line(char *name)
if (out[n] == 0) return -1;
}
- fb_queue_require(name, invert, n, out);
+ fb_queue_require(prod, name, invert, n, out);
return 0;
}
@@ -432,6 +443,8 @@ void do_update(char *fn)
queue_info_dump();
+ fb_queue_query_save("product", cur_product, sizeof(cur_product));
+
zdata = load_file(fn, &zsize);
if (zdata == 0) die("failed to load '%s'", fn);
@@ -477,11 +490,11 @@ void do_send_signature(char *fn)
void *data;
unsigned sz;
char *xtn;
-
+
xtn = strrchr(fn, '.');
if (!xtn) return;
if (strcmp(xtn, ".img")) return;
-
+
strcpy(xtn,".sig");
data = load_file(fn, &sz);
strcpy(xtn,".img");
@@ -498,6 +511,8 @@ void do_flashall(void)
queue_info_dump();
+ fb_queue_query_save("product", cur_product, sizeof(cur_product));
+
fname = find_item("info", product);
if (fname == 0) die("cannot find android-info.txt");
data = load_file(fname, &sz);
@@ -521,18 +536,18 @@ void do_flashall(void)
data = load_file(fname, &sz);
if (data == 0) die("could not load system.img");
do_send_signature(fname);
- fb_queue_flash("system", data, sz);
+ fb_queue_flash("system", data, sz);
}
#define skip(n) do { argc -= (n); argv += (n); } while (0)
-#define require(n) do { if (argc < (n)) usage(); } while (0)
+#define require(n) do { if (argc < (n)) {usage(); exit(1);}} while (0)
int do_oem_command(int argc, char **argv)
{
int i;
char command[256];
if (argc <= 1) return 0;
-
+
command[0] = 0;
while(1) {
strcat(command,*argv);
@@ -541,7 +556,7 @@ int do_oem_command(int argc, char **argv)
strcat(command," ");
}
- fb_queue_command(command,"");
+ fb_queue_command(command,"");
return 0;
}
@@ -553,11 +568,12 @@ int main(int argc, char **argv)
void *data;
unsigned sz;
unsigned page_size = 2048;
+ int status;
skip(1);
if (argc == 0) {
usage();
- return 0;
+ return 1;
}
if (!strcmp(*argv, "devices")) {
@@ -565,6 +581,12 @@ int main(int argc, char **argv)
return 0;
}
+ if (!strcmp(*argv, "help")) {
+ usage();
+ return 0;
+ }
+
+
serial = getenv("ANDROID_SERIAL");
while (argc > 0) {
@@ -689,6 +711,7 @@ int main(int argc, char **argv)
argc = do_oem_command(argc, argv);
} else {
usage();
+ return 1;
}
}
@@ -704,6 +727,6 @@ int main(int argc, char **argv)
usb = open_device();
- fb_execute_queue(usb);
- return 0;
+ status = fb_execute_queue(usb);
+ return (status) ? 1 : 0;
}
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index a36c569..9e043fe 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -43,15 +43,20 @@ char *fb_get_error(void);
/* engine.c - high level command queue engine */
void fb_queue_flash(const char *ptn, void *data, unsigned sz);;
void fb_queue_erase(const char *ptn);
-void fb_queue_require(const char *var, int invert, unsigned nvalues, const char **value);
+void fb_queue_require(const char *prod, const char *var, int invert,
+ unsigned nvalues, const char **value);
void fb_queue_display(const char *var, const char *prettyname);
+void fb_queue_query_save(const char *var, char *dest, unsigned dest_size);
void fb_queue_reboot(void);
void fb_queue_command(const char *cmd, const char *msg);
void fb_queue_download(const char *name, void *data, unsigned size);
void fb_queue_notice(const char *notice);
-void fb_execute_queue(usb_handle *usb);
+int fb_execute_queue(usb_handle *usb);
/* util stuff */
void die(const char *fmt, ...);
+/* Current product */
+extern char cur_product[FB_RESPONSE_SZ + 1];
+
#endif
diff --git a/fastboot/usb_osx.c b/fastboot/usb_osx.c
index 9488687..570a456 100644
--- a/fastboot/usb_osx.c
+++ b/fastboot/usb_osx.c
@@ -231,8 +231,7 @@ static int try_interfaces(IOUSBDeviceInterface182 **dev, usb_handle *handle) {
kr = (*interface)->ClearPipeStallBothEnds(interface,
handle->bulkIn);
if (kr != 0) {
- ERR("could not clear input pipe; result %d", kr);
- return -1;
+ ERR("could not clear input pipe; result %x, ignoring...\n", kr);
}
}
@@ -240,8 +239,7 @@ static int try_interfaces(IOUSBDeviceInterface182 **dev, usb_handle *handle) {
kr = (*interface)->ClearPipeStallBothEnds(interface,
handle->bulkOut);
if (kr != 0) {
- ERR("could not clear output pipe; result %d", kr);
- return -1;
+ ERR("could not clear output pipe; result %x, ignoring....\n", kr);
}
}