This is mail.c in view mode; [Download] [Up]
/* $Id: mail.c,v 1.1 1995/12/19 19:30:47 eilts Exp eilts $ */
#include "bbs.h"
int mimerecode(const char *file, const char *encoding,
const confrecordtyp *confrecord)
{
char scratch[PATH_MAX+1], sstr[3], c;
FILE *infp, *outfp;
if (encoding == NULL) {
return 0;
}
if (strcasecmp(encoding,"quoted-printable") == 0) {
if ((infp=fopen(file,"r")) == NULL) {
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","minerecode",
"fopen %s: %m",file);
return -1;
}
scratchfilename(scratch,"mime",NULL,confrecord->maildir);
if ((outfp=fopen(scratch,"w")) == NULL) {
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","minerecode",
"fopen %s: %m",scratch);
return -1;
}
sstr[2] = '\0';
while ((c=getc(infp)) != EOF) {
if (c == '=') {
if ((sstr[0]=getc(infp)) == EOF) return -1;
if ((sstr[1]=getc(infp)) == EOF) return -1;
if (strcmp(sstr,AE_U_QP) == 0) {
putc(AE_U_L1,outfp);
}
else if (strcmp(sstr,AE_L_QP) == 0) {
putc(AE_L_L1,outfp);
}
else if (strcmp(sstr,OE_U_QP) == 0) {
putc(OE_U_L1,outfp);
}
else if (strcmp(sstr,OE_L_QP) == 0) {
putc(OE_L_L1,outfp);
}
else if (strcmp(sstr,UE_U_QP) == 0) {
putc(UE_U_L1,outfp);
}
else if (strcmp(sstr,UE_L_QP) == 0) {
putc(UE_L_L1,outfp);
}
else if (strcmp(sstr,SS_QP) == 0) {
putc(SS_L1,outfp);
}
else if (strcmp(sstr,EQCHAR_QP) == 0) {
putc('=',outfp);
}
else {
putc('=',outfp);
fputs(sstr,outfp);
}
}
else {
putc(c,outfp);
}
}
fclose(infp);
fclose(outfp);
if (rename(scratch,file) < 0) {
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","minerecode",
"rename %s to %s: %m",scratch,file);
return -1;
}
chmod(file,0600);
}
return 0;
}
int addresstyp(const char *address, const confrecordtyp *confrecord)
/*
Returnwerte:
-1: falscher Addresssyntax
0: Message-Addresse
1: Sysop
2: lokale E-Mail Addresse
3: nichtlokale E-Mail Addresse
*/
{
int n, k, rw = 0;
char *sp, *host, *splits[MAXARGS+1], addr[ARG_MAX+1], dest[S_STRLEN+1],
realname[S_STRLEN+1];
struct hostent *hostentp;
extern int h_errno;
strmaxcpy(addr,address,ARG_MAX);
splitstring(splits,addr,',',MAXARGS);
for (k=0; splits[k]!=NULL; k++) {
parseaddrline(dest,realname,splits[k]);
n = -1;
if (strchr(dest,'!') != NULL) {
n = -1;
}
else if (strcmp(dest,confrecord->sysop) == 0) {
n = 1;
}
else if ((host=strchr(dest,'@')) != NULL) {
host++;
if ((hostentp=gethostbyname(host)) == NULL) {
switch (h_errno) {
case HOST_NOT_FOUND:
sp = "Authoritative Answer Host not found";
break;
case TRY_AGAIN:
sp = "Non-Authoritive Host not found, or SERVERFAIL";
break;
case NO_RECOVERY:
sp = "Non recoverable errors, FORMERR, REFUSED, NOTIMP";
break;
case NO_DATA:
sp = "Valid name, no data record of requested type";
break;
default:
sp = "failed";
}
/*
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","addresstyp",
"gethostbyname %s: %s",host,sp);
return(-1);
*/
}
if (hostentp != NULL &&
strcmp(hostentp->h_name,confrecord->hostname) == 0) {
n = 2;
}
else {
n = 3;
}
}
else {
n = 0;
}
if (n < 0) return n;
if (n > rw) rw = n;
}
return rw;
}
int mailreply(char cmd[], const int nr, const char *msg_id,
const menuetyp bbsmenue[], const chrootrecordtyp *chrootrecord,
const confrecordtyp *confrecord)
{
int n;
char subject[STRLEN+1], addr[ARG_MAX+1], scratch[PATH_MAX+1], key,
*hdrbuf = NULL;
mailheadertyp mailhdr;
if (makereplytext(scratch,&mailhdr,nr,msg_id,hdrbuf,confrecord) < 0) {
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","reader_c",
"cannot copy message Nr: %d, Id: %s",nr,msg_id);
n = -1;
}
else {
strcpy(subject,"Re: ");
strmaxcat(subject,mailhdr.subject,STRLEN-1);
if (*mailhdr.reply_to != '\0') {
strcpy(addr,mailhdr.reply_to);
}
else {
strcpy(addr,mailhdr.from);
}
if (*mailhdr.cc != '\0') {
key = getkeyonprompt(msg("mail",0,confrecord->userrecord.lang),
"JYN",TRUE,FALSE,NULL,confrecord);
if (key == 'Y' || key == 'J') {
strcat(addr,",");
strcat(addr,mailhdr.cc);
}
}
if ((n=addresstyp(addr,confrecord)) < 0) return n;
if (n < 2) {
key = getkeyonprompt(msg("mail",1,confrecord->userrecord.lang),
"NME",TRUE,FALSE,NULL,confrecord);
if (key == 'E') {
key = EMAIL_KEY;
}
else {
key = MESSAGE_KEY;
}
}
else {
key = EMAIL_KEY;
}
*cmd = '\0';
n = 0;
while (bbsmenue[n].key!='\0') {
if (bbsmenue[n].key==key && *(bbsmenue[n].dec)!='\0') {
strcpy(cmd,bbsmenue[n].cmd);
break;
}
n++;
}
if (key == MESSAGE_KEY) {
n = sendmessage_c(cmd,scratch,addr,subject,chrootrecord, confrecord);
}
else {
n = sendmail_c(cmd,scratch,addr,subject,FALSE,chrootrecord,confrecord);
}
}
if (hdrbuf != NULL) free(hdrbuf);
return n;
}
int makereplytext(char scratch[], mailheadertyp *mailhdr, const int nr,
const char *mesg_id, char *hdrbuf,
const confrecordtyp *confrecord)
{
char path[PATH_MAX+1], zeile[STRLEN+1];
FILE *fp, *sfp;
scratch[0] = '\0';
if (getmessage(path,nr,mesg_id,confrecord) < 0) {
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","makereplytext",
"message Nr %d, Msg-ID %s, not found",nr,mesg_id);
return -1;
}
if ((fp=fopen(path,"r")) == NULL) {
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","makereplytext",
"fopen %s: %m",path);
return -1;
}
unlink(path);
if ((hdrbuf=parsemailheader(mailhdr,fp,confrecord)) == NULL) {
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","makereplytext",
"parsemailheader of %s failed",path);
return -1;
}
rewind(fp);
scratchfilename(scratch,"reply.",NULL,confrecord->scratchdir);
if ((sfp=fopen(scratch,"w")) == NULL) {
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","makereplytext",
"fopen %s: %m",scratch);
return -1;
}
fprintf(sfp,"In reply of:\n");
while (fgetnln(zeile,STRLEN,fp) >= 0) {
fputs("> ",sfp);
fputs(zeile,sfp);
putc('\n',sfp);
}
fclose(fp);
fclose(sfp);
return 0;
}
#ifndef NO_REGCOMP
#define NO_RE_COMP
#endif
int checkmailperms(const char *address, const confrecordtyp *confrecord)
{
int a_anz, p_anz, p, k, n;
char *asplits[MAXARGS+1], *psplits[MAXARGS+1], astr[ARG_MAX+1],
pstr[STRLEN+1], pattern[STRLEN+1], *psp, c;
#ifdef NeXT
char hoststr[S_STRLEN+1];
#endif
const char *sp;
#ifndef NO_REGCOMP
regex_t preg;
regmatch_t pmatch[1];
#else
#endif
struct hostent *hostentp;
strmaxcpy(astr,address,ARG_MAX);
a_anz = splitstring(asplits,astr,',',MAXARGS);
for (k=0; k<a_anz; k++) {
parseaddrline(pstr,pattern,asplits[k]);
strcpy(asplits[k],pstr);
}
strmaxcpy(pstr,confrecord->userrecord.permittions,STRLEN);
p_anz = splitstring(psplits,pstr,':',MAXARGS);
for (n=0; psplits[n] != NULL; n++) {
if (*psplits[n] == 'N' || *psplits[n] == 'P') {
continue;
}
else if (*psplits[n] == 'E') {
strcpy(pattern,&(psplits[n][1]));
}
else if (strcmp(psplits[n],"L") == 0) {
for (k=0; k < a_anz; k++) {
if ((sp=strchr(asplits[k],'@')) != NULL) {
sp++;
}
else if (strchr(asplits[k],'!') == NULL) {
sp = confrecord->hostname;
}
else {
sp = "@";
}
#ifdef NeXT
strmaxcpy(hoststr,sp,S_STRLEN);
if ((hostentp=gethostbyname(hoststr)) != NULL &&
#else
if ((hostentp=gethostbyname(sp)) != NULL &&
#endif
strcmp(confrecord->hostname,hostentp->h_name) == 0) {
asplits[k--] = asplits[--a_anz];
asplits[a_anz] = NULL;
}
}
}
else {
p = 0;
pattern[p++] = '^';
psp = psplits[n];
while ((c=*psp++) != '\0') {
switch (c) {
case '.':
pattern[p++] = '\\';
pattern[p++] = '.';
break;
case '*':
pattern[p++] = '.';
pattern[p++] = '*';
break;
#ifndef NO_REGCOMP
case '?':
pattern[p++] = '.';
break;
#endif
default:
pattern[p++] = c;
}
}
pattern[p++] = '$';
pattern[p] = '\0';
}
#ifndef NO_REGCOMP
if ((k=regcomp(&preg,pattern,REG_ICASE|REG_EXTENDED|REG_NOSUB)) != 0) {
regerror(k,&preg,pattern,STRLEN);
#else
#ifndef NO_RE_COMP
if ((sp=re_comp(pattern)) != (char *)0) {
strmaxcpy(pattern,sp,STRLEN);
#endif
#endif
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","checkmailperms",
"wrong pattern: %s",pattern);
return(-1);
}
for (k=0; k < a_anz; k++) {
#ifndef NO_REGCOMP
if ((p=regexec(&preg,asplits[k],0,pmatch,0)) == 0) {
#else
#ifndef NO_RE_COMP
lowercases(asplits[k]);
if ((p=re_exec(asplits[k])) == 1) {
#endif
#endif
asplits[k--] = asplits[--a_anz];
asplits[a_anz] = NULL;
}
#ifndef NO_REGCOMP
else if (p != REG_NOMATCH) {
regerror(p,&preg,pattern,STRLEN);
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","checkmailperms",
"regexec: %s",pattern);
regfree(&preg);
#else
#ifndef NO_RE_COMP
else if (p < 0) {
errormsg(E_LOGFILE|E_USER,confrecord,"bbs","checkmailperms",
"re_exec: internal error");
#endif
#endif
return(-1);
}
}
#ifndef NO_REGCOMP
regfree(&preg);
#endif
}
return a_anz;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.