+ outbuf = malloc(remaining);
+ if (outbuf == NULL) {
+ xlog(L_ERROR, "Failed to delete: no memory");
+ goto out;
+ }
+
+ f = fopen(path, "r");
+ if (f == NULL) {
+ xlog(L_ERROR, "Failed to delete: "
+ "could not open original file %s: %m", path);
+ goto out;
+ }
+
+ /*
+ * Walk the records in the file, and copy the non-matching
+ * ones to our output buffer.
+ */
+ next = outbuf;
+ while (fgets(line, (int)sizeof(line), f) != NULL) {
+ struct sockaddr_in sin;
+ struct mon m;
+ size_t len;
+
+ if (!nsm_parse_line(line, &sin, &m)) {
+ xlog(L_ERROR, "Failed to delete: "
+ "could not parse original file %s", path);
+ (void)fclose(f);
+ goto out;
+ }
+
+ if (strcmp(mon_name, m.mon_id.mon_name) == 0 &&
+ strcmp(my_name, m.mon_id.my_id.my_name) == 0)
+ continue;
+
+ /* nsm_parse_line destroys the contents of line[], so
+ * reconstruct the copy in our output buffer. */
+ len = nsm_create_monitor_record(next, remaining,
+ (struct sockaddr *)(char *)&sin, &m);
+ if (len == 0) {
+ xlog(L_ERROR, "Failed to delete: "
+ "could not construct output record");
+ (void)fclose(f);
+ goto out;
+ }
+ next += len;
+ remaining -= len;
+ }
+
+ (void)fclose(f);
+
+ /*
+ * If nothing was copied when we're done, then unlink the file.
+ * Otherwise, atomically update the contents of the file.
+ */
+ if (next != outbuf) {
+ if (!nsm_atomic_write(path, outbuf, strlen(outbuf)))
+ xlog(L_ERROR, "Failed to delete: "
+ "could not write new file %s: %m", path);
+ } else {
+ if (unlink(path) == -1)
+ xlog(L_ERROR, "Failed to delete: "
+ "could not unlink file %s: %m", path);
+ }
+
+out:
+ free(outbuf);