+static struct zipentry *
+find_entry (const char *fname)
+{
+ struct zipentry *ze;
+
+ for (ze = ziptail; ze; ze = ze->next_entry)
+ {
+ if (!strcmp (ze->filename, fname))
+ return ze;
+ }
+ return NULL;
+}
+
+
+static int
+looks_like_dir (const char *fname)
+{
+ struct zipentry *ze;
+ size_t len = strlen (fname);
+
+ for (ze = ziptail; ze; ze = ze->next_entry)
+ {
+ if (strlen (ze->filename) > len
+ && !strncmp (fname, ze->filename, len)
+ && ze->filename[len] == '/')
+ return 1;
+ }
+ return 0;
+}
+
+
+/*
+ * Read the zip entries of an existing file, building `ziplist' as we go.
+ */
+int read_entries (int fd)
+{
+ struct zipentry *ze;
+ ub1 intbuf[4];
+ ub1 header[46];
+ ub2 len;
+ ub2 count, i;
+ off_t offset;
+
+ if (lseek (fd, -22, SEEK_END) == -1)
+ {
+ fprintf (stderr, "%s: %s: can't seek file\n", progname, jarfile);
+ return 1;
+ }
+
+ if (read (fd, intbuf, 4) < 4)
+ {
+ perror (progname);
+ return 1;
+ }
+ /* Is there a zipfile comment? */
+ while (UNPACK_UB4(intbuf, 0) != 0x06054b50)
+ {
+ if (lseek (fd, -5, SEEK_CUR) == -1 ||
+ read (fd, intbuf, 4) != 4)
+ {
+ fprintf (stderr, "%s: can't find end of central directory: %s\n",
+ progname, strerror (errno));
+ return 1;
+ }
+ }
+
+ /* Skip disk numbers. */
+ if (lseek (fd, 6, SEEK_CUR) == -1)
+ {
+ perror (progname);
+ return 1;
+ }
+
+ /* Number of entries in the central directory. */
+ if (read (fd, intbuf, 2) != 2)
+ {
+ perror (progname);
+ return 1;
+ }
+ count = UNPACK_UB2(intbuf, 0);
+
+ if (lseek (fd, 4, SEEK_CUR) == -1)
+ {
+ perror (progname);
+ return 1;
+ }
+
+ /* Offset where the central directory begins. */
+ if (read (fd, intbuf, 4) != 4)
+ {
+ perror (progname);
+ return 1;
+ }
+ offset = UNPACK_UB4(intbuf, 0);
+ end_of_entries = offset;
+
+ if (lseek (fd, offset, SEEK_SET) != offset)
+ {
+ perror (progname);
+ return 1;
+ }
+
+ if (read (fd, header, 46) != 46)
+ {
+ fprintf (stderr, "%s: %s: unexpected end of file\n",
+ progname, jarfile);
+ return 1;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ if (UNPACK_UB4(header, 0) != 0x02014b50)
+ {
+ fprintf (stderr, "%s: can't find central directory header\n",
+ progname);
+ return 1;
+ }
+ ze = (struct zipentry *) malloc (sizeof (struct zipentry));
+ if (!ze)
+ {
+ perror (progname);
+ return 1;
+ }
+ memset (ze, 0, sizeof (struct zipentry));
+ ze->flags = UNPACK_UB2(header, CEN_FLAGS);
+ ze->mod_time = UNPACK_UB2(header, CEN_MODTIME);
+ ze->mod_date = UNPACK_UB2(header, CEN_MODDATE);
+ ze->crc = UNPACK_UB4(header, CEN_CRC);
+ ze->usize = UNPACK_UB4(header, CEN_USIZE);
+ ze->csize = UNPACK_UB4(header, CEN_CSIZE);
+ ze->offset = UNPACK_UB4(header, CEN_OFFSET);
+ ze->compressed = (header[CEN_COMP] || header[CEN_COMP+1]);
+ len = UNPACK_UB2(header, CEN_FNLEN);
+ ze->filename = (char *) malloc ((len+1) * sizeof (char));
+ if (!ze->filename)
+ {
+ perror (progname);
+ return 1;
+ }
+ if (read (fd, ze->filename, len) != len)
+ {
+ fprintf (stderr, "%s: %s: unexpected end of file\n",
+ progname, jarfile);
+ return 1;
+ }
+ len = UNPACK_UB4(header, CEN_EFLEN);
+ len += UNPACK_UB4(header, CEN_COMLEN);
+ if (lseek (fd, len, SEEK_CUR) == -1)
+ {
+ perror (progname);
+ return 1;
+ }
+ add_entry (ze);
+ if (i < count - 1)
+ {
+ if (read (fd, header, 46) != 46)
+ {
+ fprintf (stderr, "%s: %s: unexpected end of file\n",
+ progname, jarfile);
+ return 1;
+ }
+ }
+ }
+
+ lseek (fd, 0, SEEK_SET);
+ return 0;
+}
+
+int make_manifest(int jfd, const char *mf_name, int updating){