+static int
+writequeuef(struct qitem *it)
+{
+ int error;
+ int queuefd;
+
+ queuefd = open_locked(it->queuefn, O_CREAT|O_EXCL|O_RDWR, 0660);
+ if (queuefd == -1)
+ return (-1);
+ if (fchmod(queuefd, 0660) < 0)
+ return (-1);
+ it->queuef = fdopen(queuefd, "w+");
+ if (it->queuef == NULL)
+ return (-1);
+
+ error = fprintf(it->queuef,
+ "ID: %s\n"
+ "Sender: %s\n"
+ "Recipient: %s\n",
+ it->queueid,
+ it->sender,
+ it->addr);
+
+ if (error <= 0)
+ return (-1);
+
+ if (fflush(it->queuef) != 0 || fsync(fileno(it->queuef)) != 0)
+ return (-1);
+
+ return (0);
+}
+
+static struct qitem *
+readqueuef(struct queue *queue, char *queuefn)
+{
+ char line[1000];
+ struct queue itmqueue;
+ FILE *queuef = NULL;
+ char *s;
+ char *queueid = NULL, *sender = NULL, *addr = NULL;
+ struct qitem *it = NULL;
+
+ bzero(&itmqueue, sizeof(itmqueue));
+ LIST_INIT(&itmqueue.queue);
+
+ queuef = fopen(queuefn, "r");
+ if (queuef == NULL)
+ goto out;
+
+ while (!feof(queuef)) {
+ if (fgets(line, sizeof(line), queuef) == NULL || line[0] == 0)
+ break;
+ line[strlen(line) - 1] = 0; /* chop newline */
+
+ s = strchr(line, ':');
+ if (s == NULL)
+ goto malformed;
+ *s = 0;
+
+ s++;
+ while (isspace(*s))
+ s++;
+
+ s = strdup(s);
+ if (s == NULL)
+ goto malformed;
+
+ if (strcmp(line, "ID") == 0) {
+ queueid = s;
+ } else if (strcmp(line, "Sender") == 0) {
+ sender = s;
+ } else if (strcmp(line, "Recipient") == 0) {
+ addr = s;
+ } else {
+ syslog(LOG_DEBUG, "ignoring unknown queue info `%s' in `%s'",
+ line, queuefn);
+ free(s);
+ }
+ }
+
+ if (queueid == NULL || sender == NULL || addr == NULL ||
+ *queueid == 0 || *addr == 0) {
+malformed:
+ errno = EINVAL;
+ syslog(LOG_ERR, "malformed queue file `%s'", queuefn);
+ goto out;
+ }
+
+ if (add_recp(&itmqueue, addr, 0) != 0)
+ goto out;
+
+ it = LIST_FIRST(&itmqueue.queue);
+ it->sender = sender; sender = NULL;
+ it->queueid = queueid; queueid = NULL;
+ it->queuefn = queuefn; queuefn = NULL;
+ LIST_INSERT_HEAD(&queue->queue, it, next);
+
+out:
+ if (sender != NULL)
+ free(sender);
+ if (queueid != NULL)
+ free(queueid);
+ if (addr != NULL)
+ free(addr);
+ if (queuef != NULL)
+ fclose(queuef);
+
+ return (it);
+}
+