This is bbsmail.c in view mode; [Download] [Up]
/* $Id$ */
#include "bbs.h"
boolean bbsdaemon = FALSE;
SIGSET_T old_blocksigset;
sigmaskstatusenum blocksigsetstatus = SIGMASK_UNSET;
extern char **environ;
int main(int argc, char *argv[], char *envp[])
/*
Zum Empfangen von externer E-Mail (sendmail -> BBS-mailbox)
*/
{
int infd, sockd, n, k, rknown, anz, rw[MAXARGS];
SIZE_T msgsize, len;
#ifdef BBSMAILNAME
SIZE_T envlen;
#endif
SSIZE_T bytes;
char c, conffile[PATH_MAX+1], file[PATH_MAX+1], recipient[S_STRLEN+1],
bstr[BEFSTRLEN+1], rstr[ARG_MAX+1], *splits[MAXARGS+1], *msgbuf, *bp;
boolean argserror = FALSE;
confrecordtyp confrecord;
extern int optind, opterr, optopt;
extern char *optarg;
*recipient = '\0';
if ((bp=getenv("TZ")) != NULL) {
strncpy(recipient,bp,S_STRLEN);
}
#ifdef BBSMAILNAME
/* Speicher vom alten Environment fuer setproctitle recyclen */
envlen = 0;
for (n=0; n<argc; n++) envlen += strlen(argv[n]);
for (n=0; envp[n]!=NULL; n++) envlen += strlen(envp[n]);
#endif
environ[0] = (char *)NULL;
if (*recipient != '\0') mdefenv("TZ",recipient);
mputenv("EDITOR=/bin/false");
openlog("bbsmail",LOG_PID,LOG_BBS);
strcpy(conffile,CONFFILE);
*recipient = '\0';
strcpy(file,"-");
/* Optionen verarbeiten */
opterr = FALSE;
while ((c = getopt(argc, argv, "c:f:")) != EOF) {
switch (c) {
case 'c':
strmaxcpy(conffile,optarg,PATH_MAX);
break;
case 'f':
strmaxcpy(file,optarg,PATH_MAX);
break;
case '?':
fprintf(stderr,"bbsmail: unrecognized option: -%c\n", optopt);
errormsg(E_LOGFILE,&confrecord,"bbsmail","bbsmail",
"unrecognized option: -%c",optopt);
argserror = TRUE;
}
}
anz = 0;
*rstr = '\0';
while (optind < argc) {
anz++;
strmaxcat(rstr,argv[optind++],ARG_MAX-1);
strcat(rstr,",");
}
if (anz == 0) {
argserror = TRUE;
bgerror("bbsmail","no recipients given");
fprintf(stderr,"no recipients given\n");
argserror = TRUE;
}
#ifdef BBSMAILNAME
/* alten Programmtitel loeschen */
argv[0][envlen-2] = '\0';
for (n=0; n<envlen-2; n++) argv[0][n] = ' ';
#endif
if (readconffile(&confrecord,conffile) < 0) {
bgerror("bbsmail","cannot read conffile %s",conffile);
fprintf(stderr,"cannot read conffile %s\n",conffile);
exit(EX_UNAVAILABLE);
}
confrecord.curses_on = FALSE;
if (startbbsd(&confrecord,conffile) < 0) {
bgerror("bbsmail","starting bbsd failed");
fprintf(stderr,"starting bbsd failed\n");
exit(EX_OSERR);
}
if (strcmp(file,"-") == 0) {
#ifdef FIONREAD
if (isatty(STDIN_FILENO) && ioctl(STDIN_FILENO,FIONREAD,&msgsize) < 0) {
errormsg(E_LOGFILE|E_USER,&confrecord,"bbsmail","bbsmail","ioctl: %m");
exit(EX_OSERR);
}
for (k=0; msgsize == 0 && k < 20; k++) {
usleep(100000);
if (ioctl(STDIN_FILENO,FIONREAD,&msgsize) < 0) {
errormsg(E_LOGFILE|E_USER,&confrecord,"bbsmail","bbsmail","ioctl: %m");
exit(EX_OSERR);
}
}
if (msgsize == 0) {
errormsg(E_LOGFILE|E_USER,&confrecord,"bbsmail","bbsmail",
"no input on stdin");
exit(EX_NOINPUT);
}
#endif
infd = STDIN_FILENO;
}
else {
if ((infd=open(file,O_RDONLY)) < 0) {
errormsg(E_LOGFILE|E_USER,&confrecord,"bbsmail","bbsmail",
"open %s: %m",file);
exit(EX_NOINPUT);
}
}
if (argserror) {
errormsg(E_LOGFILE|E_USER,&confrecord,"bbsmail","bbsmail",
"usage: bbsmail [-c conffile] [-f file] recipient1 recipient2 ...");
exit(EX_USAGE);
}
if ((msgbuf=(char *)malloc(ALLOCSTEPSIZE)) == NULL) {
errormsg(E_LOGFILE|E_USER,&confrecord,"bbsmail","bbsmail","malloc: %m");
exit(EX_OSERR);
}
n = 1;
bp = msgbuf;
while ((bytes=readn(infd,msgbuf+(n-1)*ALLOCSTEPSIZE,ALLOCSTEPSIZE)) ==
ALLOCSTEPSIZE) {
n++;
bp += ALLOCSTEPSIZE;
if ((msgbuf=(char *)realloc((void *)msgbuf,n*ALLOCSTEPSIZE)) == NULL) {
errormsg(E_LOGFILE|E_USER,&confrecord,"bbsmail","bbsmail","realloc: %m");
exit(EX_OSERR);
}
}
if (bytes < 0) {
errormsg(E_LOGFILE|E_USER,&confrecord,"bbsmail","bbsmail","readn: %m");
exit(EX_IOERR);
}
close(infd);
msgsize = (n-1) * ALLOCSTEPSIZE + bytes;
anz = splitstring(splits,rstr,',',MAXARGS);
for (k=0; k<anz; k++) {
if ((sockd=connect2bbsd(&confrecord))<0) {
errormsg(E_LOGFILE|E_USER,&confrecord,"bbsmail","bbsmail",
"connection to daemon failed");
exit(EX_SOFTWARE);
}
sprintf(bstr,"#%2d\n",DO_RECEIVEMAIL);
sendn(sockd,(void *)bstr,(SIZE_T)BEFSTRLEN,0);
#ifdef BBSMAILNAME
setproctitle(argv,envlen,"checking recipient %s",splits[k]);
#endif
len = strlen(splits[k]) + 1;
sendn(sockd,(void *)&len,sizeof(SIZE_T),0);
sendn(sockd,(void *)splits[k],len,0);
recvn(sockd,(void *)&rknown,(SIZE_T)sizeof(int),0);
if (rknown == 0) {
#ifdef BBSMAILNAME
setproctitle(argv,envlen,"deliver %s",splits[k]);
#endif
sendn(sockd,(void *)&msgsize,sizeof(SIZE_T),0);
sendn(sockd,(void *)msgbuf,msgsize,0);
}
recvn(sockd,(void *)&n,(SIZE_T)sizeof(int),0);
unconnect2bbsd(sockd,&confrecord);
bbslog(LOG_FILE,&confrecord,"bbsmail: delivering mail to %s: %s",
splits[k],n==0?"ok":"failed");
if (n == 0) {
rw[k] = EX_OK;
}
else {
rw[k] = EX_SOFTWARE;
n = EX_NOUSER;
}
if (rknown != 0) {
rw[k] = EX_NOUSER;
n = EX_NOUSER;
}
}
if (n != 0) {
for (k=0; k<anz; k++) {
switch (rw[k]) {
case EX_OK:
fprintf(stderr,"Delivery to %s: OK\n",splits[k]);
break;
case EX_NOUSER:
fprintf(stderr,"User %s: not known at BBS\n",splits[k]);
break;
default:
fprintf(stderr,"Delivery to %s: FAILED by internal BBS error\n",
splits[k]);
}
}
}
free(msgbuf);
closelog();
return n;
}
int startbbsd(const confrecordtyp *confrecord, const char *conffile)
{
PID_T dpid;
int status;
if ((dpid=testdaemon(confrecord->bbsdpidpath,confrecord)) < 0) {
unlink(confrecord->sockpath);
}
/* dpid enthaelt die Pid des Daemons, wenn > 0 */
if (dpid <= 0) {
if ((dpid=fork())<0) {
errormsg(E_SYSLOG|E_CONSOLE,confrecord,"bbsmail","startbbsd",
"fork: %m");
return(-1);
}
if (dpid==0) {
execl(confrecord->bbsdpath,"bbsd","-d","-c",conffile,
"-p",confrecord->bbsdpath,NULL);
errormsg(E_SYSLOG|E_CONSOLE,confrecord,"bbsmail","startbbsd",
"execl %s: %m",confrecord->bbsdpath);
exit(-1);
}
while (wait(&status)!=dpid);
if (!WIFEXITED(status)) {
errormsg(E_SYSLOG|E_CONSOLE,confrecord,"bbsmail","startbbsd",
"starting bbsd failed: %d",status);
return(-1);
}
if (WIFEXITED(status) && WEXITSTATUS(status)!=0) {
errormsg(E_SYSLOG|E_CONSOLE,confrecord,"bbsmail","startbbsd",
"bbsd exited with %i",WEXITSTATUS(status));
return(-1);
}
}
return 0;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.