コード例 #1
0
ファイル: times.c プロジェクト: gnb/cyrus-imapd
/*
 * Test time_to_rfc822()
 */
static void test_gen_rfc822(void)
{
    static const char DATETIME_MEL[] = "Fri, 26 Nov 2010 14:22:02 +1100";
    static const char DATETIME_UTC[] = "Fri, 26 Nov 2010 03:22:02 +0000";
    static const char DATETIME_NYC[] = "Thu, 25 Nov 2010 22:22:02 -0500";
    static const time_t TIMET = 1290741722;
    int r;
    char buf[RFC822_DATETIME_MAX+1];

    memset(buf, 0x45, sizeof(buf));
    r = time_to_rfc822(TIMET, buf, sizeof(buf));
    CU_ASSERT_EQUAL(r, 31);
    CU_ASSERT_STRING_EQUAL(buf, DATETIME_MEL);

    push_tz(TZ_UTC);
    memset(buf, 0x45, sizeof(buf));
    r = time_to_rfc822(TIMET, buf, sizeof(buf));
    CU_ASSERT_EQUAL(r, 31);
    CU_ASSERT_STRING_EQUAL(buf, DATETIME_UTC);
    pop_tz();

    push_tz(TZ_NEWYORK);
    memset(buf, 0x45, sizeof(buf));
    r = time_to_rfc822(TIMET, buf, sizeof(buf));
    CU_ASSERT_EQUAL(r, 31);
    CU_ASSERT_STRING_EQUAL(buf, DATETIME_NYC);
    pop_tz();
}
コード例 #2
0
ファイル: mbtool.c プロジェクト: pmhahn/cyrus-imapd
/*
 * mboxlist_findall() callback function to examine a mailbox
 */
static int do_timestamp(char *name)
{
    unsigned recno;
    int r = 0;
    char ext_name_buf[MAX_MAILBOX_PATH+1];
    struct mailbox *mailbox = NULL;
    struct index_record record;
    char olddate[RFC822_DATETIME_MAX+1];
    char newdate[RFC822_DATETIME_MAX+1];

    signals_poll();

    /* Convert internal name to external */
    (*recon_namespace.mboxname_toexternal)(&recon_namespace, name,
					   "cyrus", ext_name_buf);
    printf("Working on %s...\n", ext_name_buf);

    /* Open/lock header */
    r = mailbox_open_iwl(name, &mailbox);
    if (r) return r;

    for (recno = 1; recno <= mailbox->i.num_records; recno++) {
	r = mailbox_read_index_record(mailbox, recno, &record);
	if (r) goto done;

	if (record.system_flags & FLAG_EXPUNGED)
	    continue;

	/* 1 day is close enough */
	if (abs(record.internaldate - record.gmtime) < 86400)
	    continue;

	time_to_rfc822(record.internaldate, olddate, sizeof(olddate));
	time_to_rfc822(record.gmtime, newdate, sizeof(newdate));
	printf("  %u: %s => %s\n", record.uid, olddate, newdate);

	/* switch internaldate */
	record.internaldate = record.gmtime;

	r = mailbox_rewrite_index_record(mailbox, &record);
	if (r) goto done;
    }

 done:
    mailbox_close(&mailbox);

    return r;
}
コード例 #3
0
ファイル: mbtool.c プロジェクト: Distrotech/cyrus-imapd
/*
 * mboxlist_findall() callback function to examine a mailbox
 */
static int do_timestamp(const char *name)
{
    int r = 0;
    char ext_name_buf[MAX_MAILBOX_PATH+1];
    struct mailbox *mailbox = NULL;
    const struct index_record *record;
    char olddate[RFC822_DATETIME_MAX+1];
    char newdate[RFC822_DATETIME_MAX+1];

    signals_poll();

    /* Convert internal name to external */
    (*recon_namespace.mboxname_toexternal)(&recon_namespace, name,
                                           "cyrus", ext_name_buf);
    printf("Working on %s...\n", ext_name_buf);

    /* Open/lock header */
    r = mailbox_open_iwl(name, &mailbox);
    if (r) return r;

    struct mailbox_iter *iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_EXPUNGED);
    while ((record = mailbox_iter_step(iter))) {
        /* 1 day is close enough */
        if (labs(record->internaldate - record->gmtime) < 86400)
            continue;

        struct index_record copyrecord = *record;

        time_to_rfc822(copyrecord.internaldate, olddate, sizeof(olddate));
        time_to_rfc822(copyrecord.gmtime, newdate, sizeof(newdate));
        printf("  %u: %s => %s\n", copyrecord.uid, olddate, newdate);

        /* switch internaldate */
        copyrecord.internaldate = copyrecord.gmtime;

        r = mailbox_rewrite_index_record(mailbox, &copyrecord);
        if (r) goto done;
    }

 done:
    mailbox_iter_done(&iter);
    mailbox_close(&mailbox);

    return r;
}
コード例 #4
0
ファイル: lmtp_sieve.c プロジェクト: sebmichel/cyrus-imapd
static int send_rejection(const char *origid,
			  const char *rejto,
			  const char *origreceip, 
			  const char *mailreceip, 
			  const char *reason, 
			  struct protstream *file)
{
    FILE *sm;
    const char *smbuf[10];
    char buf[8192], *namebuf;
    int i, sm_stat;
    time_t t;
    char datestr[RFC822_DATETIME_MAX+1];
    pid_t sm_pid, p;
    duplicate_key_t dkey = DUPLICATE_INITIALIZER;

    smbuf[0] = "sendmail";
    smbuf[1] = "-i";		/* ignore dots */
    smbuf[2] = "-f";
    smbuf[3] = "<>";
    smbuf[4] = "--";
    smbuf[5] = rejto;
    smbuf[6] = NULL;
    sm_pid = open_sendmail(smbuf, &sm);
    if (sm == NULL) {
	return -1;
    }

    t = time(NULL);
    p = getpid();
    snprintf(buf, sizeof(buf), "<cmu-sieve-%d-%d-%d@%s>", (int) p, (int) t, 
	     global_outgoing_count++, config_servername);
    
    namebuf = make_sieve_db(mailreceip);

    time_to_rfc822(t, datestr, sizeof(datestr));

    dkey.id = buf;
    dkey.to = namebuf;
    dkey.date = datestr;
    duplicate_mark(&dkey, t, 0);

    fprintf(sm, "Message-ID: %s\r\n", buf);
    fprintf(sm, "Date: %s\r\n", datestr);

    fprintf(sm, "X-Sieve: %s\r\n", SIEVE_VERSION);
    fprintf(sm, "From: Mail Sieve Subsystem <%s>\r\n",
	    config_getstring(IMAPOPT_POSTMASTER));
    fprintf(sm, "To: <%s>\r\n", rejto);
    fprintf(sm, "MIME-Version: 1.0\r\n");
    fprintf(sm, "Content-Type: "
	    "multipart/report; report-type=disposition-notification;"
	    "\r\n\tboundary=\"%d/%s\"\r\n", (int) p, config_servername);
    fprintf(sm, "Subject: Automatically rejected mail\r\n");
    fprintf(sm, "Auto-Submitted: auto-replied (rejected)\r\n");
    fprintf(sm, "\r\nThis is a MIME-encapsulated message\r\n\r\n");

    /* this is the human readable status report */
    fprintf(sm, "--%d/%s\r\n", (int) p, config_servername);
    fprintf(sm, "Content-Type: text/plain; charset=utf-8\r\n");
    fprintf(sm, "Content-Disposition: inline\r\n");
    fprintf(sm, "Content-Transfer-Encoding: 8bit\r\n\r\n");

    fprintf(sm, "Your message was automatically rejected by Sieve, a mail\r\n"
	    "filtering language.\r\n\r\n");
    fprintf(sm, "The following reason was given:\r\n%s\r\n\r\n", reason);

    /* this is the MDN status report */
    fprintf(sm, "--%d/%s\r\n"
	    "Content-Type: message/disposition-notification\r\n\r\n",
	    (int) p, config_servername);
    fprintf(sm, "Reporting-UA: %s; Cyrus %s/%s\r\n",
	    config_servername, cyrus_version(), SIEVE_VERSION);
    if (origreceip)
	fprintf(sm, "Original-Recipient: rfc822; %s\r\n", origreceip);
    fprintf(sm, "Final-Recipient: rfc822; %s\r\n", mailreceip);
    if (origid)
	fprintf(sm, "Original-Message-ID: %s\r\n", origid);
    fprintf(sm, "Disposition: "
	    "automatic-action/MDN-sent-automatically; deleted\r\n");
    fprintf(sm, "\r\n");

    /* this is the original message */
    fprintf(sm, "--%d/%s\r\nContent-Type: message/rfc822\r\n\r\n",
	    (int) p, config_servername);
    prot_rewind(file);
    while ((i = prot_read(file, buf, sizeof(buf))) > 0) {
	fwrite(buf, i, 1, sm);
    }
    fprintf(sm, "\r\n\r\n");
    fprintf(sm, "--%d/%s--\r\n", (int) p, config_servername);

    fclose(sm);
    while (waitpid(sm_pid, &sm_stat, 0) < 0);

    return sm_stat;	/* sendmail exit value */
}
コード例 #5
0
ファイル: lmtpengine.c プロジェクト: gnb/cyrus-imapd
/*
 * file in the message structure 'm' from 'pin', assuming a dot-stuffed
 * stream a la lmtp.
 *
 * returns 0 on success, imap error code on failure
 */
static int savemsg(struct clientdata *cd,
		   const struct lmtp_func *func,
		   message_data_t *m)
{
    FILE *f;
    struct stat sbuf;
    const char **body;
    int r;
    int nrcpts = m->rcpt_num;
    time_t now = time(NULL);
    static unsigned msgid_count = 0;
    char datestr[RFC822_DATETIME_MAX+1], tls_info[250] = "";
    const char *skipheaders[] = {
	"Return-Path",  /* need to remove (we add our own) */
	NULL
    };
    char *addbody, *fold[5], *p;
    int addlen, nfold, i;

    /* Copy to spool file */
    f = func->spoolfile(m);
    if (!f) {
	prot_printf(cd->pout, 
		    "451 4.3.%c cannot create temporary file: %s\r\n",
		    (
#ifdef EDQUOT
			errno == EDQUOT ||
#endif
			errno == ENOSPC) ? '1' : '2',
		    error_message(errno));
	return IMAP_IOERROR;
    }

    prot_printf(cd->pout, "354 go ahead\r\n");

    if (m->return_path && func->addretpath) { /* add the return path */
	char *rpath = m->return_path;
	const char *hostname = 0;

	clean_retpath(rpath);
	/* Append our hostname if there's no domain in address */
	hostname = NULL;
	if (!strchr(rpath, '@') && strlen(rpath) > 0) {
	    hostname = config_servername;
	}

	addlen = 2 + strlen(rpath) + (hostname ? 1 + strlen(hostname) : 0);
	addbody = xmalloc(addlen + 1);
	sprintf(addbody, "<%s%s%s>",
		rpath, hostname ? "@" : "", hostname ? hostname : "");
	fprintf(f, "Return-Path: %s\r\n", addbody);
	spool_cache_header(xstrdup("Return-Path"), addbody, m->hdrcache);
    }

    /* add a received header */
    time_to_rfc822(now, datestr, sizeof(datestr));
    addlen = 8 + strlen(cd->lhlo_param) + strlen(cd->clienthost);
    if (m->authuser) addlen += 28 + strlen(m->authuser) + 5; /* +5 for ssf */
    addlen += 25 + strlen(config_servername) + strlen(cyrus_version());
#ifdef HAVE_SSL
    if (cd->tls_conn) {
	addlen += 3 + tls_get_info(cd->tls_conn, tls_info, sizeof(tls_info));
    }
#endif
    addlen += 2 + strlen(datestr);
    p = addbody = xmalloc(addlen + 1);

    nfold = 0;
    p += sprintf(p, "from %s (%s)", cd->lhlo_param, cd->clienthost);
    fold[nfold++] = p;
    if (m->authuser) {
	const void *ssfp;
	sasl_ssf_t ssf;
	sasl_getprop(cd->conn, SASL_SSF, &ssfp);
	ssf = *((sasl_ssf_t *) ssfp);
	p += sprintf(p, " (authenticated user=%s bits=%d)", m->authuser, ssf);
	fold[nfold++] = p;
    }

    /* We are always atleast "with LMTPA" -- no unauth delivery */
    p += sprintf(p, " by %s", config_servername);
    if (config_serverinfo == IMAP_ENUM_SERVERINFO_ON) {
	p += sprintf(p, " (Cyrus %s)", cyrus_version());
    }
    p += sprintf(p, " with LMTP%s%s",
		 cd->starttls_done ? "S" : "",
		 cd->authenticated != NOAUTH ? "A" : "");

    if (*tls_info) {
	fold[nfold++] = p;
	p += sprintf(p, " (%s)", tls_info);
    }

    strcat(p++, ";");
    fold[nfold++] = p;
    p += sprintf(p, " %s", datestr);
 
    fprintf(f, "Received: ");
    for (i = 0, p = addbody; i < nfold; p = fold[i], i++) {
	fprintf(f, "%.*s\r\n\t", (int) (fold[i] - p), p);
    }
    fprintf(f, "%s\r\n", p);
    spool_cache_header(xstrdup("Received"), addbody, m->hdrcache);

    /* add any requested headers */
    if (func->addheaders) {
	struct addheader *h;
	for (h = func->addheaders; h && h->name; h++) {
	    fprintf(f, "%s: %s\r\n", h->name, h->body);
	    spool_cache_header(xstrdup(h->name), xstrdup(h->body), m->hdrcache);
	}
    }

    /* fill the cache */
    r = spool_fill_hdrcache(cd->pin, f, m->hdrcache, skipheaders);

    /* now, using our header cache, fill in the data that we want */

    /* first check resent-message-id */
    if ((body = msg_getheader(m, "resent-message-id")) && body[0][0]) {
	m->id = xstrdup(body[0]);
    } else if ((body = msg_getheader(m, "message-id")) && body[0][0]) {
	m->id = xstrdup(body[0]);
    } else if (body) {
	r = IMAP_MESSAGE_BADHEADER;  /* empty message-id */
    } else {
	/* no message-id, create one */
	pid_t p = getpid();

	m->id = xmalloc(40 + strlen(config_servername));
	sprintf(m->id, "<cmu-lmtpd-%d-%d-%u@%s>", p, (int) now,
		msgid_count++, config_servername);
	fprintf(f, "Message-ID: %s\r\n", m->id);
	spool_cache_header(xstrdup("Message-ID"), xstrdup(m->id), m->hdrcache);
    }

    /* get date */
    if (!(body = spool_getheader(m->hdrcache, "date"))) {
	/* no date, create one */
	addbody = xstrdup(datestr);
	m->date = xstrdup(datestr);
	fprintf(f, "Date: %s\r\n", addbody);
	spool_cache_header(xstrdup("Date"), addbody, m->hdrcache);
    }
    else {
	m->date = xstrdup(body[0]);
    }

    if (!m->return_path &&
	(body = msg_getheader(m, "return-path"))) {
	/* let's grab return_path */
	m->return_path = xstrdup(body[0]);
	clean822space(m->return_path);
	clean_retpath(m->return_path);
    }

    r |= spool_copy_msg(cd->pin, f);
    if (r) {
	fclose(f);
	if (func->removespool) {
	    /* remove the spool'd message */
	    func->removespool(m);
	}
	while (nrcpts--) {
	    send_lmtp_error(cd->pout, r);
	}
	return r;
    }

    fflush(f);
    if (ferror(f)) {
	while (nrcpts--) {
	    prot_printf(cd->pout,
	       "451 4.3.%c cannot copy message to temporary file: %s\r\n",
		   (
#ifdef EDQUOT
		    errno == EDQUOT ||
#endif
		    errno == ENOSPC) ? '1' : '2',
		   error_message(errno));
	}
	fclose(f);
	if (func->removespool) func->removespool(m);
	return IMAP_IOERROR;
    }

    if (fstat(fileno(f), &sbuf) == -1) {
	while (nrcpts--) {
	    prot_printf(cd->pout,
			"451 4.3.2 cannot stat message temporary file: %s\r\n",
			error_message(errno));
	}
	fclose(f);
	if (func->removespool) func->removespool(m);
	return IMAP_IOERROR;
    }
    m->size = sbuf.st_size;
    m->f = f;
    m->data = prot_new(fileno(f), 0);

    return 0;
}