summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml20
-rw-r--r--config.mk2
-rw-r--r--debian/changelog5
-rw-r--r--debian/compat1
-rw-r--r--debian/control84
-rw-r--r--debian/copyright29
-rw-r--r--debian/docs2
-rwxr-xr-xdebian/rules11
-rw-r--r--debian/source/format1
-rw-r--r--src/Makefile4
-rw-r--r--src/cold-flash.c2
-rw-r--r--src/fiasco.c60
-rw-r--r--src/image.c7
-rw-r--r--src/local.c36
-rw-r--r--src/main.c93
-rw-r--r--src/nolo.c52
-rw-r--r--src/printf-utils.c2
-rw-r--r--src/usb-device.c30
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
diff --git a/config.mk b/config.mk
index 158d300..822eb02 100644
--- a/config.mk
+++ b/config.mk
@@ -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;
diff --git a/src/main.c b/src/main.c
index fdd2b4b..0552593 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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 )
diff --git a/src/nolo.c b/src/nolo.c
index 238336d..e437ef7 100644
--- a/src/nolo.c
+++ b/src/nolo.c
@@ -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);