+ chmod(tmpfil, perms);
+
+ make_comp(&comp);
+
+ if (mode == MODE_DEL) {
+ dodel(fd, comp, text, tmp, number);
+ }
+ if (mode == MODE_ADD) {
+ doadd(fd, comp, text, tmp, datesw, append);
+ }
+
+ cpydata(fd, fileno(tmp), file, tmpfil);
+ fclose(tmp);
+
+ if ((tmpfd = open(tmpfil, O_RDONLY)) == NOTOK) {
+ adios(EX_IOERR, tmpfil, "unable to open for re-reading");
+ }
+ lseek(fd, (off_t) 0, SEEK_SET);
+
+ /*
+ ** We're making the file shorter if we're deleting a header field
+ ** so the file has to be truncated or it will contain garbage.
+ */
+ if (mode == MODE_DEL && ftruncate(fd, 0) == -1) {
+ adios(EX_IOERR, tmpfil, "unable to truncate.");
+ }
+ cpydata(tmpfd, fd, tmpfil, file);
+ close(tmpfd);
+ unlink(tmpfil);
+
+ if (preserve && utime(file, &b) == -1) {
+ advise("can't set access and modification times for %s", file);
+ }
+ lkclose(fd, file);
+ return 0;
+}
+
+/*
+** We're trying to delete a header field (annotation).
+**
+** - If number is greater than zero,
+** we're deleting the nth header field that matches
+** the field (component) name.
+** - If number is zero and text is NULL,
+** we're deleting the first field in which the field name
+** matches the component name.
+** - If number is zero and text is set,
+** we're deleting the first field in which both the field name
+** matches the component name and the field body matches the text.
+** - If number is -1,
+** we delete all matching fields.
+*/
+static void
+dodel(int fd, unsigned char *comp, char *text, FILE *tmp, int number)
+{
+ int length = strlen(comp); /* convenience copy */
+ int count = 1; /* Number of matching header line. */
+ int c, n;
+ char *cp;
+ char *field = NULL;
+ int field_size = 256;
+ FILE *fp;