/*
*
*              Reverse MX Filter for Postfix 2
*                    reject_bad_rmx
*           (c) 2004 Elita rozanski@sergiusz.com
*
*/

/*
MXfilter is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "spfmacro.h"

int macro(char *k, int sizek, struct tspfm *spfm) {
char b[1024];
char o[1024];
char *r,*p,*e;

memset(o,0,sizeof(o));

snprintf(b,sizeof(b),"%s",k);

r=b;
while((p=(char *)index(r,'%'))) {
    p++[0]=0;
    sprintf(o,"%s%s",o,r);
    if (p[0]=='%') {
	sprintf(o,"%s%%",o);
	r=p+1;
	}
    else
    if (p[0]=='_') {
	sprintf(o,"%s ",o); 
	r=p+1;
	}
    else
    if (p[0]=='-') {
	sprintf(o,"%s%%20",o);
	r=p+1;
	}
    else
    if (p[0]=='{') {
	char war[1024];
    
	if (!(e=(char *)index(p,'}'))) return -1;
	p++;
	if(p[0]=='l') snprintf(war,sizeof(war),"%s",spfm->l);
	else if(p[0]=='s') snprintf(war,sizeof(war),"%s",spfm->s);
	else if(p[0]=='o') snprintf(war,sizeof(war),"%s",spfm->o);
	else if(p[0]=='d') snprintf(war,sizeof(war),"%s",spfm->d);
	else if(p[0]=='i') snprintf(war,sizeof(war),"%s",spfm->i);
	else if(p[0]=='t') snprintf(war,sizeof(war),"%s",spfm->t);
	else if(p[0]=='p') snprintf(war,sizeof(war),"%s",spfm->p);
	else if(p[0]=='v') snprintf(war,sizeof(war),"in-addr");
	else if(p[0]=='h') snprintf(war,sizeof(war),"%s",spfm->h);
	else return -1;

	r=e+1;

	e--;
	while (e>p) {
	    int i;
	    
	    if(e[0]=='.' || e[0]=='-' || e[0]=='+' || e[0]==',' || e[0]=='|' || e[0]=='_') {
		for(i=0;i<strlen(war);i++)
		    if(war[i]==e[0])
			war[i]='.';
		}
	    else
	    if(e[0]=='r') {
		char pom[1024];
		char *q;
		memset(pom,0,sizeof(pom));
	    
		while((q=(char *)rindex(war,'.'))) {
		    sprintf(pom,"%s%s.",pom,q+1);
		    q[0]=0;
		    }
		sprintf(pom,"%s%s",pom,war);
		sprintf(war,"%s",pom);
		}
	    else
	    if(atoi(p+1)>0) {
		i=atoi(p+1);
		e=p;
		
		if(i>0) {
		    char pom[1024];
		    char *q;
		    int j=0;
		    
		    snprintf(pom,sizeof(pom),"%s",war);
		    q=pom;
		    while((q=(char *)index(q,'.'))) {
			j++;
			q++;
			}
		    
		    if(i<=j) {
			int jj,ji=j-i+1;
			q=pom;
			for(jj=0;jj<ji;jj++)
			    if(q) {
				q=(char *)index(q,'.');
				if(q)q++;
				}
			snprintf(war,sizeof(war),"%s",q);
			}
		    }
		}
	    else
		return -1;
	    e--;
	    }

	sprintf(o,"%s%s",o,war);
	}
    else
    return -1; //macro error
    }
snprintf(k,sizek,"%s%s",o,r);

return 0;
}

/*
int main () {
char k[1000];
int w;
struct tspfm spfm;

sprintf(spfm.l,"serek-a-b-c-d+e");

sprintf(k,"%%{l}_%%{l-}_%%{l+}_%%{l1+-}_%%{l10r+-}");
printf("%s->",k);

w=macro(k,sizeof(k),&spfm);

printf("%s w:%d\n",k,w);

return 0;

}
*/
