summaryrefslogtreecommitdiff
path: root/misc-utils/flashcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc-utils/flashcp.c')
-rw-r--r--misc-utils/flashcp.c173
1 files changed, 77 insertions, 96 deletions
diff --git a/misc-utils/flashcp.c b/misc-utils/flashcp.c
index 718c513..9e92fa2 100644
--- a/misc-utils/flashcp.c
+++ b/misc-utils/flashcp.c
@@ -48,7 +48,7 @@
/* for debugging purposes only */
#ifdef DEBUG
#undef DEBUG
-#define DEBUG(fmt,args...) { log_printf (LOG_ERROR,"%d: ",__LINE__); log_printf (LOG_ERROR,fmt,## args); }
+#define DEBUG(fmt,args...) { fprintf (stderr,"%d: ",__LINE__); fprintf (stderr,fmt,## args); }
#else
#undef DEBUG
#define DEBUG(fmt,args...)
@@ -62,7 +62,6 @@
/* cmd-line flags */
#define FLAG_NONE 0x00
-#define FLAG_VERBOSE 0x01
#define FLAG_HELP 0x02
#define FLAG_FILENAME 0x04
#define FLAG_DEVICE 0x08
@@ -73,21 +72,34 @@
#define LOG_NORMAL 1
#define LOG_ERROR 2
-static void log_printf (int level,const char *fmt, ...)
+static NORETURN void log_failure (const char *fmt, ...)
{
- FILE *fp = level == LOG_NORMAL ? stdout : stderr;
va_list ap;
va_start (ap,fmt);
- vfprintf (fp,fmt,ap);
+ vfprintf (stderr,fmt,ap);
va_end (ap);
- fflush (fp);
+ fflush (stderr);
+
+ exit (EXIT_FAILURE);
}
-static NORETURN void showusage(bool error)
+static int verbose = 0;
+static void log_verbose (const char *fmt, ...)
{
- int level = error ? LOG_ERROR : LOG_NORMAL;
+ va_list ap;
- log_printf (level,
+ if (!verbose)
+ return;
+
+ va_start (ap,fmt);
+ vfprintf (stdout,fmt,ap);
+ va_end (ap);
+ fflush (stdout);
+}
+
+static NORETURN void showusage(bool error)
+{
+ fprintf (error ? stderr : stdout,
"\n"
"Flash Copy - Written by Abraham van der Merwe <abraham@2d3d.co.za>\n"
"\n"
@@ -110,44 +122,42 @@ static NORETURN void showusage(bool error)
static int safe_open (const char *pathname,int flags)
{
+ const char *access = "unknown";
int fd;
fd = open (pathname,flags);
if (fd < 0)
{
- log_printf (LOG_ERROR,"While trying to open %s",pathname);
if (flags & O_RDWR)
- log_printf (LOG_ERROR," for read/write access");
+ access = "read/write";
else if (flags & O_RDONLY)
- log_printf (LOG_ERROR," for read access");
+ access = "read";
else if (flags & O_WRONLY)
- log_printf (LOG_ERROR," for write access");
- log_printf (LOG_ERROR,": %m\n");
- exit (EXIT_FAILURE);
+ access = "write";
+
+ log_failure ("While trying to open %s for %s access: %m\n",pathname,access);
}
return (fd);
}
-static void safe_read (int fd,const char *filename,void *buf,size_t count,bool verbose)
+static void safe_read (int fd,const char *filename,void *buf,size_t count)
{
ssize_t result;
result = read (fd,buf,count);
if (count != result)
{
- if (verbose) log_printf (LOG_NORMAL,"\n");
+ log_verbose ("\n");
if (result < 0)
{
- log_printf (LOG_ERROR,"While reading data from %s: %m\n",filename);
- exit (EXIT_FAILURE);
+ log_failure("While reading data from %s: %m\n",filename);
}
- log_printf (LOG_ERROR,"Short read count returned while reading from %s\n",filename);
- exit (EXIT_FAILURE);
+ log_failure("Short read count returned while reading from %s\n",filename);
}
}
-static void safe_write (int fd,const void *buf,size_t count,size_t written,unsigned long long to_write,const char *device,bool verbose)
+static void safe_write (int fd,const void *buf,size_t count,size_t written,unsigned long long to_write,const char *device)
{
ssize_t result;
@@ -155,18 +165,14 @@ static void safe_write (int fd,const void *buf,size_t count,size_t written,unsig
result = write (fd,buf,count);
if (count != result)
{
- if (verbose) log_printf (LOG_NORMAL,"\n");
+ log_verbose ("\n");
if (result < 0)
{
- log_printf (LOG_ERROR,
- "While writing data to 0x%.8lx-0x%.8lx on %s: %m\n",
+ log_failure("While writing data to 0x%.8lx-0x%.8lx on %s: %m\n",
written,written + count,device);
- exit (EXIT_FAILURE);
}
- log_printf (LOG_ERROR,
- "Short write count returned while writing to x%.8zx-0x%.8zx on %s: %zu/%llu bytes written to flash\n",
+ log_failure("Short write count returned while writing to x%.8zx-0x%.8zx on %s: %zu/%llu bytes written to flash\n",
written,written + count,device,written + result,to_write);
- exit (EXIT_FAILURE);
}
}
@@ -177,8 +183,7 @@ static off_t safe_lseek (int fd,off_t offset,int whence,const char *filename)
off = lseek (fd,offset,whence);
if (off < 0)
{
- log_printf (LOG_ERROR,"While seeking on %s: %m\n",filename);
- exit (EXIT_FAILURE);
+ log_failure("While seeking on %s: %m\n",filename);
}
return off;
@@ -189,15 +194,13 @@ static void safe_rewind (int fd,const char *filename)
safe_lseek(fd,0L,SEEK_SET,filename);
}
-static void safe_memerase (int fd,const char *device,struct erase_info_user *erase,bool verbose)
+static void safe_memerase (int fd,const char *device,struct erase_info_user *erase)
{
if (ioctl (fd,MEMERASE,erase) < 0)
{
- if (verbose) log_printf (LOG_NORMAL,"\n");
- log_printf (LOG_ERROR,
- "While erasing blocks 0x%.8x-0x%.8x on %s: %m\n",
+ log_verbose ("\n");
+ log_failure("While erasing blocks 0x%.8x-0x%.8x on %s: %m\n",
(unsigned int) erase->start,(unsigned int) (erase->start + erase->length),device);
- exit (EXIT_FAILURE);
}
}
@@ -249,7 +252,7 @@ int main (int argc,char *argv[])
DEBUG("Got FLAG_HELP\n");
break;
case 'v':
- flags |= FLAG_VERBOSE;
+ verbose = 1;
DEBUG("Got FLAG_VERBOSE\n");
break;
case 'p':
@@ -289,24 +292,17 @@ int main (int argc,char *argv[])
if (ioctl (dev_fd,MEMGETINFO,&mtd) < 0)
{
DEBUG("ioctl(): %m\n");
- log_printf (LOG_ERROR,"This doesn't seem to be a valid MTD flash device!\n");
- exit (EXIT_FAILURE);
+ log_failure("This doesn't seem to be a valid MTD flash device!\n");
}
/* get some info about the file we want to copy */
fil_fd = safe_open (filename,O_RDONLY);
if (fstat (fil_fd,&filestat) < 0)
- {
- log_printf (LOG_ERROR,"While trying to get the file status of %s: %m\n",filename);
- exit (EXIT_FAILURE);
- }
+ log_failure("While trying to get the file status of %s: %m\n",filename);
/* does it fit into the device/partition? */
if (filestat.st_size > mtd.size)
- {
- log_printf (LOG_ERROR,"%s won't fit into %s!\n",filename,device);
- exit (EXIT_FAILURE);
- }
+ log_failure("%s won't fit into %s!\n",filename,device);
/* diff block flashcp */
if (flags & FLAG_PARTITION)
@@ -332,24 +328,24 @@ int main (int argc,char *argv[])
erase.length *= mtd.erasesize;
}
- if (flags & FLAG_VERBOSE)
+ if (verbose)
{
/* if the user wants verbose output, erase 1 block at a time and show him/her what's going on */
int blocks = erase.length / mtd.erasesize;
erase.length = mtd.erasesize;
- log_printf (LOG_NORMAL,"Erasing blocks: 0/%d (0%%)",blocks);
+ log_verbose ("Erasing blocks: 0/%d (0%%)",blocks);
for (i = 1; i <= blocks; i++)
{
- log_printf (LOG_NORMAL,"\rErasing blocks: %d/%d (%d%%)",i,blocks,PERCENTAGE (i,blocks));
- safe_memerase(dev_fd,device,&erase,flags & FLAG_VERBOSE);
+ log_verbose ("\rErasing blocks: %d/%d (%d%%)",i,blocks,PERCENTAGE (i,blocks));
+ safe_memerase(dev_fd,device,&erase);
erase.start += mtd.erasesize;
}
- log_printf (LOG_NORMAL,"\rErasing blocks: %d/%d (100%%)\n",blocks,blocks);
+ log_verbose ("\rErasing blocks: %d/%d (100%%)\n",blocks,blocks);
}
else
{
/* if not, erase the whole chunk in one shot */
- safe_memerase(dev_fd,device,&erase,flags & FLAG_VERBOSE);
+ safe_memerase(dev_fd,device,&erase);
}
DEBUG("Erased %u / %luk bytes\n",erase.length,filestat.st_size);
@@ -357,33 +353,30 @@ int main (int argc,char *argv[])
* write the entire file to flash *
**********************************/
- if (flags & FLAG_VERBOSE) log_printf (LOG_NORMAL,"Writing data: 0k/%lluk (0%%)",KB ((unsigned long long)filestat.st_size));
+ log_verbose ("Writing data: 0k/%lluk (0%%)",KB ((unsigned long long)filestat.st_size));
size = filestat.st_size;
i = BUFSIZE;
written = 0;
while (size)
{
if (size < BUFSIZE) i = size;
- if (flags & FLAG_VERBOSE)
- log_printf (LOG_NORMAL,"\rWriting data: %dk/%lluk (%llu%%)",
- KB (written + i),
- KB ((unsigned long long)filestat.st_size),
- PERCENTAGE (written + i,(unsigned long long)filestat.st_size));
+ log_verbose ("\rWriting data: %dk/%lluk (%llu%%)",
+ KB (written + i),
+ KB ((unsigned long long)filestat.st_size),
+ PERCENTAGE (written + i,(unsigned long long)filestat.st_size));
/* read from filename */
- safe_read (fil_fd,filename,src,i,flags & FLAG_VERBOSE);
+ safe_read (fil_fd,filename,src,i);
/* write to device */
- safe_write(dev_fd,src,i,written,(unsigned long long)filestat.st_size,device,flags & FLAG_VERBOSE);
+ safe_write(dev_fd,src,i,written,(unsigned long long)filestat.st_size,device);
written += i;
size -= i;
}
- if (flags & FLAG_VERBOSE)
- log_printf (LOG_NORMAL,
- "\rWriting data: %lluk/%lluk (100%%)\n",
- KB ((unsigned long long)filestat.st_size),
- KB ((unsigned long long)filestat.st_size));
+ log_verbose ("\rWriting data: %lluk/%lluk (100%%)\n",
+ KB ((unsigned long long)filestat.st_size),
+ KB ((unsigned long long)filestat.st_size));
DEBUG("Wrote %d / %lluk bytes\n",written,(unsigned long long)filestat.st_size);
/**********************************
@@ -395,40 +388,32 @@ int main (int argc,char *argv[])
size = filestat.st_size;
i = BUFSIZE;
written = 0;
- if (flags & FLAG_VERBOSE) log_printf (LOG_NORMAL,"Verifying data: 0k/%lluk (0%%)",KB ((unsigned long long)filestat.st_size));
+ log_verbose ("Verifying data: 0k/%lluk (0%%)",KB ((unsigned long long)filestat.st_size));
while (size)
{
if (size < BUFSIZE) i = size;
- if (flags & FLAG_VERBOSE)
- log_printf (LOG_NORMAL,
- "\rVerifying data: %luk/%lluk (%llu%%)",
- KB (written + i),
- KB ((unsigned long long)filestat.st_size),
- PERCENTAGE (written + i,(unsigned long long)filestat.st_size));
+ log_verbose ("\rVerifying data: %luk/%lluk (%llu%%)",
+ KB (written + i),
+ KB ((unsigned long long)filestat.st_size),
+ PERCENTAGE (written + i,(unsigned long long)filestat.st_size));
/* read from filename */
- safe_read (fil_fd,filename,src,i,flags & FLAG_VERBOSE);
+ safe_read (fil_fd,filename,src,i);
/* read from device */
- safe_read (dev_fd,device,dest,i,flags & FLAG_VERBOSE);
+ safe_read (dev_fd,device,dest,i);
/* compare buffers */
if (memcmp (src,dest,i))
- {
- log_printf (LOG_ERROR,
- "File does not seem to match flash data. First mismatch at 0x%.8zx-0x%.8zx\n",
+ log_failure("File does not seem to match flash data. First mismatch at 0x%.8zx-0x%.8zx\n",
written,written + i);
- exit (EXIT_FAILURE);
- }
written += i;
size -= i;
}
- if (flags & FLAG_VERBOSE)
- log_printf (LOG_NORMAL,
- "\rVerifying data: %lluk/%lluk (100%%)\n",
- KB ((unsigned long long)filestat.st_size),
- KB ((unsigned long long)filestat.st_size));
+ log_verbose ("\rVerifying data: %lluk/%lluk (100%%)\n",
+ KB ((unsigned long long)filestat.st_size),
+ KB ((unsigned long long)filestat.st_size));
DEBUG("Verified %d / %lluk bytes\n",written,(unsigned long long)filestat.st_size);
exit (EXIT_SUCCESS);
@@ -450,22 +435,18 @@ DIFF_BLOCKS:
int blocks = erase.length / mtd.erasesize;
erase.length = mtd.erasesize;
- if (flags & FLAG_VERBOSE)
- log_printf (LOG_NORMAL,
- "\rProcessing blocks: 0/%d (%d%%)", blocks, PERCENTAGE (0,blocks));
+ log_verbose ("\rProcessing blocks: 0/%d (%d%%)", blocks, PERCENTAGE (0,blocks));
for (int s = 1; s <= blocks; s++)
{
if (size < mtd.erasesize) i = size;
- if (flags & FLAG_VERBOSE)
- log_printf (LOG_NORMAL,
- "\rProcessing blocks: %d/%d (%d%%)", s, blocks, PERCENTAGE (s,blocks));
+ log_verbose ("\rProcessing blocks: %d/%d (%d%%)", s, blocks, PERCENTAGE (s,blocks));
/* read from filename */
- safe_read (fil_fd,filename,src,i,flags & FLAG_VERBOSE);
+ safe_read (fil_fd,filename,src,i);
/* read from device */
current_dev_block = safe_lseek(dev_fd, 0, SEEK_CUR, device);
- safe_read (dev_fd,device,dest,i,flags & FLAG_VERBOSE);
+ safe_read (dev_fd,device,dest,i);
/* compare buffers, if not the same, erase and write the block */
if (memcmp (src,dest,i))
@@ -473,11 +454,11 @@ DIFF_BLOCKS:
diffBlock++;
/* erase block */
safe_lseek(dev_fd, current_dev_block, SEEK_SET, device);
- safe_memerase(dev_fd,device,&erase,flags & FLAG_VERBOSE);
+ safe_memerase(dev_fd,device,&erase);
/* write to device */
safe_lseek(dev_fd, current_dev_block, SEEK_SET, device);
- safe_write(dev_fd,src,i,written,(unsigned long long)filestat.st_size,device,flags & FLAG_VERBOSE);
+ safe_write(dev_fd,src,i,written,(unsigned long long)filestat.st_size,device);
}
erase.start += i;
@@ -485,7 +466,7 @@ DIFF_BLOCKS:
size -= i;
}
- if (flags & FLAG_VERBOSE) log_printf (LOG_NORMAL, "\ndiff blocks: %d\n", diffBlock);
+ log_verbose ("\ndiff blocks: %d\n", diffBlock);
exit (EXIT_SUCCESS);
}