@@ -76,7 +76,11 @@ static int fill_buffer(int fd, unsigned char *buf, unsigned int nbytes, unsigned
return count;
}
-static int copy_write(void *out, const void *buf, unsigned int len)
+/*
+ * Export this to be used in other modules
+ * It just copy a buffer to a file
+ */
+int copy_write(void *out, const void *buf, unsigned int len)
{
int ret;
int fd = (out != NULL) ? *(int *)out : -1;
@@ -76,6 +76,7 @@ static struct option long_options[] = {
{"loglevel", required_argument, NULL, 'l'},
{"syslog", no_argument, NULL, 'L' },
{"select", required_argument, NULL, 'e'},
+ {"output", required_argument, NULL, 'o'},
#ifdef CONFIG_SIGNED_IMAGES
{"key", required_argument, NULL, 'k'},
#endif
@@ -548,7 +549,7 @@ int main(int argc, char **argv)
#endif
memset(main_options, 0, sizeof(main_options));
memset(image_url, 0, sizeof(image_url));
- strcpy(main_options, "vhi:e:l:Lcf:p:");
+ strcpy(main_options, "vhi:e:l:Lcf:p:o:");
#ifdef CONFIG_MTD
strcat(main_options, "b:");
#endif
@@ -658,6 +659,9 @@ int main(int argc, char **argv)
strncpy(fname, optarg, sizeof(fname));
opt_i = 1;
break;
+ case 'o':
+ strncpy(swcfg.output, optarg, sizeof(swcfg.output));
+ break;
case 'l':
loglevel = strtoul(optarg, NULL, 10);
break;
@@ -750,6 +754,13 @@ int main(int argc, char **argv)
exit(1);
}
+ if (opt_i && strlen(swcfg.output)) {
+ fprintf(stderr,
+ "Output just from network - do you know cp ?\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
#ifdef CONFIG_SURICATTA
if (opt_u && (opt_c || opt_i)) {
fprintf(stderr, "invalid mode combination with suricatta.\n");
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/socket.h>
#include <ctype.h>
#include <fcntl.h>
#include <dirent.h>
@@ -281,6 +282,32 @@ static int extract_files(int fd, struct swupdate_cfg *software)
}
}
+static int save_stream(int fdin, const char *output)
+{
+ char *buf;
+ int fdout, ret, len;
+ const int bufsize = 16 * 1024;
+
+ fdout = openfileoutput(output);
+ if (fdout < 0)
+ return -1;
+
+ buf = (char *)malloc(bufsize);
+ if (!buf)
+ return -ENOMEM;
+
+ for (;;) {
+ len = read(fdin, buf, bufsize);
+ if (len == 0)
+ break;
+ ret = copy_write(&fdout, buf, len);
+ if (ret < 0)
+ return -EIO;
+ }
+
+ return 0;
+}
+
void *network_initializer(void *data)
{
int ret;
@@ -306,6 +333,26 @@ void *network_initializer(void *data)
pthread_mutex_unlock(&stream_mutex);
notify(START, RECOVERY_NO_ERROR, INFOLEVEL, "Software Update started !");
+ /*
+ * Check if the stream should be saved
+ */
+ if (strlen(software->output)) {
+ ret = save_stream(inst.fd, software->output);
+ if (ret < 0) {
+ notify(FAILURE, RECOVERY_ERROR, ERRORLEVEL,
+ "Image invalid or corrupted. Not installing ...");
+ continue;
+ }
+
+ /*
+ * now replace the file descriptor with
+ * the saved file
+ */
+ close(inst.fd);
+ inst.fd = open(software->output, O_RDONLY, S_IRUSR);
+ }
+
+
#ifdef CONFIG_MTD
mtd_cleanup();
scan_mtd_devices();
@@ -116,6 +116,7 @@ struct swupdate_cfg {
char version[SWUPDATE_GENERAL_STRING_SIZE];
char software_set[SWUPDATE_GENERAL_STRING_SIZE];
char running_mode[SWUPDATE_GENERAL_STRING_SIZE];
+ char output[SWUPDATE_GENERAL_STRING_SIZE];
struct hw_type hw;
struct hwlist hardware;
struct swver installed_sw_list;
@@ -131,6 +131,7 @@ char *sdup(const char *str);
typedef int (*writeimage) (void *out, const void *buf, unsigned int len);
int openfile(const char *filename);
+int copy_write(void *out, const void *buf, unsigned int len);
int copyfile(int fdin, void *out, unsigned int nbytes, unsigned long *offs,
unsigned long long seek,
int skip_file, int compressed, uint32_t *checksum,
Some use cases require to save the incoming stream to a local file. Add command line parameter (-o or --output) Signed-off-by: Stefano Babic <sbabic@denx.de> --- core/cpio_utils.c | 6 +++++- core/swupdate.c | 13 ++++++++++++- corelib/stream_interface.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ include/swupdate.h | 1 + include/util.h | 1 + 5 files changed, 66 insertions(+), 2 deletions(-)