1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/************************************************************************
* 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.7 2001/09/13 19:08:49 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(!chad||!*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
|