diff options
author | Pali Rohár <pali.rohar@gmail.com> | 2014-12-13 20:47:42 +0100 |
---|---|---|
committer | Pali Rohár <pali.rohar@gmail.com> | 2014-12-13 20:47:42 +0100 |
commit | 55bed7e8cd05b05f96503d81f04fb18a202ae785 (patch) | |
tree | 30dd9452d2c8b64e55baea36777325fb7e31fd40 | |
parent | e6ac56569c4960102838199297bbd1681aed9eb8 (diff) | |
parent | 3538c40ad17c243fcf0f2596dadc3b92360db780 (diff) | |
download | 0xFFFF-55bed7e8cd05b05f96503d81f04fb18a202ae785.tar.bz2 |
Merge branch 'master'
-rw-r--r-- | .travis.yml | 20 | ||||
-rw-r--r-- | config.mk | 2 | ||||
-rw-r--r-- | debian/changelog | 5 | ||||
-rw-r--r-- | debian/compat | 1 | ||||
-rw-r--r-- | debian/control | 84 | ||||
-rw-r--r-- | debian/copyright | 29 | ||||
-rw-r--r-- | debian/docs | 2 | ||||
-rwxr-xr-x | debian/rules | 11 | ||||
-rw-r--r-- | debian/source/format | 1 | ||||
-rw-r--r-- | src/Makefile | 4 | ||||
-rw-r--r-- | src/cold-flash.c | 2 | ||||
-rw-r--r-- | src/fiasco.c | 60 | ||||
-rw-r--r-- | src/image.c | 7 | ||||
-rw-r--r-- | src/local.c | 36 | ||||
-rw-r--r-- | src/main.c | 93 | ||||
-rw-r--r-- | src/nolo.c | 52 | ||||
-rw-r--r-- | src/printf-utils.c | 2 | ||||
-rw-r--r-- | src/usb-device.c | 30 |
18 files changed, 229 insertions, 212 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..3e46a37 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +language: c +compiler: + - gcc +before_install: + - sudo apt-get update -qq + - sudo apt-get install -qq -y libusb-dev +script: if [ ${COVERITY_SCAN_BRANCH} != 1 ]; then make ; fi + +env: + global: + - secure: "JdUp+xFykPZoYA4aRfmYk2CtilLapniQllWPKo2dDdJd1vzdawfTvVxIAKjy7ac9RKwZzg3Chq3RsMEXPv8BtaLbssw266C7RDLMgjacl1eFLcmGRj/Gkk9peDSZ6vVdGEcA2j+6KDSfpCa/XjFjvOufZOgKw6m+3+d0A4G45SI=" + +addons: + coverity_scan: + project: + name: "pali/0xFFFF" + description: "Build submitted via Travis CI" + notification_email: pali.rohar@gmail.com + build_command: "make" + branch_pattern: master @@ -1,4 +1,4 @@ -VERSION = 0.6 +VERSION = 0.6.1 PREFIX = /usr/local # NetBSD stuff diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index 444d517..0000000 --- a/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -0xffff (0.6-1) unstable; urgency=low - - * This is new rewritten version of original 0xFFFF 0.5 tool - - -- Pali Rohár <pali.rohar@gmail.com> Sun, 07 Apr 2013 15:01:50 +0200 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index 7f8f011..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/debian/control b/debian/control deleted file mode 100644 index cf065e7..0000000 --- a/debian/control +++ /dev/null @@ -1,84 +0,0 @@ -Source: 0xffff -Section: user/system -Priority: extra -Maintainer: Pali Rohár <pali.rohar@gmail.com> -Build-Depends: debhelper (>= 7), libusb-dev -Standards-Version: 3.9.3 - -Package: 0xffff -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, mtd-utils -Description: Open Free Fiasco Firmware Flasher - 0xFFFF is Open Free Fiasco Firmware Flasher for Maemo devices. It support - generating and unpacking FIASCO images on local computer. Useful for editing - Maemo firmware package for future flash. It support via USB flashing any image - type to Maemo device and also "cold" flashing which means flashing dead - device with erased bootloader. There is support for booting kernel via USB - without flashing to NAND and also changing configuration of Maemo device - (enable/disable R&D mode, changing HW revision strings, ...). - . - 0xFFFF is alternative tool to proprietary Nokia flasher-3.5 and fiasco-gen. - 0xFFFF generate compatible FIASCO images and also accept FIASCO images - generated by Nokia fiasco-gen. - . - Supported Maemo devices: - Nokia 770, Nokia N800, Nokia N810, Nokia N810 WiMAX, Nokia N900 -XSBC-Maemo-Display-Name: 0xFFFF -XB-Maemo-Icon-26: - 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 - 5l7y6xMAAAAASUVORK5CYII= diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 8c04568..0000000 --- a/debian/copyright +++ /dev/null @@ -1,29 +0,0 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: 0xffff - -Files: * -Copyright: 2007-2012 pancake <pancake@youterm.com> - 2011 Michael Buesch <mb@bu3sch.de> - 2011-2013 Pali Rohár <pali.rohar@gmail.com> -License: GPL-3.0+ - -Files: debian/* -Copyright: 2013 Pali Rohár <pali.rohar@gmail.com> -License: GPL-3.0+ - -License: GPL-3.0+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - . - On Debian systems, the complete text of the GNU General - Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". diff --git a/debian/docs b/debian/docs deleted file mode 100644 index 2e09849..0000000 --- a/debian/docs +++ /dev/null @@ -1,2 +0,0 @@ -README -doc/* diff --git a/debian/rules b/debian/rules deleted file mode 100755 index f43d960..0000000 --- a/debian/rules +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -%: - dh $@ - -override_dh_auto_install: - dh_auto_install -- PREFIX=/usr diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 163aaf8..0000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/src/Makefile b/src/Makefile index d1df391..b436ee6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -31,10 +31,10 @@ $(BIN).1: $(BIN) $(MANGEN) $(DEPENDS) ../doc/examples mv $@.tmp $@ libusb-sniff-32.so: libusb-sniff.c $(DEPENDS) - $(CC) $(CFLAGS) $(LDFLAGS) -fPIC -ldl -shared -m32 -o $@ $< + $(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m32 -o $@ libusb-sniff-64.so: libusb-sniff.c $(DEPENDS) - $(CC) $(CFLAGS) $(LDFLAGS) -fPIC -ldl -shared -m64 -o $@ $< + $(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m64 -o $@ %.o: %.c $(DEPENDS) $(CROSS_CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< diff --git a/src/cold-flash.c b/src/cold-flash.c index 6441187..8874b32 100644 --- a/src/cold-flash.c +++ b/src/cold-flash.c @@ -130,7 +130,7 @@ struct xloader_msg { uint32_t size; /* 4 bytes - size of file */ uint32_t crc1; /* 4 bytes - crc32 of file */ uint32_t crc2; /* 4 bytes - crc32 of first 12 bytes of message */ -}; +} __attribute__((__packed__)); #define XLOADER_MSG_TYPE_PING 0x6301326E #define XLOADER_MSG_TYPE_SEND 0x6302326E diff --git a/src/fiasco.c b/src/fiasco.c index 721785e..a2cd55a 100644 --- a/src/fiasco.c +++ b/src/fiasco.c @@ -192,9 +192,12 @@ struct fiasco * fiasco_alloc_from_file(const char * file) { if ( ! hwrevs[0] ) strcpy(hwrevs, hwrev); else { - /* TODO: check if hwrevs has enough size */ - strcat(hwrevs, ","); - strcat(hwrevs, hwrev); + size_t len1 = strlen(hwrevs); + size_t len2 = strlen(hwrev); + if ( len1 + len2 + 2 < sizeof(hwrevs) ) { + hwrevs[len1] = ','; + memcpy(hwrevs+len1+1, hwrev, len2+1); + } } VERBOSE(" hw revision: %s\n", hwrev); pbuf += strlen(hwrev) + 1; @@ -410,6 +413,7 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) { WRITE_OR_FAIL(file, fd, "2", 1); /* 2 - device & hwrevs */ WRITE_OR_FAIL(file, fd, &device_hwrevs_bufs[i][0], 1); WRITE_OR_FAIL(file, fd, device_hwrevs_bufs[i]+1, ((uint8_t *)(device_hwrevs_bufs[i]))[0]); + /* FIXME: memory leak: device_hwrevs_bufs */ } free(device_hwrevs_bufs); @@ -449,9 +453,9 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) { int fiasco_unpack(struct fiasco * fiasco, const char * dir) { - int fd = -1; - char * name = NULL; - char * layout_name = NULL; + int fd; + char * name; + char * layout_name; struct image * image; struct image_list * image_list; uint32_t size; @@ -480,6 +484,10 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { while ( image_list ) { + fd = -1; + name = NULL; + layout_name = NULL; + image = image_list->image; name = image_name_alloc_from_values(image); @@ -492,9 +500,11 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { if ( image->layout ) { - layout_name = calloc(1, strlen(name) + strlen(".layout") + 1); - if ( ! layout_name ) + layout_name = calloc(1, strlen(name) + sizeof(".layout")-1 + 1); + if ( ! layout_name ) { + free(name); ALLOC_ERROR_RETURN(-1); + } sprintf(layout_name, "%s.layout", name); @@ -508,21 +518,32 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644); if ( fd < 0 ) { ERROR_INFO("Cannot create output file %s", name); + free(name); + free(layout_name); return -1; } } - free(name); - image_seek(image, 0); while ( 1 ) { size = image_read(image, buf, sizeof(buf)); if ( size == 0 ) break; - WRITE_OR_FAIL(name, fd, buf, size); + if ( ! simulate ) { + if ( write(fd, buf, size) != (ssize_t)size ) { + ERROR_INFO_STR(name, "Cannot write %d bytes", size); + close(fd); + free(name); + free(layout_name); + return -1; + } + } } - close(fd); + free(name); + + if ( ! simulate ) + close(fd); if ( image->layout ) { @@ -530,15 +551,24 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) { fd = open(layout_name, O_RDWR|O_CREAT|O_TRUNC, 0644); if ( fd < 0 ) { ERROR_INFO("Cannot create layout file %s", layout_name); + free(layout_name); + return -1; + } + + size = strlen(image->layout); + + if ( write(fd, image->layout, size) != (ssize_t)size ) { + ERROR_INFO_STR(layout_name, "Cannot write %d bytes", size); + close(fd); + free(layout_name); return -1; } } free(layout_name); - WRITE_OR_FAIL(layout_name, fd, image->layout, (int)strlen(image->layout)); - - close(fd); + if ( ! simulate ) + close(fd); } diff --git a/src/image.c b/src/image.c index 44655fb..48d80d8 100644 --- a/src/image.c +++ b/src/image.c @@ -88,14 +88,13 @@ static void image_missing_values_from_name(struct image * image, const char * na if ( image->devices && image->devices->device && ! image->devices->hwrevs ) image->devices->hwrevs = hwrevs_alloc_from_string(hwrevs); - else - free(hwrevs); if ( ! image->version ) image->version = version; else free(version); + free(hwrevs); free(str); } @@ -135,8 +134,10 @@ char * image_name_alloc_from_values(struct image * image) { length += 1 + strlen(image->version); name = calloc(1, length); - if ( ! name ) + if ( ! name ) { + free(hwrevs); ALLOC_ERROR_RETURN(NULL); + } strcpy(name, type); ptr = name + strlen(name); diff --git a/src/local.c b/src/local.c index e90011b..c7f3ad1 100644 --- a/src/local.c +++ b/src/local.c @@ -127,9 +127,9 @@ int local_init(void) { while ( fgets(buf, sizeof(buf), file) ) { - if ( strncmp(buf, "Hardware", strlen("Hardware")) == 0 ) { + if ( strncmp(buf, "Hardware", sizeof("Hardware")-1) == 0 ) { - ptr = buf + strlen("Hardware"); + ptr = buf + sizeof("Hardware")-1; while ( ptr < buf + sizeof(buf) && *ptr > 0 && *ptr <= 32 ) ++ptr; @@ -316,21 +316,23 @@ int local_dump_image(enum image_type image, const char * file) { while ( ( dirent = readdir(dir) ) ) { - snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/slot_name", dirent->d_name); + if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/slot_name", dirent->d_name) <= 0 ) + continue; fd = open(buf, O_RDONLY); if ( fd < 0 ) continue; - buf[0] = 0; - if ( read(fd, buf, sizeof(buf)) < 0 ) + memset(buf, 0, sizeof(buf)); + if ( read(fd, buf, sizeof(buf)-1) < 0 ) buf[0] = 0; close(fd); - if ( strncmp(buf, "internal", strlen("internal")) != 0 ) + if ( strncmp(buf, "internal", sizeof("internal")-1) != 0 ) continue; - snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/", dirent->d_name, dirent->d_name); + if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/", dirent->d_name, dirent->d_name) <= 0 ) + continue; dir2 = opendir(buf); if ( ! dir2 ) @@ -338,10 +340,11 @@ int local_dump_image(enum image_type image, const char * file) { while ( ( dirent2 = readdir(dir2) ) ) { - if ( strncmp(dirent2->d_name, "block:mmcblk", strlen("block:mmcblk")) != 0 ) + if ( strncmp(dirent2->d_name, "block:mmcblk", sizeof("block:mmcblk")-1) != 0 ) continue; - snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/%s/dev", dirent->d_name, dirent->d_name, dirent2->d_name); + if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/%s/dev", dirent->d_name, dirent->d_name, dirent2->d_name) <= 0 ) + continue; f = fopen(buf, "r"); if ( ! f ) @@ -385,7 +388,8 @@ int local_dump_image(enum image_type image, const char * file) { while ( ( dirent = readdir(dir) ) ) { - snprintf(buf, sizeof(buf), "/dev/%s", dirent->d_name); + if ( snprintf(buf, sizeof(buf), "/dev/%s", dirent->d_name) <= 0 ) + continue; if ( stat(buf, &st) != 0 ) continue; @@ -410,7 +414,7 @@ int local_dump_image(enum image_type image, const char * file) { VERBOSE("Detected internal mmc device: '%s'\n", blk); - strncat(blk, "p1", sizeof(blk)); + strncat(blk, "p1", sizeof(blk)-strlen(blk)-1); printf("Using MyDocs mmc device: '%s'\n", blk); @@ -457,6 +461,10 @@ int local_dump_image(enum image_type image, const char * file) { if ( addr[nlen-1] != 0xFF ) break; + for ( ; nlen > 0; --nlen ) + if ( addr[nlen-1] != 0x00 ) + break; + if ( image == IMAGE_MMC ) align = 8; else @@ -532,7 +540,7 @@ int local_set_usb_host_mode(int enable) { int local_get_rd_mode(void) { - if ( strncmp(rd_mode, "master", strlen("master")) == 0 ) + if ( strncmp(rd_mode, "master", sizeof("master")-1) == 0 ) return 1; else return 0; @@ -551,8 +559,8 @@ int local_get_rd_flags(char * flags, size_t size) { const char * ptr; - if ( strncmp(rd_mode, "master", strlen("master")) == 0 ) - ptr = rd_mode + strlen("master"); + if ( strncmp(rd_mode, "master", sizeof("master")-1) == 0 ) + ptr = rd_mode + sizeof("master")-1; else ptr = rd_mode; @@ -53,8 +53,8 @@ static void show_usage(void) { " -f flash all specified images\n" " -c cold flash 2nd and secondary images\n" " -x [/dev/mtd] check for bad blocks on mtd device (default: all)\n" - " -E file dump all device images to one fiasco image, see -t\n" - " -e [dir] dump all device images to directory, see -t (default: current)\n" + " -E file dump all device images to one fiasco image\n" + " -e [dir] dump all device images (or one -t) to directory (default: current)\n" "\n" "Device configuration:\n" @@ -84,7 +84,7 @@ static void show_usage(void) { "\n" "Image filters:\n" - " -t types filter images by type\n" + " -t type filter images by type\n" " -d dev filter images by device\n" " -w hw filter images by HW revision\n" "\n" @@ -210,7 +210,7 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) { exit(1); } lseek(fd, 0, SEEK_SET); - layout = malloc(len); + layout = malloc(len+1); if ( ! layout ) { ALLOC_ERROR(); exit(1); @@ -219,6 +219,8 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) { ERROR_INFO("Cannot read %lu bytes from layout file %s", len, layout_file); exit(1); } + layout[len] = 0; + close(fd); } image = image_alloc_from_file(file, type, device, hwrevs, version, layout); @@ -661,6 +663,9 @@ int main(int argc, char **argv) { goto clean; } filter_images_by_type(type, &image_first); + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; } /* filter images by device */ @@ -672,11 +677,18 @@ int main(int argc, char **argv) { goto clean; } filter_images_by_device(device, &image_first); + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; } /* filter images by hwrev */ - if ( filter_hwrev ) + if ( filter_hwrev ) { filter_images_by_hwrev(atoi(filter_hwrev_arg), &image_first); + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; + } /* reorder images for flashing (first x-loader, second secondary) */ /* set 2nd and secondary images for cold-flashing */ @@ -740,11 +752,29 @@ int main(int argc, char **argv) { image_ptr = next; } + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; + } - /* make sure that fiasco_in has valid images*/ - if ( fiasco_in ) - fiasco_in->first = image_first; + /* remove 2nd image when doing normal flash */ + if ( dev_flash ) { + image_ptr = image_first; + while ( image_ptr ) { + struct image_list * next = image_ptr->next; + if ( image_ptr->image->type == IMAGE_2ND ) { + if ( image_ptr == image_first ) + image_first = next; + image_list_del(image_ptr); + } + image_ptr = next; + } + + /* make sure that fiasco_in has valid images */ + if ( fiasco_in ) + fiasco_in->first = image_first; + } /* identify images */ if ( image_ident ) { @@ -782,8 +812,9 @@ int main(int argc, char **argv) { WARNING("Removing unknown image (specified by %s %s)", image_ptr->image->orig_filename ? "file" : "fiasco", image_ptr->image->orig_filename ? image_ptr->image->orig_filename : "image"); if ( image_ptr == image_first ) image_first = next; - image_list_unlink(image_ptr); - free(image_ptr); + if ( fiasco_in && image_ptr == fiasco_in->first ) + fiasco_in->first = fiasco_in->first->next; + image_list_del(image_ptr); } image_ptr = next; } @@ -983,6 +1014,8 @@ int main(int argc, char **argv) { filter_images_by_device(dev->detected_device, &image_first); if ( detected_hwrev ) filter_images_by_hwrev(dev->detected_hwrev, &image_first); + if ( fiasco_in && ( detected_device || detected_hwrev ) ) + fiasco_in->first = image_first; /* set kernel and initfs images for loading */ if ( dev_load ) { @@ -1047,8 +1080,7 @@ int main(int argc, char **argv) { if ( fiasco_in && image_kernel == fiasco_in->first ) fiasco_in->first = fiasco_in->first->next; - image_list_unlink(image_kernel); - free(image_kernel); + image_list_del(image_kernel); image_kernel = NULL; } @@ -1059,11 +1091,10 @@ int main(int argc, char **argv) { if ( image_initfs == image_first ) image_first = image_first->next; - if ( fiasco_in && image_kernel == fiasco_in->first ) + if ( fiasco_in && image_initfs == fiasco_in->first ) fiasco_in->first = fiasco_in->first->next; - image_list_unlink(image_initfs); - free(image_initfs); + image_list_del(image_initfs); image_initfs = NULL; } } @@ -1079,11 +1110,10 @@ int main(int argc, char **argv) { if ( image_ptr == image_first ) image_first = image_first->next; - if ( fiasco_in && image_kernel == fiasco_in->first ) + if ( fiasco_in && image_ptr == fiasco_in->first ) fiasco_in->first = fiasco_in->first->next; - image_list_unlink(image_ptr); - free(image_ptr); + image_list_del(image_ptr); image_ptr = next; } } @@ -1175,9 +1205,21 @@ int main(int argc, char **argv) { buf[0] = 0; } - for ( i = 0; i < IMAGE_COUNT; ++i ) - if ( image_tmp_name(i) ) - dev_dump_image(dev, i, image_tmp_name(i)); + if ( filter_type ) { + enum image_type type = image_type_from_string(filter_type_arg); + if ( ! type || ! image_tmp_name(type) ) { + ERROR("Specified unknown image type for filtering: %s", filter_type_arg); + ret = 1; + goto clean; + } + ret = dev_dump_image(dev, type, image_tmp_name(type)); + if ( ret != 0 ) + goto clean; + } else { + for ( i = 0; i < IMAGE_COUNT; ++i ) + if ( image_tmp_name(i) ) + dev_dump_image(dev, i, image_tmp_name(i)); + } if ( buf[0] ) if ( chdir(buf) < 0 ) @@ -1196,7 +1238,8 @@ int main(int argc, char **argv) { if ( ! image_tmp_name(i) ) continue; - sprintf(buf, "%hd", dev->detected_hwrev); + buf[0] = 0; + snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev); switch ( i ) { case IMAGE_2ND: @@ -1298,14 +1341,16 @@ int main(int argc, char **argv) { break; } - sprintf(buf, "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr); + buf[0] = 0; + snprintf(buf, sizeof(buf), "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr); printf("Renaming %s image file to %s...\n", image_type_to_string(i), buf); if ( rename(image_tmp_name(i), buf) < 0 ) { ERROR_INFO("Renaming failed"); - sprintf(buf, "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr); + buf[0] = 0; + snprintf(buf, sizeof(buf), "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr); printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf); if ( rename(image_tmp_name(i), buf) < 0 ) @@ -84,12 +84,14 @@ static void nolo_error_log(struct usb_device_info * dev, int only_clear) { char buf[2048]; size_t i, count; + int ret; for ( count = 0; count < 20; ++count ) { memset(buf, 0, sizeof(buf)); - if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, buf, sizeof(buf), 2000) <= 0 ) + ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, buf, sizeof(buf), 2000); + if ( ret < 0 ) break; if ( ! only_clear ) { @@ -103,6 +105,9 @@ static void nolo_error_log(struct usb_device_info * dev, int only_clear) { } + if ( (size_t)ret < sizeof(buf) ) + break; + } } @@ -176,14 +181,14 @@ static int nolo_get_version_string(struct usb_device_info * dev, const char * st if ( strlen(str) > 500 ) return -1; - sprintf(buf, "version:%s", str); + if ( sprintf(buf, "version:%s", str) <= 0 ) + return -1; ret = nolo_get_string(dev, buf, out, size); - - nolo_error_log(dev, 1); - - if ( ret < 0 ) + if ( ret < 0 ) { + nolo_error_log(dev, 1); return ret; + } if ( ! out[0] ) return -1; @@ -311,7 +316,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i if ( bufs ) { memset(buf, 0, sizeof(buf)); - snprintf(buf, 8, "%d", dev->hwrev); + snprintf(buf, 8+1, "%d", dev->hwrev); for ( i = 0; bufs[i]; ++i ) { len = ((uint8_t*)bufs[i])[0]; @@ -418,8 +423,8 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { unsigned long long int part; unsigned long long int total; unsigned long long int last_total; - char status[20]; char buf[128]; + char * ptr; if ( image->type == IMAGE_ROOTFS ) flash = 1; @@ -463,7 +468,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { if ( nolo_get_string(dev, "cmt:status", buf, sizeof(buf)) < 0 ) NOLO_ERROR_RETURN("cmt:status failed", -1); - if ( strncmp(buf, "idle", strlen("idle")) == 0 ) + if ( strncmp(buf, "idle", sizeof("idle")-1) == 0 ) state = 4; else printf("Erasing CMT...\n"); @@ -475,7 +480,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { NOLO_ERROR_RETURN("cmt:status failed", -1); } - if ( strncmp(buf, "finished", strlen("finished")) == 0 ) { + if ( strncmp(buf, "finished", sizeof("finished")-1) == 0 ) { if ( state <= 0 ) { printf_progressbar(last_total, last_total); @@ -490,18 +495,29 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { state = 4; + } else if ( strncmp(buf, "error", sizeof("error")-1) == 0 ) { + + PRINTF_ERROR_RETURN("cmt:status error", -1); + } else { - if ( sscanf(buf, "%s:%llu/%llu", status, &part, &total) != 3 ) + ptr = strchr(buf, ':'); + if ( ! ptr ) + PRINTF_ERROR_RETURN("cmt:status unknown", -1); + + *ptr = 0; + ptr++; + + if ( sscanf(ptr, "%llu/%llu", &part, &total) != 2 ) PRINTF_ERROR_RETURN("cmt:status unknown", -1); - if ( strcmp(status, "program") == 0 && state <= 0 ) { + if ( strcmp(buf, "program") == 0 && state <= 0 ) { printf_progressbar(last_total, last_total); printf("Done\n"); state = 1; } - if ( strcmp(status, "program") == 0 && state <= 1 ) { + if ( strcmp(buf, "program") == 0 && state <= 1 ) { printf("Programming CMT...\n"); state = 2; } @@ -509,12 +525,12 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) { printf_progressbar(part, total); last_total = total; - if ( strcmp(status, "erase") == 0 && state <= 0 && part == total ) { + if ( strcmp(buf, "erase") == 0 && state <= 0 && part == total ) { printf("Done\n"); state = 1; } - if ( strcmp(status, "program") == 0 && state <= 2 && part == total ) { + if ( strcmp(buf, "program") == 0 && state <= 2 && part == total ) { printf("Done\n"); state = 3; } @@ -536,9 +552,9 @@ int nolo_boot_device(struct usb_device_info * dev, const char * cmdline) { int size = 0; int mode = NOLO_BOOT_MODE_NORMAL; - if ( cmdline && strncmp(cmdline, "update", strlen("update")) == 0 && cmdline[strlen("update")] <= 32 ) { + if ( cmdline && strncmp(cmdline, "update", sizeof("update")-1) == 0 && cmdline[sizeof("update")-1] <= 32 ) { mode = NOLO_BOOT_MODE_UPDATE; - cmdline += strlen("update"); + cmdline += sizeof("update")-1; if ( *cmdline ) ++cmdline; while ( *cmdline && *cmdline <= 32 ) ++cmdline; @@ -763,7 +779,7 @@ int nolo_set_hwrev(struct usb_device_info * dev, int16_t hwrev) { char buf[9]; memset(buf, 0, sizeof(buf)); - snprintf(buf, 8, "%d", hwrev); + snprintf(buf, sizeof(buf), "%d", hwrev); printf("Setting HW revision to: %s\n", buf); return nolo_set_string(dev, "hw_rev", buf); diff --git a/src/printf-utils.c b/src/printf-utils.c index 939cf54..3520d0b 100644 --- a/src/printf-utils.c +++ b/src/printf-utils.c @@ -39,7 +39,7 @@ void printf_progressbar(unsigned long long part, unsigned long long total) { int tmp, cols = 80; /* percentage calculation */ - pc = (int)(part*100/total); + pc = total==0?100:(int)(part*100/total); (pc<0)?pc=0:(pc>100)?pc=100:0; PRINTF_BACK(); diff --git a/src/usb-device.c b/src/usb-device.c index 039e82e..bf1241e 100644 --- a/src/usb-device.c +++ b/src/usb-device.c @@ -27,6 +27,10 @@ #include <usb.h> +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP +#include <sys/ioctl.h> +#endif + #include "global.h" #include "device.h" #include "usb-device.h" @@ -73,6 +77,25 @@ static void usb_flash_device_info_print(const struct usb_flash_device * dev) { } +static void usb_reattach_kernel_driver(usb_dev_handle * udev, int interface) { + +#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP + struct { + int ifno; + int ioctl_code; + void * data; + } command = { + .ifno = interface, + .ioctl_code = _IO('U', 23), + .data = NULL, + }; + + usb_release_interface(udev, interface); + ioctl(*((int *)udev), _IOWR('U', 18, command), &command); +#endif + +} + static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device * dev, char * product, size_t size) { char buf[1024]; @@ -145,6 +168,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { if ( usb_claim_interface(udev, usb_devices[i].interface) < 0 ) { PRINTF_ERROR("usb_claim_interface failed"); fprintf(stderr, "\n"); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); return NULL; } @@ -154,6 +178,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) { PRINTF_ERROR("usb_claim_interface failed"); fprintf(stderr, "\n"); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); return NULL; } @@ -164,6 +189,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { if ( usb_set_configuration(udev, usb_devices[i].configuration) < 0 ) { PRINTF_ERROR("usb_set_configuration failed"); fprintf(stderr, "\n"); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); return NULL; } @@ -172,6 +198,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { ret = calloc(1, sizeof(struct usb_device_info)); if ( ! ret ) { ALLOC_ERROR(); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); return NULL; } @@ -197,7 +224,9 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { if ( ! *device ) { ERROR("Device mishmash"); fprintf(stderr, "\n"); + usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_close(udev); + free(ret); return NULL; } } @@ -308,6 +337,7 @@ struct usb_device_info * usb_open_and_wait_for_device(void) { void usb_close_device(struct usb_device_info * dev) { + usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface); usb_close(dev->udev); free(dev); |