integrate bsdiff into imgdiff, instead of using subprocess

Integrate the bsdiff code into imgdiff so we can just call it rather
than writing temp files and invoking bsdiff as a subprocess.  When
computing multiple patches from the same source file, we can also save
time by doing some bsdiff preprocessing on the source file only once.

(Note this renames the existing 'bsdiff.c' -- which actually does
patching in applypatch -- to 'bspatch.c', and introduces a new
bsdiff.c linked into imgdiff.)
diff --git a/tools/applypatch/imgdiff.c b/tools/applypatch/imgdiff.c
index 5386d9b..38e3c83 100644
--- a/tools/applypatch/imgdiff.c
+++ b/tools/applypatch/imgdiff.c
@@ -134,6 +134,8 @@
   size_t source_start;
   size_t source_len;
 
+  off_t* I;             // used by bsdiff
+
   // --- for CHUNK_DEFLATE chunks only: ---
 
   // original (compressed) deflate data
@@ -167,6 +169,10 @@
   }
 }
 
+// from bsdiff.c
+int bsdiff(u_char* old, off_t oldsize, off_t** IP, u_char* new, off_t newsize,
+           const char* patch_filename);
+
 unsigned char* ReadZip(const char* filename,
                        int* num_chunks, ImageChunk** chunks,
                        int include_pseudo_chunk) {
@@ -278,6 +284,7 @@
     curr->len = st.st_size;
     curr->data = img;
     curr->filename = NULL;
+    curr->I = NULL;
     ++curr;
     ++*num_chunks;
   }
@@ -292,6 +299,7 @@
       curr->deflate_len = temp_entries[nextentry].deflate_len;
       curr->deflate_data = img + pos;
       curr->filename = temp_entries[nextentry].filename;
+      curr->I = NULL;
 
       curr->len = temp_entries[nextentry].uncomp_len;
       curr->data = malloc(curr->len);
@@ -336,6 +344,7 @@
     }
     curr->data = img + pos;
     curr->filename = NULL;
+    curr->I = NULL;
     pos += curr->len;
 
     ++*num_chunks;
@@ -400,6 +409,7 @@
       curr->type = CHUNK_NORMAL;
       curr->len = GZIP_HEADER_LEN;
       curr->data = p;
+      curr->I = NULL;
 
       pos += curr->len;
       p += curr->len;
@@ -407,6 +417,7 @@
 
       curr->type = CHUNK_DEFLATE;
       curr->filename = NULL;
+      curr->I = NULL;
 
       // We must decompress this chunk in order to discover where it
       // ends, and so we can put the uncompressed data and its length
@@ -452,6 +463,7 @@
       curr->start = pos;
       curr->len = GZIP_FOOTER_LEN;
       curr->data = img+pos;
+      curr->I = NULL;
 
       pos += curr->len;
       p += curr->len;
@@ -475,6 +487,7 @@
       *chunks = realloc(*chunks, *num_chunks * sizeof(ImageChunk));
       ImageChunk* curr = *chunks + (*num_chunks-1);
       curr->start = pos;
+      curr->I = NULL;
 
       // 'pos' is not the offset of the start of a gzip chunk, so scan
       // forward until we find a gzip header.
@@ -591,43 +604,12 @@
     }
   }
 
-  char stemp[] = "/tmp/imgdiff-src-XXXXXX";
-  char ttemp[] = "/tmp/imgdiff-tgt-XXXXXX";
   char ptemp[] = "/tmp/imgdiff-patch-XXXXXX";
-  mkstemp(stemp);
-  mkstemp(ttemp);
   mkstemp(ptemp);
 
-  FILE* f = fopen(stemp, "wb");
-  if (f == NULL) {
-    fprintf(stderr, "failed to open src chunk %s: %s\n",
-            stemp, strerror(errno));
-    return NULL;
-  }
-  if (fwrite(src->data, 1, src->len, f) != src->len) {
-    fprintf(stderr, "failed to write src chunk to %s: %s\n",
-            stemp, strerror(errno));
-    return NULL;
-  }
-  fclose(f);
-
-  f = fopen(ttemp, "wb");
-  if (f == NULL) {
-    fprintf(stderr, "failed to open tgt chunk %s: %s\n",
-            ttemp, strerror(errno));
-    return NULL;
-  }
-  if (fwrite(tgt->data, 1, tgt->len, f) != tgt->len) {
-    fprintf(stderr, "failed to write tgt chunk to %s: %s\n",
-            ttemp, strerror(errno));
-    return NULL;
-  }
-  fclose(f);
-
-  char cmd[200];
-  sprintf(cmd, "bsdiff %s %s %s", stemp, ttemp, ptemp);
-  if (system(cmd) != 0) {
-    fprintf(stderr, "failed to run bsdiff: %s\n", strerror(errno));
+  int r = bsdiff(src->data, src->len, &(src->I), tgt->data, tgt->len, ptemp);
+  if (r != 0) {
+    fprintf(stderr, "bsdiff() failed: %d\n", r);
     return NULL;
   }
 
@@ -641,8 +623,6 @@
   unsigned char* data = malloc(st.st_size);
 
   if (tgt->type == CHUNK_NORMAL && tgt->len <= st.st_size) {
-    unlink(stemp);
-    unlink(ttemp);
     unlink(ptemp);
 
     tgt->type = CHUNK_RAW;
@@ -652,7 +632,7 @@
 
   *size = st.st_size;
 
-  f = fopen(ptemp, "rb");
+  FILE* f = fopen(ptemp, "rb");
   if (f == NULL) {
     fprintf(stderr, "failed to open patch %s: %s\n", ptemp, strerror(errno));
     return NULL;
@@ -663,8 +643,6 @@
   }
   fclose(f);
 
-  unlink(stemp);
-  unlink(ttemp);
   unlink(ptemp);
 
   tgt->source_start = src->start;