/************************************************************************
* Routines for dealing with comsat, as used by procmail *
* *
* Copyright (c) 1990-1999, S.R. van den Berg, The Netherlands *
* Copyright (c) 1999-2001, Philip Guenther, The United States *
* of America *
* #include "../README" *
************************************************************************/
#ifdef RCS
static /*const*/char rcsid[]=
"$Id: comsat.c,v 1.5 2001/07/03 15:05:47 guenther Exp $";
#endif
#include "procmail.h"
#ifndef NO_COMSAT
#include "sublib.h" /* for strtol() and strlcat() */
#include "robust.h" /* for rclose() */
#include "shell.h" /* for tmemmove() */
#include "acommon.h" /* for ultstr() */
#include "mailfold.h" /* for lasttell */
#include "misc.h"
#include "variables.h"
#include "network.h"
#include "comsat.h"
static int csvalid; /* is it turned on with a good address? */
static struct sockaddr_in csaddr;
static char*cslastf,*cslgname;
void setlfcs(folder)const char*folder; /* set lastfolder for comsat */
{ char*new,*old;
if(strchr(dirsep,*folder)) /* absolute filename? */
new=tstrdup(folder);
else /* nope; prepend the current maildir */
{ const char*md=tgetenv(maildir);
size_t len=strlen(md)+2+strlen(folder);
new=malloc(len);
strcpy(new,md);
strlcat(new,MCDIRSEP_,len);
strlcat(new,folder,len);
}
onguard(); /* protect the change over from signals */
old=cslastf;
cslastf=new;
offguard();
if(old)
free(old);
}
void setlgcs(name)const char*name; /* set logname for comsat */
{ char*new,*old;
new=tstrdup(name);
onguard(); /* protect the change over from signals */
old=cslgname;
cslgname=new;
offguard();
if(old)
free(old);
}
int setcomsat(chp)const char*chp;
{ char*chad;int newvalid; struct sockaddr_in newaddr;
chad=strchr(chp,SERV_ADDRsep); /* @ separator? */
if(!chad&&!renvint(-1L,chp))
return csvalid=0; /* turned off comsat */
newvalid=1;
if(chad)
*chad++='\0'; /* split the specifier */
if(!chad||!*chad) /* no host */
#ifndef IP_localhost /* Is "localhost" preresolved? */
chad=COMSAThost; /* nope, use default */
#else /* IP_localhost */
{ static const unsigned char ip_localhost[]=IP_localhost;
newaddr.sin_family=AF_INET;
tmemmove(&newaddr.sin_addr,ip_localhost,sizeof ip_localhost);
}
else
#endif /* IP_localhost */
{ const struct hostent*host; /* what host? paranoid checks */
if(!(host=gethostbyname(chad))||!host->h_0addr_list)
{ bbzero(&newaddr.sin_addr,sizeof newaddr.sin_addr);
newvalid=0; /* host can't be found, too bad */
}
else
{ newaddr.sin_family=host->h_addrtype; /* address number found */
tmemmove(&newaddr.sin_addr,host->h_0addr_list,host->h_length);
}
endhostent();
}
if(newvalid) /* so far, so good */
{ int s;
if(!*chp) /* no service */
chp=BIFF_serviceport; /* new balls please! */
s=strtol(chp,&chad,10);
if(chp!=chad) /* the service is not numeric */
newaddr.sin_port=htons((short)s); /* network order */
else
{ const struct servent*serv;
serv=getservbyname(chp,COMSATprotocol); /* so get its no. */
if(serv)
newaddr.sin_port=serv->s_port;
else
{ newaddr.sin_port=htons((short)0); /* no such service */
newvalid=0;
}
endservent();
}
}
onguard(); /* update the address atomically */
if(csvalid=newvalid)
tmemmove(&csaddr,&newaddr,sizeof(newaddr));
offguard();
return newvalid;
}
void sendcomsat(folder)const char*folder;
{ int s;const char*p;
if(!csvalid||!buf) /* is comat on and set to a valid address? */
return;
if(!cslgname||!*cslgname||strlen(cslgname)+2>linebuf) /* is $LOGNAME bogus? */
return;
if(!(p=folder?folder:cslastf)) /* do we have a folder? */
return;
strcpy(buf,cslgname);
strlcat(buf,"@",linebuf); /* start setting up the message */
if(lasttell>=0) /* was it a file? */
{ ultstr(0,(unsigned long)lasttell,buf2); /* yep, include the offset */
strlcat(buf,buf2,linebuf);
}
strlcat(buf,COMSATxtrsep,linebuf); /* custom seperator */
strlcat(buf,p,linebuf); /* where was it delivered? */
if((s=socket(AF_INET,SOCK_DGRAM,UDP_protocolno))>=0)
{ sendto(s,buf,strlen(buf),0,(struct sockaddr*)&csaddr,sizeof(csaddr));
rclose(s);
yell("Notified comsat:",buf);
}
}
#else
int comsat_dummy_var; /* to prevent insanity in some linkers */
#endif
syntax highlighted by Code2HTML, v. 0.9.1