Page MenuHomePhorge

updateimsp.c
No OneTemporary

Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None

updateimsp.c

/* updateimsp.c -- program to send mailbox updates to IMSP.
*
* (C) Copyright 1994 by Carnegie Mellon University
*
* All Rights Reserved
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Carnegie
* Mellon University not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. Carnegie Mellon University makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <com_err.h>
#include "acte.h"
#include "imclient.h"
#include "sysexits.h"
#include "xmalloc.h"
#include "imap_err.h"
#include "config.h"
#include "mailbox.h"
#ifdef HAVE_ACTE_KRB
extern struct acte_client krb_acte_client;
#endif
struct acte_client *login_acte_client[] = {
#ifdef HAVE_ACTE_KRB
&krb_acte_client,
#endif
NULL
};
FILE *failedfp;
int commands_pending;
struct imclient *connecttoimsp();
main()
{
char *val;
config_init("updateimsp");
if (geteuid() == 0) fatal("must run as the Cyrus user", EX_USAGE);
if (chdir(config_dir)) {
syslog(LOG_ERR, "IOERROR: changing directory to config directory: %m");
fatal("cannot change directory to config directory", EX_TEMPFAIL);
}
#ifdef HAVE_ACTE_KRB
if (val = config_getstring("srvtab", 0)) {
kerberos_set_srvtab(val);
}
#endif
for (;;) {
doupdate();
sleep(15*60);
}
}
doupdate()
{
char *imsphost;
char hostbuf[256];
char *p;
struct imclient *imspconn;
int workfd, retryfd, newfd;
char *work_base, *retry_base;
unsigned long work_size = 0, *retry_size = 0;
struct stat work_sbuf, retry_sbuf;
char *failaction;
imsphost = config_getstring("imspservers", 0);
if (!imsphost) {
syslog(LOG_ERR, "Missing required imsphost configuration option");
fatal("Missing required imsphost configuration option", EX_CONFIG);
}
while (isspace(*imsphost)) imsphost++;
strncpy(hostbuf, imsphost, sizeof(hostbuf)-1);
hostbuf[sizeof(hostbuf)-1] = '\0';
p = hostbuf;
while (*p && !isspace(*p)) p++;
*p = '\0';
imspconn = connecttoimsp(hostbuf);
failedfp = fopen("toimsp.failed", "w");
if (!failedfp) {
syslog(LOG_ERR, "Can't create toimsp.failed: %m");
return;
}
(void) link("toimsp", "toimsp.work");
workfd = open("toimsp.work", O_RDWR, 0666);
if (workfd == -1) {
syslog(LOG_ERR, "IOERROR: opening toimsp.work: %m", failaction);
return;
}
if (lock_reopen(workfd, "toimsp.work", &work_sbuf, &failaction)) {
syslog(LOG_ERR, "IOERROR: %s toimsp.work: %m", failaction);
close(workfd);
return;
}
newfd = open("toimsp.new", O_RDWR|O_CREAT|O_TRUNC, 0666);
if (newfd == -1) {
syslog(LOG_ERR, "IOERROR: creating toimsp.new: %m");
close(workfd);
return;
}
close(newfd);
if (rename("toimsp.new", "toimsp") == -1) {
syslog(LOG_ERR, "IOERROR: renaming toimsp.new: %m");
close(workfd);
return;
}
lock_unlock(newfd);
retryfd = open("toimsp.retry", O_RDWR, 0666);
if (retryfd != -1) {
if (fstat(retryfd, &retry_sbuf) == -1) {
syslog(LOG_ERR, "IOERROR: fstat on toimsp.retry: %m");
close(workfd);
close(retryfd);
return;
}
map_refresh(retryfd, 1, &retry_base, &retry_size,
retry_sbuf.st_size, "toimsp.retry", 0);
processfile(imspconn, retry_base, retry_size);
}
map_refresh(workfd, 1, &work_base, &work_size, work_sbuf.st_size,
"toimsp.work", 0);
processfile(imspconn, work_base, work_size);
while (commands_pending) {
imclient_processoneevent(imspconn);
}
imclient_close(imspconn);
map_free(&work_base, &work_size);
close(workfd);
if (retryfd != -1) {
map_free(&retry_base, &retry_size);
close(retryfd);
}
fclose(failedfp);
if (rename("toimsp.failed", "toimsp.retry") != -1) {
(void) unlink("toimsp.work");
}
}
struct imclient *
connecttoimsp(hostname)
char *hostname;
{
static time_t cred_expire, curtime, life;
int i, gotcred = 0;
struct imclient *imspconn;
int r;
const char *err;
curtime = time(0);
if (cred_expire < curtime+5*60) {
for (i = 0; login_acte_client[i]; i++) {
/* XXX look for authmech (or similar) config option */
err = login_acte_client[i]->new_cred("imap", &life);
if (!err) {
if (!gotcred++ || curtime + life < cred_expire) {
cred_expire = curtime + life;
}
}
else {
syslog(LOG_WARNING, "Error getting %s credential: %s",
login_acte_client[i]->auth_type, err);
/*debug*/printf("cannot get %s credential: %s",
login_acte_client[i]->auth_type, err);
}
}
}
r = imclient_connect(&imspconn, hostname, "406");
if (r) {
if (r == -1) {
err = "unknown host";
}
else if (r == -2) {
err = "unknown service";
}
else {
err = error_message(r);
}
syslog(LOG_WARNING, "Error connecting to IMSP server: %s", err);
/*debug*/ printf("cannot connect to IMSP: %s\n", err);
return 0;
}
r = imclient_authenticate(imspconn, login_acte_client, (char *)0,
ACTE_PROT_ANY);
if (r) {
syslog(LOG_WARNING, "Error authenticating to IMSP server");
/*debug*/printf("cannot authenticate to imsp\n");
imclient_close(imspconn);
return 0;
}
commands_pending = 0;
return imspconn;
}
void
callback_retryonfail(imspconn, rock, reply)
struct imclient *imspconn;
void *rock;
struct imclient_reply *reply;
{
char *cmd = (char *)rock;
char *cmdend;
commands_pending--;
/*debug*/ printf("%u %s %s %s\n", commands_pending, reply->keyword, reply->text, cmd + 1);
if (strcmp(reply->keyword, "OK") != 0) {
cmdend = memchr(cmd+1, '\n', 1024*1024);
fwrite(cmd, cmdend - cmd + 1, 1, failedfp);
}
}
#define MAXARGS 20
processfile(imspconn, base, size)
struct imclient *imspconn;
char *base;
int size;
{
char *endline;
char *p, *endp;
char *mailbox, *uidvalidity;
char *arg[MAXARGS];
int nargs;
while (p = memchr(base, '\n', size)) {
size -= p - base;
while (size && p[1] == '\n') {
p++;
size--;
}
base = p+1;
size--;
endline = memchr(base, '\n', size);
if (!endline) break;
if (endline - base < size && endline[1] != '\n') continue;
nargs = 0;
p = base;
while (p < endline) {
arg[nargs++] = p;
if (nargs == MAXARGS) continue;
endp = memchr(p, '\0', endline - p);
if (!endp) continue;
p = endp + 1;
}
arg[nargs] = 0;
imclient_send(imspconn, callback_retryonfail, (void *)(base-1),
"X-CYRUS-MBINFO %v", arg);
commands_pending++;
}
}
fatal(msg, code)
char *msg;
int code;
{
fprintf(stderr, "updateimsp: %s\n", msg);
exit(code);
}

File Metadata

Mime Type
text/x-c
Expires
Fri, Apr 24, 10:29 AM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18896512
Default Alt Text
updateimsp.c (7 KB)

Event Timeline