void SetEmailArea(char *box) { char *p; if (!exitinfo.Email) return; /* * Use a temp variable because this function can be called line SetEmailArea(sMailbox) */ p = xstrcpy(box); snprintf(sMailpath, PATH_MAX, "%s/%s/%s", CFG.bbs_usersdir, exitinfo.Name, p); snprintf(sMailbox, 21, "%s", p); free(p); /* * Get information from the message base */ if (Msg_Open(sMailpath)) { EmailBase.Lowest = Msg_Lowest(); EmailBase.Highest = Msg_Highest(); EmailBase.Total = Msg_Number(); Msg_Close(); } else WriteError("Error open JAM %s", sMailpath); }
void die(int onsig) { signal(onsig, SIG_IGN); CloseDupes(); Msg_Close(); if (onsig) { if (onsig <= NSIG) WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]); else WriteError("Terminated with error %d", onsig); } if (do_mailout) CreateSema((char *)"mailout"); t_end = time(NULL); Syslog('+', "Send [%6lu] Received [%6lu]", sentbytes, rcvdbytes); Syslog(' ', "FTNNNTP finished in %s", t_elapsed(t_start, t_end)); if (envptr) free(envptr); ExitClient(onsig); msleep(1); /* For the linker only */ }
/* * Pack message area if there are deleted messages. */ void PackArea(char *Path, int Areanr) { IsDoing("Packing %ld", Areanr); if (Msg_Open(Path)) { if (!do_quiet) { mbse_colour(LIGHTRED, BLACK); printf(" (Packing)"); fflush(stdout); } if (Msg_Lock(30L)) { Msg_Pack(); Msg_UnLock(); } else Syslog('+', "Can't lock %s", Path); Msg_Close(); if (!do_quiet) { printf("\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } } if (CFG.slow_util && do_quiet) msleep(1); }
void QuickScan_Email(void) { int FoundMsg = FALSE; int i; char temp[81]; iLineCount = 2; WhosDoingWhat(READ_POST, NULL); if (EmailBase.Total == 0) { Enter(1); /* There are no messages in this area. */ pout(WHITE, BLACK, (char *) Language(205)); Enter(2); sleep(3); return; } clear(); /* # From To Subject */ poutCR(YELLOW, BLUE, (char *) Language(220)); if (Msg_Open(sMailpath)) { for (i = EmailBase.Lowest; i <= EmailBase.Highest; i++) { if (Msg_ReadHeader(i)) { snprintf(temp, 81, "%-6u", Msg.Id); pout(WHITE, BLACK, temp); snprintf(temp, 81, "%s ", padleft(Msg.From, 20, ' ')); pout(CYAN, BLACK, temp); snprintf(temp, 81, "%s ", padleft(Msg.To, 20, ' ')); pout(GREEN, BLACK, temp); snprintf(temp, 81, "%s", padleft(Msg.Subject, 31, ' ')); pout(MAGENTA, BLACK, temp); Enter(1); FoundMsg = TRUE; if (LC(1)) break; } } Msg_Close(); } if(!FoundMsg) { Enter(1); /* There are no messages in this area. */ pout(LIGHTGREEN, BLACK, (char *) Language(205)); Enter(2); sleep(3); } iLineCount = 2; Pause(); }
void die(int onsig) { if (onsig <= NSIG) signal(onsig, SIG_DFL); /* * First check if there is a child running, if so, kill it. */ if (e_pid) { if ((kill(e_pid, SIGTERM)) == 0) Syslog('+', "SIGTERM to pid %d succeeded", e_pid); else { if ((kill(e_pid, SIGKILL)) == 0) Syslog('+', "SIGKILL to pid %d succeeded", e_pid); else WriteError("Failed to kill pid %d", e_pid); } } if (MsgBase.Locked) Msg_UnLock(); if (MsgBase.Open) Msg_Close(); Home(); if (onsig) { if (onsig == SIGHUP) { hanged_up = 1; Syslog('+', "Lost Carrier"); } else if (onsig == SIGPIPE) { hanged_up = 1; Syslog('+', "Broken Pipe"); } else if (onsig == SIGALRM) { Syslog('+', "User inactivity timeout"); } else { if (onsig <= NSIG) { hanged_up = 1; WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]); } else { WriteError("Terminated with error %d", onsig); } } } else { Syslog(' ', "Terminated by user"); } if (onsig == SIGSEGV) { Syslog('+', "Last msg area %s", msgs.Name); } Good_Bye(onsig); }
/* * Open specified message base */ int Msg_Open(char *Base) { int RetVal = FALSE; if (MsgBase.Open) { if (strcmp(MsgBase.Path, Base) != 0) Msg_Close(); else return TRUE; } RetVal = JAM_Open(Base); MsgBase.Open = RetVal; strcpy(MsgBase.Path, Base); return RetVal; }
void FinishMsg(int Final, int filepos) { char *temp; FILE *fp, *fi; Syslog('m', "FinishMsg(%s, %d)", Final ? "TRUE":"FALSE", filepos); temp = calloc(PATH_MAX, sizeof(char)); if (Final && ((fi = OpenMacro(newfiles.Template, newfiles.Language, FALSE)) != NULL)) { /* * Message footer */ MacroVars("CD", "dd", TotalFiles, TotalSize); fseek(fi, filepos, SEEK_SET); Msg_Macro(fi); fclose(fi); MacroClear(); } if (strlen(newfiles.Origin)) Msg_Bot(newfiles.UseAka, newfiles.Origin, newfiles.Template); else Msg_Bot(newfiles.UseAka, CFG.origin, newfiles.Template); Msg_AddMsg(); Msg_UnLock(); Syslog('+', "Posted message %ld, %d bytes", Msg.Id, Msg.Size); chartran_close(); snprintf(temp, PATH_MAX, "%s/tmp/echomail.jam", getenv("MBSE_ROOT")); if ((fp = fopen(temp, "a")) != NULL) { fprintf(fp, "%s %u\n", newfiles.Area, Msg.Id); fclose(fp); } Msg_Close(); free(temp); }
void die(int onsig) { if (onsig && (onsig <= NSIG)) { signal(onsig, SIG_IGN); } if (!do_quiet) { printf("\r"); mbse_colour(CYAN, BLACK); } if (MsgBase.Locked) Msg_UnLock(); if (MsgBase.Open) Msg_Close(); if (onsig) { if (onsig <= NSIG) WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]); else WriteError("Terminated with error %d", onsig); } if (are_tot || are_proc || msg_link) Syslog('+', "Areas [%6d] Processed [%6d] Linked [%6d]", are_tot, are_proc, msg_link); if (msg_tot || msg_del) Syslog('+', "Msgs [%6d] Deleted [%6d]", msg_tot, msg_del); t_end = time(NULL); Syslog(' ', "MBMSG finished in %s", t_elapsed(t_start, t_end)); umask(oldmask); if (!do_quiet) { mbse_colour(LIGHTGRAY, BLACK); printf("\r \n"); } ExitClient(onsig); }
int StartMsg(void) { Syslog('m', "StartMsg()"); if (!Msg_Open(newfiles.Area)) return -1; if (!Msg_Lock(30L)) { Msg_Close(); return -1; } Msg_New(); CountPosted(newfiles.Area); chartran_init((char *)"CP437", get_ic_ftn(newfiles.charset), 'f'); snprintf(Msg.From, 101, "%s", chartran(newfiles.From)); snprintf(Msg.To, 101, "%s", chartran(newfiles.Too)); if (MsgCount == 1) { snprintf(Msg.Subject, 101, "%s", chartran(newfiles.Subject)); TotalSize = TotalFiles = 0; } else snprintf(Msg.Subject, 101, "%s #%d", chartran(newfiles.Subject), MsgCount); snprintf(Msg.FromAddress, 101, "%s", aka2str(newfiles.UseAka)); Msg.Written = time(NULL); Msg.Arrived = time(NULL); Msg.Local = TRUE; Msg.Echomail = TRUE; /* * Start message text including kludges */ Msg_Id(newfiles.UseAka); Msg_Pid(newfiles.charset); return Msg_Top(newfiles.Template, newfiles.Language, newfiles.UseAka); }
/* * Kill messages according to age and max messages. */ void KillArea(char *Path, char *Name, int DaysOld, int MaxMsgs, int Areanr) { unsigned int Number, TotalMsgs = 0, *Active, Counter = 0; int i, DelCount = 0, DelAge = 0, Done; time_t Today, MsgDate; IsDoing("Killing %ld", Areanr); Today = time(NULL) / 86400L; if (Msg_Open(Path)) { if (!do_quiet) { mbse_colour(LIGHTRED, BLACK); printf(" (Killing)"); mbse_colour(LIGHTMAGENTA, BLACK); fflush(stdout); } if (Msg_Lock(30L)) { TotalMsgs = Msg_Number(); if (TotalMsgs) { if ((Active = (unsigned int *)malloc((size_t)((TotalMsgs + 100L) * sizeof(unsigned int)))) != NULL) { i = 0; Number = Msg_Lowest(); do { Active[i++] = Number; } while (Msg_Next(&Number) == TRUE); } } else Active = NULL; Number = Msg_Lowest(); do { if (CFG.slow_util && do_quiet) msleep(1); if ((!do_quiet) && ((Counter % 10L) == 0)) { printf("%6u / %6u\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", Counter, TotalMsgs); fflush(stdout); } if ((Counter % 10L) == 0) DoNop(); Counter++; msg_tot++; if (Msg_ReadHeader(Number) == TRUE) { Done = FALSE; if (DaysOld) { /* * GoldED doesn't fill the Msg.Arrived field, use the * written date instead. */ if (Msg.Arrived == 0L) MsgDate = Msg.Written / 86400L; else MsgDate = Msg.Arrived / 86400L; if ((Today - MsgDate) > DaysOld) { Msg_Delete(Number); Done = TRUE; DelAge++; msg_del++; if (Active != NULL) { for (i = 0; i < TotalMsgs; i++) { if (Active[i] == Number) Active[i] = 0L; } } } } if (Done == FALSE && (MaxMsgs) && Msg_Number() > MaxMsgs) { Msg_Delete(Number); DelCount++; msg_del++; if (Active != NULL) { for (i = 0; i < TotalMsgs; i++) { if (Active[i] == Number) Active[i] = 0L; } } } } } while (Msg_Next(&Number) == TRUE); if (Active != NULL) free(Active); Msg_UnLock(); } else { Syslog('+', "Can't lock msgbase %s", Path); } if (!do_quiet) { printf(" \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } Msg_Close(); Syslog('-', "%6d %6d %6d %6d %6d %s", TotalMsgs, DaysOld, DelAge, MaxMsgs, DelCount, Name); if (!do_quiet) { printf("\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } } else Syslog('+', "Failed to open %s", Path); }
/* * Function will check and create a home directory for the user if * needed. It will also change into the users home directory when * they login. */ char *ChangeHomeDir(char *Name, int Mailboxes) { char *temp; static char temp1[PATH_MAX]; FILE *fp; temp = calloc(PATH_MAX, sizeof(char)); /* * set umask bits to zero's then reset with mkdir */ umask(000); /* * First check to see if users home directory exists * else try create directory, as set in CFG.bbs_usersdir */ if ((access(CFG.bbs_usersdir, R_OK)) != 0) { WriteError("$FATAL: Access to %s failed", CFG.bbs_usersdir); free(temp); ExitClient(MBERR_INIT_ERROR); } snprintf(temp1, PATH_MAX, "%s/%s", CFG.bbs_usersdir, Name); /* * Then check to see if users directory exists in the home dir */ if ((access(temp1, R_OK)) != 0) { WriteError("$FATAL: Users homedir %s doesn't exist", temp1); free(temp); ExitClient(MBERR_INIT_ERROR); } /* * Change to users home directory */ if (chdir(temp1) != 0) { WriteError("$FATAL: Can't change to users home dir, aborting: %s", temp1); free(temp); ExitClient(MBERR_INIT_ERROR); } setenv("HOME", temp1, 1); /* * Check if user has a .signature file. * If not, create a simple one. */ snprintf(temp, PATH_MAX, "%s/%s/.signature", CFG.bbs_usersdir, Name); if (access(temp, R_OK)) { Syslog('+', "Creating users .signature file"); if ((fp = fopen(temp, "w")) == NULL) { WriteError("$Can't create %s", temp); } else { fprintf(fp, " Greetings, %s\n", exitinfo.sUserName); if ((CFG.EmailMode == E_PRMISP) && exitinfo.Email && CFG.GiveEmail) fprintf(fp, " email: %s@%s\n", exitinfo.Name, CFG.sysdomain); fclose(fp); } } /* * Check subdirectories, create them if they don't exist. */ snprintf(temp, PATH_MAX, "%s/wrk", temp1); CheckDir(temp); snprintf(temp, PATH_MAX, "%s/tag", temp1); CheckDir(temp); snprintf(temp, PATH_MAX, "%s/upl", temp1); CheckDir(temp); snprintf(temp, PATH_MAX, "%s/tmp", temp1); CheckDir(temp); snprintf(temp, PATH_MAX, "%s/.dosemu", temp1); CheckDir(temp); snprintf(temp, PATH_MAX, "%s/.dosemu/run", temp1); CheckDir(temp); snprintf(temp, PATH_MAX, "%s/.dosemu/tmp", temp1); CheckDir(temp); umask(007); /* * Check users private emailboxes */ if (Mailboxes) { snprintf(temp, PATH_MAX, "%s/mailbox", temp1); if (Msg_Open(temp)) Msg_Close(); snprintf(temp, PATH_MAX, "%s/archive", temp1); if (Msg_Open(temp)) Msg_Close(); snprintf(temp, PATH_MAX, "%s/trash", temp1); if (Msg_Open(temp)) Msg_Close(); } free(temp); return temp1; }
int Read_a_Email(unsigned int Num) { char *p = NULL, *fn, *charset = NULL, *charsin = NULL; lastread LR; unsigned int mycrc; LastNum = Num; iLineCount = 7; WhosDoingWhat(READ_POST, NULL); /* * The area data is already set, so we can do the next things */ if (EmailBase.Total == 0) { Enter(1); /* There are no messages in this area */ pout(WHITE, BLACK, (char *) Language(205)); Enter(2); sleep(3); return FALSE; } if (!Msg_Open(sMailpath)) { WriteError("Error open JAM base %s", sMailpath); return FALSE; } if (!Msg_ReadHeader(Num)) { Enter(1); pout(WHITE, BLACK, (char *)Language(77)); Enter(2); Msg_Close(); sleep(3); return FALSE; } /* * Fill Quote file in case the user wants to reply. Note that line * wrapping is set lower then normal message read, to create room * for the Quote> strings at the start of each line. */ fn = calloc(PATH_MAX, sizeof(char)); snprintf(fn, PATH_MAX, "%s/%s/.quote", CFG.bbs_usersdir, exitinfo.Name); if ((qf = fopen(fn, "w")) != NULL) { if (Msg_Read(Num, 75)) { if ((p = (char *)MsgText_First()) != NULL) do { if (p[0] == '\001') { /* * Check CHRS kludge */ if (strncmp(p, "\001CHRS: ", 7) == 0) { charset = xstrcpy(p + 7); } /* * While doing this, store the original Message-id in case * a reply will be made. */ if (strncasecmp(p, "\001Message-id: ", 13) == 0) { snprintf(Msg.Msgid, sizeof(Msg.Msgid), "%s", p+13); Syslog('m', "Stored Msgid \"%s\"", Msg.Msgid); } if (Kludges) { p[0] = 'a'; fprintf(qf, "^%s\n", p); } } else fprintf(qf, "%s\n", p); } while ((p = (char *)MsgText_Next()) != NULL); } fclose(qf); } else { WriteError("$Can't open %s", p); } free(fn); if (charset == NULL) { charsin = xstrcpy((char *)"CP437"); } else { charsin = xstrcpy(get_ic_ftn(find_ftn_charset(charset))); } /* * Setup character translation */ chartran_init(charsin, get_ic_ftn(exitinfo.Charset), 'b'); ShowEmailHdr(); /* * Show message text */ colour(CFG.TextColourF, CFG.TextColourB); if (Msg_Read(Num, 79)) { if ((p = (char *)MsgText_First()) != NULL) { do { if (p[0] == '\001') { if (Kludges) { colour(LIGHTGRAY, BLACK); if (p[0] == '\001') p[0] = 'a'; PUTSTR(chartran(p)); Enter(1); if (CheckLine(CFG.TextColourF, CFG.TextColourB, TRUE)) break; } } else { colour(CFG.TextColourF, CFG.TextColourB); if (strchr(p, '>') != NULL) if ((strlen(p) - strlen(strchr(p, '>'))) < 10) colour(CFG.HiliteF, CFG.HiliteB); PUTSTR(chartran(p)); Enter(1); if (CheckLine(CFG.TextColourF, CFG.TextColourB, TRUE)) break; } } while ((p = (char *)MsgText_Next()) != NULL); } } if (charset) free(charset); if (charsin) free(charsin); chartran_close(); /* * Set the Received status on this message. */ if (!Msg.Received) { Syslog('m', "Marking message received"); Msg.Received = TRUE; Msg.Read = time(NULL) - (gmt_offset((time_t)0) * 60); if (Msg_Lock(30L)) { Msg_WriteHeader(Num); Msg_UnLock(); } } /* * Update lastread pointer. */ p = xstrcpy(exitinfo.sUserName); mycrc = StringCRC32(tl(p)); free(p); if (Msg_Lock(30L)) { LR.UserID = grecno; LR.UserCRC = mycrc; if (Msg_GetLastRead(&LR) == TRUE) { LR.LastReadMsg = Num; if (Num > LR.HighReadMsg) LR.HighReadMsg = Num; if (LR.HighReadMsg > EmailBase.Highest) LR.HighReadMsg = EmailBase.Highest; LR.UserCRC = mycrc; if (!Msg_SetLastRead(LR)) WriteError("Error update lastread"); } else { /* * Append new lastread pointer */ LR.UserCRC = mycrc; LR.UserID = grecno; LR.LastReadMsg = Num; LR.HighReadMsg = Num; if (!Msg_NewLastRead(LR)) WriteError("Can't append lastread"); } Msg_UnLock(); } Msg_Close(); return TRUE; }
/* * Export a email to file in the users home directory. */ int Export_a_Email(unsigned int Num) { char *p, temp[21]; LastNum = Num; iLineCount = 7; WhosDoingWhat(READ_POST, NULL); Syslog('+', "Export email %d in area %s", Num, sMailbox); /* * The area data is already set, so we can do the next things */ if (EmailBase.Total == 0) { Enter(1); /* There are no messages in this area */ pout(WHITE, BLACK, (char *) Language(205)); Enter(2); sleep(3); return FALSE; } if (!Msg_Open(sMailpath)) { WriteError("Error open JAM base %s", sMailpath); return FALSE; } if (!Msg_ReadHeader(Num)) { Enter(1); pout(WHITE, BLACK, (char *)Language(77)); Msg_Close(); Enter(2); sleep(3); return FALSE; } /* * Export the message text to the file in the users home/wrk directory. * Create the filename as <areanum>_<msgnum>.msg The message is * written in M$DOS <cr/lf> format. */ p = calloc(PATH_MAX, sizeof(char)); snprintf(p, PATH_MAX, "%s/%s/wrk/%s_%u.msg", CFG.bbs_usersdir, exitinfo.Name, sMailbox, Num); if ((qf = fopen(p, "w")) != NULL) { free(p); p = NULL; if (Msg_Read(Num, 80)) { if ((p = (char *)MsgText_First()) != NULL) { do { if (p[0] == '\001') { if (Kludges) { p[0] = 'a'; fprintf(qf, "^%s\r\n", p); } } else fprintf(qf, "%s\r\n", p); } while ((p = (char *)MsgText_Next()) != NULL); } } fclose(qf); } else { WriteError("$Can't open %s", p); free(p); } Msg_Close(); /* * Report the result. */ Enter(2); pout(CFG.TextColourF, CFG.TextColourB, (char *) Language(46)); snprintf(temp, 21, "%s_%u.msg", sMailbox, Num); pout(CFG.HiliteF, CFG.HiliteB, temp); Enter(2); Pause(); return TRUE; }
/* * Link messages in one area. * Returns -1 if error, else the number of linked messages. */ int Msg_Link(char *Path, int do_quiet, int slow_util) { int i, m, msg_link = 0; unsigned int Number, Prev, Next, Crc, Total; char Temp[128], *p; MSGLINK *Link; if (! Msg_Open(Path)) { return -1; } if (!do_quiet) { msg_colour(LIGHTRED, BLACK); printf(" (linking)"); msg_colour(LIGHTMAGENTA, BLACK); fflush(stdout); } if ((Total = Msg_Number()) != 0L) { if (Msg_Lock(30L)) { if ((Link = (MSGLINK *)malloc((Total + 1) * sizeof(MSGLINK))) != NULL) { memset(Link, 0, (Total + 1) * sizeof(MSGLINK)); Number = Msg_Lowest(); i = 0; do { Msg_ReadHeader(Number); strcpy(Temp, Msg.Subject); p = strupr(Temp); if (!strncmp(p, "RE:", 3)) { p += 3; if (*p == ' ') p++; } Link[i].Subject = StringCRC32(p); Link[i].Number = Number; i++; if (((i % 10) == 0) && (!do_quiet)) { printf("%6d / %6u\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", i, Total); fflush(stdout); } } while(Msg_Next(&Number) == TRUE); if (!do_quiet) { printf("%6d / %6u\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", i, Total); fflush(stdout); } Number = Msg_Lowest(); i = 0; do { Msg_ReadHeader(Number); Prev = Next = 0; Crc = Link[i].Subject; for (m = 0; m < Total; m++) { if (m == i) continue; if (Link[m].Subject == Crc) { if (m < i) Prev = Link[m].Number; else if (m > i) { Next = Link[m].Number; break; } } } if (((i % 10) == 0) && (!do_quiet)) { printf("%6d / %6u\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", i, Total); fflush(stdout); } if (Msg.Original != Prev || Msg.Reply != Next) { Msg.Original = Prev; Msg.Reply = Next; Msg_WriteHeader(Number); msg_link++; } i++; } while(Msg_Next(&Number) == TRUE); if (!do_quiet) { printf("%6d / %6u\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", i, Total); fflush(stdout); } free(Link); } if (!do_quiet) { printf(" \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } Msg_UnLock(); } else { Syslog('+', "Can't lock %s", Path); return -1; } } Msg_Close(); if (!do_quiet) { printf("\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b"); fflush(stdout); } return msg_link; }
/* * Read e-mail, called from the menus */ void Read_Email(void) { char *temp, *p; unsigned int Start, mycrc; lastread LR; if (HasNoEmail()) return; Enter(1); temp = calloc(128, sizeof(char)); /* Message area \"%s\" contains %lu messages. */ snprintf(temp, 128, "\n%s\"%s\" %s%u %s", (char *) Language(221), sMailbox, (char *) Language(222), EmailBase.Total, (char *) Language(223)); pout(CFG.TextColourF, CFG.TextColourB, temp); /* * Check for lastread pointer, suggest lastread number for start. */ Start = EmailBase.Lowest; p = xstrcpy(exitinfo.sUserName); mycrc = StringCRC32(tl(p)); free(p); if (Msg_Open(sMailpath)) { LR.UserID = grecno; LR.UserCRC = mycrc; if (Msg_GetLastRead(&LR)) Start = LR.HighReadMsg + 1; else Start = 1; Msg_Close(); /* * If we already have read the last message, the pointer is * higher then HighMsgNum, we set it at HighMsgNum to prevent * errors and read that message again. */ if (Start > EmailBase.Highest) Start = EmailBase.Highest; } Enter(1); /* Please enter a message between */ snprintf(temp, 81, "%s(%u - %u)", (char *) Language(224), EmailBase.Lowest, EmailBase.Highest); pout(WHITE, BLACK, temp); Enter(1); /* Message number [ */ snprintf(temp, 81, "%s%u]: ", (char *) Language(225), Start); PUTSTR(temp); colour(CFG.InputColourF, CFG.InputColourB); GetstrC(temp, 80); if ((strcmp(temp, "")) != 0) Start = atoi(temp); free(temp); if (!Read_a_Email(Start)) return; if (EmailBase.Total == 0) return; while(EmailPanel()) {} }
/* * Input a RFC news message. */ int rfc2ftn(FILE *fp) { char sbe[16], *p, *q, *temp, *origin, newsubj[4 * (MAXSUBJ+1)], *oldsubj; int i, rc, newsmode, seenlen, oldnet; rfcmsg *msg = NULL, *tmsg, *tmp; ftnmsg *fmsg = NULL; FILE *ofp, *qfp; fa_list *sbl = NULL, *ptl = NULL, *tmpl; faddr *ta, *fta; int sot_kludge = FALSE, eot_kludge = FALSE, tinyorigin = FALSE; int needsplit, hdrsize, datasize, splitpart, forbidsplit, rfcheaders; time_t Now; struct tm *l_date; char *charset = NULL; temp = calloc(4097, sizeof(char)); Syslog('m', "Entering rfc2ftn"); rewind(fp); msg = parsrfc(fp); newsmode = hdr((char *)"Newsgroups", msg) ?TRUE:FALSE; if (newsmode == FALSE) { WriteError("Not a news article"); return 1; } if ((fmsg = mkftnhdr(msg, newsmode, NULL)) == NULL) { WriteError("Unable to create FTN headers from RFC ones, aborting"); tidyrfc(msg); return 1; } fmsg->area = xstrcpy(msgs.Tag); if ((p = hdr((char *)"Message-ID",msg))) { ftnmsgid(p, &fmsg->msgid_a, &fmsg->msgid_n, fmsg->area); hash_update_s(&fmsg->msgid_n, fmsg->area); } if ((p = hdr((char *)"References",msg))) { p = strrchr(p,' '); ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area); //Griffin fmsg->reply_s=calloc(256,sizeof(char)); findorigmsg(p,fmsg->reply_s); fmsg->to->name=calloc(strlen(Msg.From)+1,sizeof(char)); strcpy(fmsg->to->name,Msg.From); Syslog('m', "fmsg to-name %s",fmsg->to->name); Syslog('m', "reply_s %s",fmsg->reply_s); if (!chkftnmsgid(p)) { hash_update_s(&fmsg->reply_n, fmsg->area); } } else if ((p = hdr((char *)"In-Reply-To",msg))) { ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area); if (!chkftnmsgid(p)) { hash_update_s(&fmsg->reply_n, fmsg->area); } } chkftnmsgid(hdr((char *)"Message-ID",msg)); // ?? removemime = FALSE; removemsgid = FALSE; removeref = FALSE; removeinreply = FALSE; removereplyto = TRUE; removereturnto = TRUE; ftnorigin = fmsg->ftnorigin; q = hdr((char *)"Content-Transfer-Encoding",msg); if (q) while (*q && isspace(*q)) q++; if (!(q)) q = (char *)"8bit"; if ((p = hdr((char *)"Content-Type",msg))) { while (*p && isspace(*p)) p++; /* * Check for mime to remove. */ if ((strncasecmp(p, "text/plain", 10) == 0) && ((q == NULL) || (strncasecmp(q,"7bit",4) == 0) || (strncasecmp(q,"8bit",4) == 0))) { removemime = TRUE; /* no need in MIME headers */ } q = strtok(p, " \n\0"); q = strtok(NULL, "; \n\0"); if (q) { while (*q && isspace(*q)) q++; Syslog('m', "charset part: %s", printable(q, 0)); if (q && (strncasecmp(q, "charset=", 8) == 0)) { /* * google.com quotes the charset name */ if (strchr(q, '"')) { charset = xstrcpy(q + 9); charset[strlen(charset)-1] = '\0'; Syslog('m', "Unquoted charset name"); } else { charset = xstrcpy(q + 8); } Syslog('m', "Charset \"%s\"", printable(charset, 0)); } } } if (charset == NULL) { charset = xstrcpy((char *)"ISO-8859-1"); Syslog('m', "No charset, setting default to iso-8859-1"); } chartran_init(charset, get_ic_ftn(msgs.Charset), 'm'); if ((p = hdr((char *)"Message-ID",msg))) { if (!removemsgid) removemsgid = chkftnmsgid(p); } if ((!removeref) && (p = hdr((char *)"References",msg))) { p = xstrcpy(p); q = strtok(p," \t\n"); if ((q) && (strtok(NULL," \t\n") == NULL)) removeref = chkftnmsgid(q); free(p); } if ((p = hdr((char *)"Reply-To",msg))) { removereplyto = FALSE; if ((q = hdr((char *)"From",msg))) { char *r; r = xstrcpy(p); p = r; while(*p && isspace(*p)) p++; if (p[strlen(p)-1] == '\n') p[strlen(p)-1]='\0'; if (strcasestr(q,p)) removereplyto = TRUE; } } if ((p = hdr((char *)"Return-Receipt-To",msg))) { removereturnto = FALSE; if ((q = hdr((char *)"From",msg))) { char *r; r = xstrcpy(p); p = r; while (*p && isspace(*p)) p++; if (p[strlen(p)-1] == '\n') p[strlen(p)-1]='\0'; if (strcasestr(q,p)) removereturnto = TRUE; } } Syslog('m', "removemime=%s removemsgid=%s removeref=%s removeinreply=%s removereplyto=%s removereturnto=%s", removemime ?"TRUE ":"FALSE", removemsgid ?"TRUE ":"FALSE", removeref ?"TRUE ":"FALSE", removeinreply ?"TRUE ":"FALSE", removereplyto ?"TRUE ":"FALSE", removereturnto ?"TRUE ":"FALSE"); p = ascfnode(fmsg->from,0x1f); i = 79-11-3-strlen(p); if (ftnorigin && fmsg->origin && (strlen(fmsg->origin) > i)) { /* This is a kludge... I don't like it too much. But well, if this is a message of FTN origin, the original origin (:) line MUST have been short enough to fit in 79 chars... So we give it a try. Probably it would be better to keep the information about the address format from the origin line in a special X-FTN-... header, but this seems even less elegant. Any _good_ ideas, anyone? */ /* OK, I am keeping this, though if should never be used al long as X-FTN-Origin is used now */ p = ascfnode(fmsg->from,0x0f); Syslog('m', "checkorigin 3"); i = 79-11-3-strlen(p); tinyorigin = TRUE; } if (tinyorigin) Syslog('m', "tinyorigin = %s", tinyorigin ? "True":"False"); if ((fmsg->origin) && (strlen(fmsg->origin) > i)) fmsg->origin[i]='\0'; forbidsplit = (ftnorigin || ((p = hdr((char *)"X-FTN-Split",msg)) && (strcasecmp(p," already\n") == 0))); needsplit = 0; splitpart = 0; hdrsize = 20; hdrsize += (fmsg->subj)?strlen(fmsg->subj):0; if (fmsg->from) hdrsize += (fmsg->from->name)?strlen(fmsg->from->name):0; if (fmsg->to) hdrsize += (fmsg->to->name)?strlen(fmsg->to->name):0; do { Syslog('m', "split loop, splitpart = %d", splitpart); datasize = 0; if (splitpart) { snprintf(newsubj,4 * (MAXSUBJ+1),"[part %d] ",splitpart+1); strncat(newsubj,fmsg->subj,MAXSUBJ-strlen(newsubj)); } else { strncpy(newsubj,fmsg->subj,MAXSUBJ); } newsubj[MAXSUBJ]='\0'; if (splitpart) { hash_update_n(&fmsg->msgid_n,splitpart); } oldsubj = fmsg->subj; fmsg->subj = newsubj; /* * Create a new temp message in FTN style format */ if ((ofp = tmpfile()) == NULL) { WriteError("$Can't open second tmpfile"); tidyrfc(msg); return 1; } if ((fmsg->msgid_a == NULL) && (fmsg->msgid_n == 0)) { Syslog('n', "No Messageid from poster, creating new MSGID"); fprintf(ofp, "\001MSGID: %s %08x\n", aka2str(msgs.Aka), sequencer()); } else { fprintf(ofp, "\001MSGID: %s %08x\n", MBSE_SS(fmsg->msgid_a),fmsg->msgid_n); } if (fmsg->reply_s) fprintf(ofp, "\1REPLY: %s\n", fmsg->reply_s); else if (fmsg->reply_a) fprintf(ofp, "\1REPLY: %s %08x\n", fmsg->reply_a, fmsg->reply_n); Now = time(NULL) - (gmt_offset((time_t)0) * 60); fprintf(ofp, "\001TZUTC: %s\n", gmtoffset(Now)); fprintf(ofp, "\001CHRS: %s\n", getftnchrs(msgs.Charset)); fmsg->subj = oldsubj; if ((p = hdr((char *)"X-FTN-REPLYADDR",msg))) { hdrsize += 10+strlen(p); fprintf(ofp,"\1REPLYADDR:"); kludgewrite(p,ofp); } else if (replyaddr) { hdrsize += 10+strlen(replyaddr); fprintf(ofp,"\1REPLYADDR: "); kludgewrite(replyaddr,ofp); } if ((p = hdr((char *)"X-FTN-REPLYTO",msg))) { hdrsize += 8+strlen(p); fprintf(ofp,"\1REPLYTO:"); kludgewrite(p,ofp); } else if (replyaddr) { hdrsize += 15; if (newsmode) fprintf(ofp,"\1REPLYTO: %s UUCP\n", aka2str(msgs.Aka)); else { fta = bestaka_s(fmsg->to); fprintf(ofp,"\1REPLYTO: %s UUCP\n", ascfnode(fta, 0x1f)); tidy_faddr(fta); } } else if ((p = hdr((char *)"Reply-To",msg))) { if ((ta = parsefaddr(p))) { if ((q = hdr((char *)"From",msg))) { if (!strcasestr(q,p)) { fprintf(ofp,"\1REPLYTO: %s %s\n", ascfnode(ta,0x1f), ta->name); } } tidy_faddr(ta); } } if ((p=strip_flags(hdr((char *)"X-FTN-FLAGS",msg)))) { hdrsize += 15; fprintf(ofp,"\1FLAGS:%s\n",p); free(p); } if (!hdr((char *)"X-FTN-PID", msg)) { p = hdr((char *)"User-Agent", msg); if (p == NULL) p = hdr((char *)"X-Newsreader", msg); if (p == NULL) p = hdr((char *)"X-Mailer", msg); if (p) { hdrsize += 4 + strlen(p); fprintf(ofp, "\1PID:"); kludgewrite(p, ofp); } else { fprintf(ofp, "\001PID: MBSE-NNTPD %s (%s-%s)\n", VERSION, OsName(), OsCPU()); } } if (!(hdr((char *)"X-FTN-Tearline", msg)) && !(hdr((char *)"X-FTN-TID", msg))) { snprintf(temp, 4096, " MBSE-NNTPD %s (%s-%s)", VERSION, OsName(), OsCPU()); hdrsize += 4 + strlen(temp); fprintf(ofp, "\1TID:"); kludgewrite(temp, ofp); } if ((splitpart == 0) || (hdrsize < MAXHDRSIZE)) { for (tmp = msg; tmp; tmp = tmp->next) { if ((!strncmp(tmp->key,"X-Fsc-",6)) || (!strncmp(tmp->key,"X-FTN-",6) && strcasecmp(tmp->key,"X-FTN-Tearline") && strcasecmp(tmp->key,"X-FTN-Origin") && strcasecmp(tmp->key,"X-FTN-Sender") && strcasecmp(tmp->key,"X-FTN-Split") && strcasecmp(tmp->key,"X-FTN-FLAGS") && strcasecmp(tmp->key,"X-FTN-AREA") && strcasecmp(tmp->key,"X-FTN-MSGID") && strcasecmp(tmp->key,"X-FTN-REPLY") && strcasecmp(tmp->key,"X-FTN-SEEN-BY") && strcasecmp(tmp->key,"X-FTN-PATH") && strcasecmp(tmp->key,"X-FTN-REPLYADDR") && strcasecmp(tmp->key,"X-FTN-REPLYTO") && strcasecmp(tmp->key,"X-FTN-To") && strcasecmp(tmp->key,"X-FTN-From") && strcasecmp(tmp->key,"X-FTN-CHARSET") && strcasecmp(tmp->key,"X-FTN-CHRS") && strcasecmp(tmp->key,"X-FTN-CODEPAGE") && strcasecmp(tmp->key,"X-FTN-ORIGCHRS") && strcasecmp(tmp->key,"X-FTN-SOT") && strcasecmp(tmp->key,"X-FTN-EOT") && strcasecmp(tmp->key,"X-FTN-Via"))) { if ((strcasecmp(tmp->key,"X-FTN-KLUDGE") == 0)) { if (!strcasecmp(tmp->val," SOT:\n")) sot_kludge = TRUE; else if (!strcasecmp(tmp->val," EOT:\n")) eot_kludge = TRUE; else { hdrsize += strlen(tmp->val); fprintf(ofp,"\1"); /* we should have restored the original string here... */ kludgewrite((tmp->val)+1,ofp); } } else { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(ofp,"\1%s:",tmp->key+6); kludgewrite(tmp->val,ofp); } } } /* ZConnect are X-ZC-*: in usenet, \1ZC-*: in FTN */ for (tmp=msg;tmp;tmp=tmp->next) if ((!strncmp(tmp->key,"X-ZC-",5))) { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(ofp,"\1%s:",tmp->key+2); kludgewrite(tmp->val,ofp); } /* mondo.org gateway uses ".MSGID: ..." in usenet */ for (tmp=msg;tmp;tmp=tmp->next) if ((!strncmp(tmp->key,".",1)) && (strcasecmp(tmp->key,".MSGID"))) { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(ofp,"\1%s:",tmp->key+1); kludgewrite(tmp->val,ofp); } for (tmp = msg; tmp; tmp = tmp->next) { if ((needputrfc(tmp, newsmode) == 1)) { if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) { hdrsize += 10+strlen(tmp->val); fprintf(ofp,"\1RFC-Newsgroups:"); } else { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(ofp,"\1RFC-%s:",tmp->key); } kludgewrite(tmp->val, ofp); } } rfcheaders=0; for (tmp=msg;tmp;tmp=tmp->next) { if ((needputrfc(tmp, newsmode) > 1)) { rfcheaders++; if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) { hdrsize += 10+strlen(tmp->val); fprintf(ofp,"Newsgroups:"); } else { hdrsize += strlen(tmp->key)+strlen(tmp->val); fprintf(ofp,"%s:",tmp->key); } charwrite(tmp->val, ofp); } } if (rfcheaders) charwrite((char *)"\n",ofp); if ((hdr((char *)"X-FTN-SOT",msg)) || (sot_kludge)) fprintf(ofp,"\1SOT:\n"); } if (replyaddr) { replyaddr = NULL; } if (needsplit) { fprintf(ofp," * Continuation %d of a split message *\n\n", splitpart); needsplit = FALSE; } else if ((p=hdr((char *)"X-Body-Start",msg))) { datasize += strlen(p); charwrite(p, ofp); } while (!(needsplit=(!forbidsplit) && (((splitpart && (datasize > (CFG.new_split * 1024))) || (!splitpart && ((datasize+hdrsize) > (CFG.new_split * 1024)))))) && (bgets(temp,4096-1,fp))) { datasize += strlen(temp); charwrite(temp, ofp); } if (needsplit) { fprintf(ofp,"\n * Message split, to be continued *\n"); splitpart++; } if ((p=hdr((char *)"X-FTN-EOT",msg)) || (eot_kludge)) fprintf(ofp,"\1EOT:\n"); if ((p=hdr((char *)"X-FTN-Tearline",msg))) { fprintf(ofp,"---"); if (strcasecmp(p," (none)\n") == 0) charwrite((char *)"\n",ofp); else charwrite(p,ofp); } else fprintf(ofp,"\n%s\n", TearLine()); if ((p = hdr((char *)"X-FTN-Origin",msg))) { if (*(q=p+strlen(p)-1) == '\n') *q='\0'; origin = xstrcpy((char *)" * Origin: "); origin = xstrcat(origin, p); } else { origin = xstrcpy((char *)" * Origin: "); if (fmsg->origin) origin = xstrcat(origin, fmsg->origin); else origin = xstrcat(origin, CFG.origin); origin = xstrcat(origin, (char *)" ("); origin = xstrcat(origin, ascfnode(fmsg->from,tinyorigin?0x0f:0x1f)); origin = xstrcat(origin, (char *)")"); } fprintf(ofp, "%s", origin); if (newsmode) { /* * Setup SEEN-BY lines, first SEEN-BY from RFC message, then all matching AKA's */ for (tmsg = msg; tmsg; tmsg = tmsg->next) if (strcasecmp(tmsg->key, "X-FTN-SEEN-BY") == 0) fill_list(&sbl, tmsg->val, NULL); for (i = 0; i < 40; i++) { if (CFG.akavalid[i] && (CFG.aka[i].point == 0) && (msgs.Aka.zone == CFG.aka[i].zone) && !((msgs.Aka.net == CFG.aka[i].net) && (msgs.Aka.node == CFG.aka[i].node))) { snprintf(sbe, 16, "%u/%u", CFG.aka[i].net, CFG.aka[i].node); fill_list(&sbl, sbe, NULL); } } if (msgs.Aka.point == 0) { snprintf(sbe, 16, "%u/%u", msgs.Aka.net, msgs.Aka.node); fill_list(&sbl, sbe, NULL); } /* * Only add SEEN-BY lines if there are any */ if (sbl != NULL) { uniq_list(&sbl); sort_list(&sbl); seenlen = MAXSEEN + 1; memset(&sbe, 0, sizeof(sbe)); /* ensure it will not match for the first entry */ oldnet = sbl->addr->net-1; for (tmpl = sbl; tmpl; tmpl = tmpl->next) { if (tmpl->addr->net == oldnet) snprintf(sbe,16," %u",tmpl->addr->node); else snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node); oldnet = tmpl->addr->net; seenlen += strlen(sbe); if (seenlen > MAXSEEN) { seenlen = 0; fprintf(ofp,"\nSEEN-BY:"); snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node); seenlen = strlen(sbe); } fprintf(ofp,"%s",sbe); } tidy_falist(&sbl); } /* * Setup PATH lines */ for (tmp = msg; tmp; tmp = tmp->next) if (!strcasecmp(tmp->key,"X-FTN-PATH")) fill_path(&ptl,tmp->val); if (msgs.Aka.point == 0) { snprintf(sbe,16,"%u/%u",msgs.Aka.net, msgs.Aka.node); fill_path(&ptl,sbe); } /* * Only add PATH line if there is something */ if (ptl != NULL) { uniq_list(&ptl); seenlen = MAXPATH+1; /* ensure it will not match for the first entry */ oldnet = ptl->addr->net-1; for (tmpl = ptl; tmpl; tmpl = tmpl->next) { if (tmpl->addr->net == oldnet) snprintf(sbe,16," %u",tmpl->addr->node); else snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node); oldnet = tmpl->addr->net; seenlen += strlen(sbe); if (seenlen > MAXPATH) { seenlen = 0; fprintf(ofp,"\n\1PATH:"); snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node); seenlen = strlen(sbe); } fprintf(ofp,"%s",sbe); } tidy_falist(&ptl); } } /* if (newsmode) */ /* * Add newline and message is ready. */ fprintf(ofp,"\n"); fflush(ofp); rewind(ofp); Syslog('m', "========== Fido start"); while (fgets(temp, 4096, ofp) != NULL) { /* * Only log kludges, skip the body */ if ((temp[0] == '\001') || !strncmp(temp, "AREA:", 5) || !strncmp(temp, "SEEN-BY", 7)) { Striplf(temp); Syslogp('m', printable(temp, 0)); } } Syslog('m', "========== Fido end"); if (!Msg_Open(msgs.Base)) { WriteError("Failed to open msgbase \"%s\"", msgs.Base); } else { if (!Msg_Lock(30L)) { WriteError("Can't lock %s", msgs.Base); } else { Msg_New(); strcpy(Msg.From, fmsg->from->name); strcpy(Msg.To, fmsg->to->name); strcpy(Msg.FromAddress, ascfnode(fmsg->from,0x1f)); strcpy(Msg.Subject, fmsg->subj); Msg.Written = Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60); Msg.Local = TRUE; rewind(ofp); while (fgets(temp, 4096, ofp) != NULL) { Striplf(temp); MsgText_Add2(temp); } Msg_AddMsg(); Msg_UnLock(); Syslog('+', "Msg (%ld) to \"%s\", \"%s\"", Msg.Id, Msg.To, Msg.Subject); do_mailout = TRUE; /* * Create fast scan index */ snprintf(temp, PATH_MAX, "%s/tmp/echomail.jam", getenv("MBSE_ROOT")); if ((qfp = fopen(temp, "a")) != NULL) { fprintf(qfp, "%s %u\n", msgs.Base, Msg.Id); fclose(qfp); } /* * Link messages */ rc = Msg_Link(msgs.Base, TRUE, CFG.slow_util); if (rc != -1) Syslog('+', "Linked %d message%s", rc, (rc != 1) ? "s":""); else Syslog('+', "Could not link messages"); /* * Update statistical counters */ Now = time(NULL); l_date = localtime(&Now); msgs.LastPosted = time(NULL); msgs.Posted.total++; msgs.Posted.tweek++; msgs.Posted.tdow[l_date->tm_wday]++; msgs.Posted.month[l_date->tm_mon]++; mgroup.LastDate = time(NULL); mgroup.MsgsSent.total++; mgroup.MsgsSent.tweek++; mgroup.MsgsSent.tdow[l_date->tm_wday]++; mgroup.MsgsSent.month[l_date->tm_mon]++; UpdateMsgs(); snprintf(temp, PATH_MAX, "%s/etc/users.data", getenv("MBSE_ROOT")); if ((qfp = fopen(temp, "r+"))) { fread(&usrconfighdr, sizeof(usrconfighdr), 1, qfp); fseek(qfp, usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize), SEEK_SET); if (fread(&usrconfig, usrconfighdr.recsize, 1, qfp) == 1) { usrconfig.iPosted++; fseek(qfp, usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize), SEEK_SET); fwrite(&usrconfig, usrconfighdr.recsize, 1, qfp); } fclose(qfp); } } Msg_Close(); } free(origin); fclose(ofp); } while (needsplit); free(temp); if (charset) free(charset); chartran_close(); tidyrfc(msg); tidy_ftnmsg(fmsg); UpdateMsgs(); return 0; }
int Post(char *To, int Area, char *Subj, char *File, char *Flavor) { int i, rc = FALSE, has_tear = FALSE, has_origin = FALSE; char *aka, *temp, *sAreas; FILE *fp, *tp; unsigned int crc = -1; time_t tt; struct tm *t; ftnd_CleanSubject(Subj); if (!do_quiet) { ftnd_colour(CYAN, BLACK); printf("Post \"%s\" to \"%s\" in area %d\n", File, To, Area); } IsDoing("Posting"); Syslog('+', "Post \"%s\" area %d to \"%s\" flavor %s", File, Area, To, Flavor); Syslog('+', "Subject: \"%s\"", Subj); if ((tp = fopen(File, "r")) == NULL) { WriteError("$Can't open %s", File); if (!do_quiet) printf("Can't open \"%s\"\n", File); return -1; } sAreas = calloc(PATH_MAX, sizeof(char)); snprintf(sAreas, PATH_MAX, "%s/etc/mareas.data", getenv("FTND_ROOT")); if ((fp = fopen(sAreas, "r")) == NULL) { WriteError("$Can't open %s", sAreas); free(sAreas); fclose(tp); return -1; } fread(&msgshdr, sizeof(msgshdr), 1, fp); if (fseek(fp, (msgshdr.recsize + msgshdr.syssize) * (Area - 1), SEEK_CUR) == 0) { if (fread(&msgs, msgshdr.recsize, 1, fp) == 1) { rc = TRUE; } else { WriteError("$Can't read area %ld", Area); } } else { WriteError("$Can't seek area %ld", Area); } free(sAreas); if (rc == FALSE) { fclose(fp); fclose(tp); return -1; } if (!msgs.Active) { WriteError("Area %s not active", msgs.Name); fclose(fp); fclose(tp); return -1; } /* * Check the proper syntax in the To parameter, in netmail areas * it must have a destination address, in all other areas just a * full name. */ if (msgs.Type == NETMAIL) { if ((strchr(To, '@') == NULL) || (strstr(To, (char *)".n") == NULL) || (strstr(To, (char *)".z") == NULL)) { WriteError("No address in \"%s\" and area is netmail", To); if (!do_quiet) printf("No address in \"%s\" and area is netmail\n", To); fclose(fp); fclose(tp); return -1; } } else { if ((strchr(To, '@')) || (strstr(To, (char *)".n")) || (strstr(To, (char *)".z"))) { WriteError("Address present in \"%s\" and area is not netmail", To); if (!do_quiet) printf("Address present in \"%s\" and area is not netmail\n", To); fclose(fp); fclose(tp); return -1; } } if (!Msg_Open(msgs.Base)) { WriteError("Can't open %s", msgs.Base); fclose(fp); fclose(tp); return -1; } if (!Msg_Lock(30L)) { WriteError("Can't lock %s", msgs.Base); Msg_Close(); fclose(fp); fclose(tp); return -1; } tt = time(NULL); t = localtime(&tt); Diw = t->tm_wday; Miy = t->tm_mon; memset(&Msg, 0, sizeof(Msg)); Msg_New(); /* * Update statistic counter for message area */ fseek(fp, - msgshdr.recsize, SEEK_CUR); msgs.Posted.total++; msgs.Posted.tweek++; msgs.Posted.tdow[Diw]++; msgs.Posted.month[Miy]++; fwrite(&msgs, msgshdr.recsize, 1, fp); fclose(fp); /* * Start writing the message */ snprintf(Msg.From, 101, CFG.sysop_name); snprintf(Msg.To, 101, To); /* * If netmail, clean the To field. */ if ((msgs.Type == NETMAIL) && strchr(To, '@')) { for (i = 0; i < strlen(Msg.To); i++) { if (Msg.To[i] == '_') Msg.To[i] = ' '; if (Msg.To[i] == '@') { Msg.To[i] = '\0'; break; } } } snprintf(Msg.Subject, 101, "%s", Subj); snprintf(Msg.FromAddress, 101, "%s", aka2str(msgs.Aka)); Msg.Written = Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60); Msg.Local = TRUE; if (strchr(Flavor, 'c')) Msg.Crash = TRUE; if (strchr(Flavor, 'p')) Msg.Private = TRUE; if (strchr(Flavor, 'h')) Msg.Hold = TRUE; switch (msgs.Type) { case LOCALMAIL: Msg.Localmail = TRUE; break; case NETMAIL: Msg.Netmail = TRUE; snprintf(Msg.ToAddress, 101, "%s", ascfnode(parsefaddr(To), 0xff)); break; case ECHOMAIL: Msg.Echomail = TRUE; break; case NEWS: Msg.News = TRUE; break; } temp = calloc(PATH_MAX, sizeof(char)); snprintf(temp, PATH_MAX, "\001MSGID: %s %08x", aka2str(msgs.Aka), sequencer()); MsgText_Add2(temp); Msg.MsgIdCRC = upd_crc32(temp, crc, strlen(temp)); Msg.ReplyCRC = 0xffffffff; snprintf(temp, PATH_MAX, "\001PID: FTND-FIDO %s (%s-%s)", VERSION, OsName(), OsCPU()); MsgText_Add2(temp); if (msgs.Charset != FTNC_NONE) { snprintf(temp, PATH_MAX, "\001CHRS: %s", getftnchrs(msgs.Charset)); } else { snprintf(temp, PATH_MAX, "\001CHRS: %s", getftnchrs(FTNC_LATIN_1)); } MsgText_Add2(temp); snprintf(temp, PATH_MAX, "\001TZUTC: %s", gmtoffset(tt)); MsgText_Add2(temp); while ((Fgets(temp, PATH_MAX, tp)) != NULL) { if (strncmp(temp, "--- ", 4) == 0) has_tear = TRUE; if (strncmp(temp, " * Origin: ", 11) == 0) has_origin = TRUE; } rewind(tp); Syslog('m', "has tearline=%s, has origin=%s", has_tear?"True":"False", has_origin?"True":"False"); /* * Add the file as text */ Msg_Write(tp); fclose(tp); /* * Finish the message */ if ((! has_tear) && (! has_origin)) { MsgText_Add2((char *)""); MsgText_Add2(TearLine()); } if (! has_origin) { aka = calloc(40, sizeof(char)); if (msgs.Aka.point) snprintf(aka, 40, "(%d:%d/%d.%d)", msgs.Aka.zone, msgs.Aka.net, msgs.Aka.node, msgs.Aka.point); else snprintf(aka, 40, "(%d:%d/%d)", msgs.Aka.zone, msgs.Aka.net, msgs.Aka.node); if (strlen(msgs.Origin)) snprintf(temp, 81, " * Origin: %s %s", msgs.Origin, aka); else snprintf(temp, 81, " * Origin: %s %s", CFG.origin, aka); MsgText_Add2(temp); free(aka); } Msg_AddMsg(); Msg_UnLock(); Syslog('+', "Posted message %ld", Msg.Id); if (msgs.Type != LOCALMAIL) { snprintf(temp, PATH_MAX, "%s/tmp/%smail.jam", getenv("FTND_ROOT"), (msgs.Type == ECHOMAIL) ? "echo" : "net"); if ((fp = fopen(temp, "a")) != NULL) { fprintf(fp, "%s %u\n", msgs.Base, Msg.Id); fclose(fp); } CreateSema((char *)"mailout"); } free(temp); Msg_Close(); return 0; }