Hello.
I noticed that many people asked about the quota check acl_rcpt.
Many are advised to use an external program. This reduces the efficiency of the postal system.
I have created a small path that makes the check without any external software and other inventions!
Waiting for comments on the work of such a function.
Code for check quota in acl_rcpt :
>>>>>>>>>>>>>>>>head<<<<<<<<<<<<<<<<<
#ifdef EXPERIMENTAL_QUOTA
#define MAX_FILE_SIZE 5120
int quota_process(uschar **listptr, uschar *quota_local, uschar *quota_domain, int action) {
uschar *list = *listptr;
uschar *maildirsize;
uschar line[MAX_FILE_SIZE];
uschar *ptr = line;
uschar *endptr;
uschar *dlm;
uschar *qfile;
uschar *nqfile;
FILE *fp;
signed long squota, cquota, ssize, csize;
signed long s_sum=0,c_sum=0;
struct stat qf;
struct stat nqf;
struct timeval detail_time;
qfile = string_sprintf("%squota.%s",list,primary_hostname);
nqfile = string_sprintf("%snquota.%s",list,primary_hostname);
if (stat(qfile,&qf) == 0) {
gettimeofday(&detail_time,NULL);
if ((detail_time.tv_sec - qf.st_mtime)<1800) return OK; else unlink(qfile);
}
if (stat(nqfile,&nqf) == 0) {
gettimeofday(&detail_time,NULL);
if ((detail_time.tv_sec - nqf.st_mtime)<1800) return FAIL; else unlink(nqfile);
}
maildirsize = string_sprintf("%s%s/maildirsize",list,quota_local);
fp = fopen(maildirsize,"rt");
if(fp == NULL) continue;
fgets(line,MAX_FILE_SIZE,fp);
dlm = strtok(ptr,",");
while (dlm)
{
off_t n = (off_t)Ustrtod(dlm, &endptr);
if (*endptr == 'S') squota = n;
else if (*endptr == 'C') cquota = (int)n;
dlm = strtok(NULL,",");
}
while(fgets(line, MAX_FILE_SIZE, fp) != NULL)
{
sscanf (line, "%ld%ld", &ssize,&csize);
s_sum+=ssize;
c_sum+=csize;
}
fclose(fp);
if ((s_sum>squota) (c_sum>cquota)) {
int fquota = open (qfile, O_RDWR|O_CREAT, 0666);
return OK;
} else {
int fnquota = open (nqfile, O_RDWR|O_CREAT, 0666);
return FAIL;
}
}
#endif