static char *fetch_smtproutes(const char *domain) { char *buf=get_control_smtproutes(); const char *p=buf; if (!buf) { struct dbobj d; char *p, *q; size_t l; p=config_search("esmtproutes.dat"); dbobj_init(&d); if (dbobj_open(&d, p, "R")) { free(p); return (0); } free(p); p=strcpy(courier_malloc(strlen(domain)+1), domain); for (q=p; *q; q++) *q=tolower(*q); q=dbobj_fetch(&d, p, strlen(p), &l, "D"); free(p); dbobj_close(&d); if (!q) return (0); p=courier_malloc(l+1); memcpy(p, q, l); p[l]=0; free(q); return (p); } while (*p) { unsigned i; for (i=0; p[i] && p[i] != '\n' && p[i] != '\r' && p[i] != ':'; ++i) ; if (p[i] == ':' && (i == 0 || config_domaincmp(domain, p, i) == 0)) { char *q; p += i; ++p; for (i=0; p[i] && p[i] != '\n' && p[i] != '\r'; i++) ; while (i && isspace((int)(unsigned char)p[i-1])) --i; while (i && isspace((int)(unsigned char)*p)) { ++p; --i; } if (i == 0) { free(buf); return (0); } q=courier_malloc(i+1); memcpy(q, p, i); q[i]=0; free(buf); return (q); } while (p[i]) { if (p[i] == '\n' || p[i] == '\r') { ++i; break; } ++i; } p += i; } free(buf); return (0); }
static void check_db() { char *dbname; char *lockname; int lockfd; struct dbobj db; time_t now; char *sender_key, *p; size_t val_len; char *val; if (!dbfile || !*dbfile) return; sender_key=strdup(sender); dbname=malloc(strlen(dbfile)+ sizeof( "." DBNAME)); lockname=malloc(strlen(dbfile)+ sizeof(".lock")); for (p=sender_key; *p; p++) *p=tolower((int)(unsigned char)*p); if (!dbname || !lockname || !sender) { perror("malloc"); exit(EX_TEMPFAIL); } strcat(strcpy(dbname, dbfile), "." DBNAME); strcat(strcpy(lockname, dbfile), ".lock"); lockfd=open(lockname, O_RDWR|O_CREAT, 0666); if (lockfd < 0 || ll_lock_ex(lockfd)) { perror(lockname); exit(EX_TEMPFAIL); } dbobj_init(&db); if (dbobj_open(&db, dbname, "C") < 0) { perror(dbname); exit(EX_TEMPFAIL); } time(&now); val=dbobj_fetch(&db, sender_key, strlen(sender_key), &val_len, ""); if (val) { time_t t; if (val_len >= sizeof(t)) { memcpy(&t, val, sizeof(t)); if (t >= now - interval * 60 * 60 * 24) { free(val); dbobj_close(&db); close(lockfd); exit(0); } } free(val); } dbobj_store(&db, sender_key, strlen(sender_key), (void *)&now, sizeof(now), "R"); dbobj_close(&db); close(lockfd); }
static int update_cur(const char *cur, const char *shared, struct dbobj *obj) { DIR *dirp; struct dirent *de; char *p; dirp=opendir(cur); while (dirp && (de=readdir(dirp)) != 0) { char *cur_base; char *cur_name_ptr; size_t cur_name_len; char *linked_name_buf; size_t linked_name_len; int n; if (de->d_name[0] == '.') continue; /* ** Strip the maildir flags, and look up the message in the ** db. */ cur_base=malloc(strlen(de->d_name)+1); if (!cur_base) { perror("malloc"); closedir(dirp); return (-1); } strcpy(cur_base, de->d_name); p=strrchr(cur_base, MDIRSEP[0]); if (p) *p=0; cur_name_ptr=dbobj_fetch(obj, cur_base, strlen(cur_base), &cur_name_len, ""); /* If it's there, delete the db entry. */ if (cur_name_ptr) dbobj_delete(obj, cur_base, strlen(cur_base)); /* ** We'll either delete this soft link, or check its ** contents, so we better build its complete pathname in ** any case. */ free(cur_base); cur_base=malloc(strlen(de->d_name)+strlen(cur)+2); if (!cur_base) { perror("malloc"); if (cur_name_ptr) free(cur_name_ptr); closedir(dirp); return (-1); } strcat(strcat(strcpy(cur_base, cur), "/"), de->d_name); if (!cur_name_ptr) /* Removed from sharable dir */ { unlink(cur_base); free(cur_base); continue; } linked_name_len=strlen(shared)+strlen(de->d_name)+100; /* should be enough */ if ((linked_name_buf=malloc(linked_name_len)) == 0) { perror("malloc"); free(cur_base); free(cur_name_ptr); closedir(dirp); return (-1); } if ((n=readlink(cur_base, linked_name_buf, linked_name_len))< 0) { /* This is stupid, let's just unlink this nonsense */ n=0; } if (n == 0 || n >= linked_name_len || (linked_name_buf[n]=0, update_link(cur, cur_base, linked_name_buf, shared, cur_name_ptr, cur_name_len))) { unlink(cur_base); free(linked_name_buf); free(cur_base); free(cur_name_ptr); closedir(dirp); return (-1); } free(cur_base); free(linked_name_buf); free(cur_name_ptr); } if (dirp) closedir(dirp); return (0); }