Example #1
0
int createq(queue_t *q, unsigned packets)
{
  if (0 == (q->packets = calloc(packets, sizeof *q->packets))) {
    seterror(err_NM);
    return 0;
  }

  if (!createlock(&q->lock)) {
    return 0;
  }
  q->n = packets;
  q->s = 0;
  q->packetlist = 0;
  q->len = 0;
  q->bytes_sent = 0;
  q->buffertime = 0;
  q->deadline = 0;

  return 1;
}
Example #2
0
int
deliver_mbox_deliver(struct deliver_ctx *dctx, struct actitem *ti)
{
    struct account			*a = dctx->account;
    struct mail			*m = dctx->mail;
    struct deliver_mbox_data	*data = ti->data;
    char				*path, *ptr, *lptr, *from = NULL;
    const char			*msg;
    size_t				 len, llen;
    int				 fd, saved_errno;
    FILE				*f;
    gzFile				 gzf;
    long long			 used;
    sigset_t			 set, oset;
    struct stat			 sb;

    f = gzf = NULL;
    fd = -1;

    path = replacepath(&data->path, m->tags, m, &m->rml, dctx->udata->home);
    if (path == NULL || *path == '\0') {
        log_warnx("%s: empty path", a->name);
        goto error;
    }
    if (data->compress) {
        len = strlen(path);
        if (len < 3 || strcmp(path + len - 3, ".gz") != 0) {
            path = xrealloc(path, 1, len + 4);
            strlcat(path, ".gz", len + 4);
        }
    }
    log_debug2("%s: saving to mbox %s", a->name, path);

    /* Save the mbox path. */
    add_tag(&m->tags, "mbox_file", "%s", path);

    /* Check permissions and ownership. */
    if (stat(path, &sb) != 0) {
        if (conf.no_create || errno != ENOENT)
            goto error_log;

        log_debug2("%s: creating %s", a->name, xdirname(path));
        if (xmkpath(xdirname(path), -1, conf.file_group, DIRMODE) != 0)
            goto error_log;
    } else {
        if ((msg = checkmode(&sb, UMASK(FILEMODE))) != NULL)
            log_warnx("%s: %s: %s", a->name, path, msg);
        if ((msg = checkowner(&sb, -1)) != NULL)
            log_warnx("%s: %s: %s", a->name, path, msg);
        if ((msg = checkgroup(&sb, conf.file_group)) != NULL)
            log_warnx("%s: %s: %s", a->name, path, msg);
    }

    /* Create or open the mbox. */
    used = 0;
    do {
        if (conf.no_create)
            fd = openlock(path, O_WRONLY|O_APPEND, conf.lock_types);
        else {
            fd = createlock(path, O_WRONLY|O_APPEND,
                            -1, conf.file_group, FILEMODE, conf.lock_types);
        }
        if (fd == -1 && errno == EEXIST)
            fd = openlock(path, O_WRONLY|O_APPEND, conf.lock_types);
        if (fd == -1) {
            if (errno == EAGAIN) {
                if (locksleep(a->name, path, &used) != 0)
                    goto error;
                continue;
            }
            goto error_log;
        }
    } while (fd < 0);

    /* Open gzFile or FILE * for writing. */
    if (data->compress) {
        if ((gzf = gzdopen(fd, "a")) == NULL) {
            errno = ENOMEM;
            goto error_log;
        }
    } else {
        if ((f = fdopen(fd, "a")) == NULL)
            goto error_log;
    }

    /*
     * mboxes are a pain: if we are interrupted after this we risk
     * having written a partial mail. So, block SIGTERM until we're
     * done.
     */
    sigemptyset(&set);
    sigaddset(&set, SIGTERM);
    if (sigprocmask(SIG_BLOCK, &set, &oset) < 0)
        fatal("sigprocmask failed");

    /* Write the from line. */
    from = make_from(m, dctx->udata->name);
    if (deliver_mbox_write(f, gzf, from, strlen(from)) < 0) {
        xfree(from);
        goto error_unblock;
    }
    if (deliver_mbox_write(f, gzf, "\n", 1) < 0) {
        xfree(from);
        goto error_unblock;
    }
    log_debug3("%s: using from line: %s", a->name, from);
    xfree(from);

    /* Write the mail, escaping from lines. */
    line_init(m, &ptr, &len);
    while (ptr != NULL) {
        if (ptr != m->data) {
            /* Skip leading >s. */
            lptr = ptr;
            llen = len;
            while (*lptr == '>' && llen > 0) {
                lptr++;
                llen--;
            }

            if (llen >= 5 && strncmp(lptr, "From ", 5) == 0) {
                log_debug2("%s: quoting from line: %.*s",
                           a->name, (int) len - 1, ptr);
                if (deliver_mbox_write(f, gzf, ">", 1) < 0)
                    goto error_unblock;
            }
        }

        if (deliver_mbox_write(f, gzf, ptr, len) < 0)
            goto error_unblock;

        line_next(m, &ptr, &len);
    }

    /* Append newlines. */
    if (m->data[m->size - 1] == '\n') {
        if (deliver_mbox_write(f, gzf, "\n", 1) < 0)
            goto error_unblock;
    } else {
        if (deliver_mbox_write(f, gzf, "\n\n", 2) < 0)
            goto error_unblock;
    }

    /* Flush buffers and sync. */
    if (gzf == NULL) {
        if (fflush(f) != 0)
            goto error_unblock;
    } else {
        if (gzflush(gzf, Z_FINISH) != Z_OK) {
            errno = EIO;
            goto error_unblock;
        }
    }
    if (fsync(fd) != 0)
        goto error_unblock;

    if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0)
        fatal("sigprocmask failed");

    if (gzf != NULL)
        gzclose(gzf);
    if (f != NULL)
        fclose(f);
    closelock(fd, path, conf.lock_types);

    xfree(path);
    return (DELIVER_SUCCESS);

error_unblock:
    saved_errno = errno;
    if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0)
        fatal("sigprocmask failed");
    errno = saved_errno;

error_log:
    log_warn("%s: %s", a->name, path);

error:
    if (gzf != NULL)
        gzclose(gzf);
    if (f != NULL)
        fclose(f);
    if (fd != -1)
        closelock(fd, path, conf.lock_types);

    if (path != NULL)
        xfree(path);
    return (DELIVER_FAILURE);
}
Example #3
0
int
chanopen(Chan *c, long nel, long elsz)
{
	Lock *l, *cl;
	Cond *da, *sa, *sc;
	uchar *buf;

	if(c == nil)
		return -1;
	if(c->status == Open){
		errorf("chanopen -- called on open channel\n");
		return -1;
	}
	l = createlock();
	if(l == nil){
		errorf("chanopen -- failed to alloc lock\n");
		return -1;
	}
	da = createcond();
	if(da == nil){
		errorf("chanopen -- createcond failed\n");
		freelock(l);
		return -1;
	}
	sa = createcond();
	if(sa == nil){
		errorf("chanopen -- createcond failed\n");
		freecond(da);
		freelock(l);
		return -1;
	}
	sc = createcond();
	if(sc == nil){
		errorf("chanopen -- createcond failed\n");
		freecond(sa);
		freecond(da);
		freelock(l);
		return -1;
	}
	if(nel > 0)
		buf = calloc(nel, elsz);
	else
		buf = calloc(1, elsz);
	if(buf == nil){
		errorf("chanopen -- failed to alloc channel buffer\n");
		freecond(sc);
		freecond(sa);
		freecond(da);
		freelock(l);
		return -1;
	}
	c->l = l;
	c->da = da;
	c->sa = sa;
	c->sc = sc;
	c->b = buf;
	c->elsz = elsz;
	c->sz = nel;
	c->s = 0;
	c->n = 0;
	c->recvbuf = nil;
	c->status = Open;
	return 0;
}