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.