home *** CD-ROM | disk | FTP | other *** search
- /* @(#)msgs.c (c) copyright 10/18/86 (Dan Heller) */
-
- #include "mush.h"
-
- void
- display_msg(n, flg)
- register int n;
- long flg;
- {
- if (ison(msg[n].m_flags, DELETE) && !do_set(set_options, "show_deleted")) {
- print("Message %d deleted; ", n+1);
- #ifdef SUNTOOL
- if (istool)
- print_more("Select UNDELETE to read."), do_clear();
- else
- #endif /* SUNTOOL */
- if (iscurses)
- print_more("Type 'u' to undelete.");
- else
- print("Type 'undelete %d' to undelete\n", n+1);
- return;
- }
- set_isread(n);
- if (ison(flg, M_TOP)) {
- turnon(flg, NO_HEADER);
- print("Top of "), turnon(glob_flags, CONT_PRNT);
- }
-
- #ifdef MMDF
- turnon(flg, NO_SEPARATOR);
- #endif /* MMDF */
- if (!istool && isoff(flg, NO_PAGE) &&
- crt < msg[n].m_lines && isoff(flg, M_TOP)) {
- char buf[32], *pager = do_set(set_options, "pager");
- if (!pager)
- pager = DEF_PAGER;
- if (!*pager || !strcmp(pager, "internal"))
- pager = NULL; /* default to internal pager if pager set to "" */
- (void) do_pager(pager, TRUE); /* start pager */
- (void) do_pager(sprintf(buf, "Message #%d (%d lines)\n",
- n+1, msg[n].m_lines), FALSE);
- (void) copy_msg(n, NULL_FILE, flg);
- (void) do_pager(NULL, FALSE); /* end pager */
- } else {
- print("Message #%d (%d lines)\n", n+1, msg[n].m_lines);
- (void) copy_msg(n, stdout, flg);
- }
- }
-
- /*
- * copy message 'n' to file "fp" according to various flag arguments
- * return number of lines copied or -1 if system error on fputs.
- * If "fp" is null, send to internal pager. This can only happen from
- * display_msg above.
- */
- copy_msg(n, fp, flags)
- register int n;
- register FILE *fp;
- u_long flags;
- {
- register int ignoring = 0, lines = 0;
- register char *indent_str;
- int on_hdr = 1, top, squeeze = 0;
- char line[BUFSIZ], *show_hdrs = NULL;
-
- still_more = 0;
- if (ison(flags, M_TOP)) {
- register char *p = do_set(set_options, "toplines");
- top = (p)? atoi(p) : crt;
- }
- /* When updating to a folder, always write all headers! */
- if (ison(flags, UPDATE_STATUS))
- turnon(flags, NO_IGNORE);
- else if (do_set(set_options, "alwaysignore"))
- turnoff(flags, NO_IGNORE);
- if (isoff(flags, NO_IGNORE)) {
- if (do_set(set_options, "squeeze"))
- squeeze = 1;
- show_hdrs = do_set(set_options, "show_hdrs");
- }
-
- #ifdef SUNTOOL
- if (istool && (!fp || fp == stdout)) {
- register int x = (msg[n].m_lines + 2) * l_height(curfont);
-
- if (x > 32765) { /* to overcome a bug in pixrects that sun won't fix */
- print("message too big to display using this font");
- return 0;
- }
- if (x < msg_rect.r_height) /* make it at least as big as the window */
- x = msg_rect.r_height;
- /* If the window isn't big enough, an infinite loop occurs in Addstr */
- if (x < 2 * l_height(curfont) || msg_rect.r_width < 3*l_width(curfont))
- return 0;
- do_clear();
- lock_cursors();
- /* msg_pix is for Addstr() */
- if (!(msg_pix = mem_create(msg_rect.r_width, x, 1))) {
- error("mem_create");
- return 0;
- }
- pr_rop(msg_pix, 0,0, msg_rect.r_width-1, x-1, PIX_CLR, 0,0,0);
- on_hdr = 1;
- }
- #endif /* SUNTOOL */
- if (ison(flags, INDENT)) {
- if ((indent_str = do_set(set_options, "pre_indent_str"))) {
- char *old_fmt = hdr_format;
- hdr_format = indent_str;
- fprintf(fp, "%s\n", compose_hdr(n) + 9); /* magic number 9 !! */
- hdr_format = old_fmt;
- }
- if (!(indent_str = do_set(set_options, "indent_str")))
- indent_str = DEF_INDENT_STR;
- }
- /* "line" used as dummy here, since 0 bytes read */
- if (!msg_get(n, line, 0)) {
- error("Unable to find msg %d", n+1);
- return -1;
- }
- while (still_more < msg[n].m_size && fgets(line, sizeof (line), tmpf)) {
- still_more += strlen(line);
- #ifdef MMDF
- if (ison(flags, NO_SEPARATOR)) {
- if (!strncmp(line, MSG_SEPARATOR, 4))
- continue;
- }
- #endif /* MMDF */
- /*
- * If squeeze is one, all blanks lines squeeze down to one blank line.
- * If squeeze is two, squeezing is in progress so wait for the next \n.
- */
- if (*line == '\n') {
- if (on_hdr) /* blank line -- end of header */
- turnoff(flags, NO_HEADER), on_hdr = 0;
- if (squeeze > 1)
- continue;
- else if (squeeze)
- squeeze = 2;
- } else if (squeeze > 1)
- squeeze = 1;
-
- if (ison(flags, UPDATE_STATUS))
- if (!strncmp(line, "Status:", 7))
- continue; /* ignore this and other "Status" lines */
- else if (!on_hdr) {
- /* preserve NEW/UNREAD status on preserved messages */
- register char *p = line;
- p += Strcpy(p, "Status: O");
- if (isoff(msg[n].m_flags, UNREAD) &&
- isoff(msg[n].m_flags, PRESERVE))
- *p++ = 'R';
- if (ison(msg[n].m_flags, SAVED))
- *p++ = 'S';
- if (ison(msg[n].m_flags, REPLIED))
- *p++ = 'r';
- *p++ = '\n', *p = 0;
- fputs(line, fp);
- (void) strcpy(line, "\n");
- turnoff(flags, UPDATE_STATUS);
- }
- if (on_hdr && (isoff(flags, NO_IGNORE) || ison(flags, FORWARD))) {
- register char *p = any(line, " \t:");
- if (!p)
- ignoring = 0, on_hdr = 0;
- else if (ignoring)
- if (*p != ':') {
- Debug("Ignoring: %s", line);
- continue;
- } else
- ignoring = 0;
- if (p && *p == ':') {
- *p = 0;
- ignoring = 0;
- if (show_hdrs) {
- if (!chk_two_lists(line, show_hdrs, ":, \t"))
- ignoring = 1;
- } else if (ison(flags, FORWARD)) {
- if (chk_two_lists(line, IGNORE_ON_FWD, ":, \t"))
- ignoring = 1;
- } else {
- register struct options *opts;
- for (opts = ignore_hdr; opts; opts = opts->next)
- if (!lcase_strncmp(opts->option, line, -1)) {
- ignoring = 1;
- break;
- }
- }
- *p = ':';
- if (ignoring) {
- Debug("Ignoring: %s", line);
- continue;
- }
- }
- }
- if (!on_hdr && ison(flags, M_TOP) && !--top)
- break;
- if (isoff(flags, NO_HEADER)) {
- /* note that function returns the number of lines */
- lines++;
- #ifdef SUNTOOL
- if (istool && (!fp || fp == stdout)) {
- Addstr(line);
- continue;
- }
- #endif /* SUNTOOL */
- if (ison(flags, INDENT))
- fputs(indent_str, fp);
- if (!fp) {
- if (do_pager(line, FALSE) == EOF)
- return -1;
- } else if (fputs(line, fp) == EOF)
- /* Pipe broken, out of file space, etc */
- return -1;
- }
- }
- if (ison(flags, INDENT) &&
- (indent_str = do_set(set_options, "post_indent_str")) && *indent_str) {
- char *old_fmt = hdr_format;
- hdr_format = indent_str;
- fprintf(fp, "%s\n", compose_hdr(n)+9); /* magic number 9 !! */
- hdr_format = old_fmt;
- }
- #ifdef SUNTOOL
- if (istool && (!fp || fp == stdout)) {
- unlock_cursors();
- txt.y = still_more = msg_rect.r_height;
- scroll_win(0); /* causes a display */
- }
- #endif /* SUNTOOL */
- return lines;
- }
-
- /*
- * copy tempfile back to folder.
- * Return 1 on success, 0 on failure.
- */
- copyback(prompt)
- char *prompt;
- {
- register int i=0, j=0, k=0;
- register long flg = 0;
- register FILE *mbox = NULL_FILE, *mail_fp = NULL_FILE;
- #ifndef DOT_LOCK
- #ifdef SYSV
- FILE *save_mail_fp = NULL_FILE;
- #endif /* SYSV */
- #endif /* !DOT_LOCK */
- char *mbox_file, action = 0;
- int hold = 0, delete_it = 0, dont_unlink = FALSE;
- int isspool, keepsave;
- static int first = 1;
-
- /*
- * if there is new mail in this folder, the user is notified and
- * prompted if he really wants to update the folder. He's either
- * quitting or changing folders, so let him read the new mail first.
- */
- if (!first && check_new_mail() > 0) {
- if (!istool) {
- char buf[16];
- if (iscurses)
- putchar('\n'), turnon(glob_flags, CNTD_CMD);
- print("%s [n] ", prompt);
- buf[0] = 0;
- if (!Getstr(buf, sizeof (buf), 0) || lower(*buf) != 'y')
- return 0;
- }
- }
- first = 0;
-
- /* If the user hasn't changed anything, just return true */
- if (isoff(glob_flags, DO_UPDATE))
- return 1;
- if (ison(glob_flags, READ_ONLY)) {
- print("Unable to update %s: read only\n", mailfile);
- return 0; /* user should use "exit" instead of "quit". */
- }
- if (!msg_cnt) /* prevent unnecessary overwrite */
- return 1;
-
- #ifdef SUNTOOL
- if (istool) {
- timerclear(&(mail_timer.it_interval));
- timerclear(&(mail_timer.it_value));
- }
- #endif /* SUNTOOL */
-
- /* open mbox if: "autodelete" AND "hold" are NOT set. */
- if (!strcmp(mailfile, spoolfile)
- && !(delete_it = !!do_set(set_options, "autodelete"))
- && !(hold = !!do_set(set_options, "hold"))) {
- register char *p;
- int x = 1; /* tell getpath to ignore "ENOENT" if file not found */
-
- if (!(p = do_set(set_options, "mbox")))
- p = DEF_MBOX;
- mbox_file = getpath(p, &x);
- if (x) {
- if (x > 0)
- print("%s is a directory.\n", mbox_file);
- else
- print("Unable to open %s: %s\n", p, mbox_file);
- mbox = NULL_FILE;
- } else {
- if (Access(mbox_file, F_OK) == -1) /* does it exist? */
- mbox = mask_fopen(mbox_file, "w");
- else
- mbox = mask_fopen(mbox_file, "a");
- if (!mbox)
- error("Unable to write to %s", mbox_file);
- }
- }
- #ifdef DOT_LOCK
- if ((i = dot_lock(mailfile)) == 0)
- #endif /* DOT_LOCK */
- #ifdef DOT_LOCK
- mail_fp = mask_fopen(mailfile, "w+");
- #else /* !DOT_LOCK */
- /* We can't lock a file unless we have an fd, but "w+" will zero
- * the file. If the lock later failed for any reason (possible
- * race condition with an MTA), we would lose all current mail.
- * So, open read/write (if possible) and truncate later.
- */
- mail_fp = mask_fopen(mailfile, "r+");
- #endif /* DOT_LOCK */
- if (!mail_fp) {
- error("Unable to rewrite %s", mailfile);
- if (mbox)
- fclose(mbox);
- return 0;
- }
- if (i != 0 || lock_file(mailfile, mail_fp) == -1) {
- #ifndef DOT_LOCK
- error("WARNING: unable to lock %s", mailfile);
- #endif /* DOT_LOCK */
- if (mail_fp)
- close_lock(mailfile, mail_fp);
- if (mbox)
- fclose(mbox);
- return 0;
- }
- #if !defined(DOT_LOCK) && defined(SYSV)
- /* SysV can't truncate a file in the middle, so we can't just
- * write to mail_fp and close. Instead, we save the mail_fp
- * and reopen for writing, ignoring our own lock. After updating,
- * we can safely fclose both file pointers.
- */
- save_mail_fp = mail_fp;
- /* This could fail if we run out of file descriptors */
- if (!(mail_fp = fopen(mailfile, "w"))) {
- error("WARNING: unable to reopen %s for update", mailfile);
- if (save_mail_fp)
- close_lock(mailfile, save_mail_fp);
- if (mbox)
- fclose(mbox);
- return 0;
- }
- #endif /* SYSV && !DOT_LOCK */
-
- print("Updating \"%s\"", mailfile);
-
- turnon(flg, UPDATE_STATUS);
- turnon(glob_flags, IGN_SIGS);
-
- keepsave = !!do_set(set_options, "keepsave");
- isspool = !strcmp(mailfile, spoolfile);
-
- for (i = 0; i < msg_cnt; i++)
- /* check to see if message is marked for deletion or, if read and not
- * preserved, delete it if autodelete is set. Otherwise, save the
- * message in the spool file if hold is set. If all fails, save in mbox.
- */
- if (ison(msg[i].m_flags, DELETE)
- || ison(msg[i].m_flags, SAVED) && !keepsave &&
- isoff(msg[i].m_flags, PRESERVE) && isspool
- || isoff(msg[i].m_flags, UNREAD) && isoff(msg[i].m_flags, PRESERVE)
- && delete_it) {
- Debug("%s %d",
- (action!='d')? "\ndeleting message:" : "", i+1), action = 'd';
- continue;
- } else if (ison(msg[i].m_flags, UNREAD) ||
- ison(msg[i].m_flags, PRESERVE) || hold || !mbox) {
- j++;
- Debug("%s %d",
- (action!='s')? "\nsaving in spool:" : "", i+1), action = 's';
- if (copy_msg(i, mail_fp, flg) == -1) {
- error("WARNING: unable to write back to spool");
- print("ALL mail left in %s\n", tempfile);
- print("Spool mailbox may be corrupted.\n");
- dont_unlink = TRUE;
- break;
- }
- } else if (isspool) { /* copy back to mbox */
- k++;
- if (copy_msg(i, mbox, flg) == -1) {
- error("WARNING: unable to write to mbox");
- print("Unresolved mail left in %s\n", tempfile);
- dont_unlink = TRUE;
- break;
- }
- Debug("%s %d",
- (action!='m')? "\nsaving in mbox:" : "", i+1), action = 'm';
- }
- Debug("\n%s", mailfile);
-
- #ifndef DOT_LOCK
- #ifdef SYSV
- /* Close the write file pointer first */
- fclose(mail_fp);
- mail_fp = save_mail_fp;
- #else /* !SYSV */
- /* Truncate the file at the end of what we just wrote.
- * If you aren't SYSV and you still can't ftruncate(),
- * you're out of luck?
- */
- (void) ftruncate(fileno(mail_fp), ftell(mail_fp));
- #endif /* SYSV */
- #endif /* !DOT_LOCK */
-
- close_lock(mailfile, mail_fp);
-
- #ifdef SUNTOOL
- if (istool) {
- mail_timer.it_value.tv_sec = time_out;
- setitimer(ITIMER_REAL, &mail_timer, NULL);
- }
- #endif /* SUNTOOL */
-
- /* some users like to have zero length folders for frequent usage */
- if (mbox)
- fclose(mbox);
- if (j) {
- long times[2];
- times[1] = time(×[0]) - (long)2;
- if (!strcmp(mailfile, spoolfile) && utime(mailfile, times))
- error("utime");
- print_more(": saved %d message%s\n", j, (j==1)? NO_STRING: "s");
- } else
- #ifdef HOMEMAIL
- if (!dont_unlink && !do_set(set_options, "save_empty"))
- #else /* HOMEMAIL */
- if (strcmp(mailfile, spoolfile) && !dont_unlink &&
- !do_set(set_options, "save_empty"))
- #endif /* HOMEMAIL */
- if (unlink(mailfile))
- turnon(glob_flags, CONT_PRNT), error(": cannot remove");
- else
- print_more(": removed\n");
- else
- print_more(": empty\n");
- if (k)
- print("saved %d message%s in %s\n",k,(k==1)? NO_STRING:"s", mbox_file);
-
- turnoff(glob_flags, IGN_SIGS);
-
- return 1;
- }
-
- /*
- * check the sizes of the current folder (file) and the spool file.
- * spool_size is the size in bytes of the user's main mailbox.
- * last_size is the size of the _current_ folder the last time we checked.
- * return true if the current folder has new mail. check_new_mail() checks
- * for new mail in the system mailbox since it checks against last_spool_size.
- */
- mail_size()
- {
- struct stat buf;
- if (strcmp(mailfile, spoolfile) && !stat(spoolfile, &buf))
- spool_size = buf.st_size;
- if (!*mailfile)
- return 0;
- if (stat(mailfile, &buf)) {
- if (errno != ENOENT)
- error("Unable to stat %s", mailfile);
- return 0;
- }
- if (!strcmp(mailfile, spoolfile))
- spool_size = buf.st_size;
- if (buf.st_size != last_size) {
- last_size = buf.st_size;
- return 1;
- }
- return 0;
- }
-
- void
- mail_status(as_prompt)
- {
- static char buf[256];
- register int cnt = 0, new = 0, unread = 0, deleted = 0;
-
- for ( ; cnt < msg_cnt; cnt++) {
- if (ison(msg[cnt].m_flags, UNREAD))
- unread++;
- if (ison(msg[cnt].m_flags, DELETE))
- deleted++;
- if (isoff(msg[cnt].m_flags, OLD))
- new++;
- }
- if (as_prompt) {
- register char *p, *b = buf;
- for (p = prompt; *p; p++)
- if (*p == '\\')
- switch (*++p) {
- case 'n': case 'r': *b++ = '\n';
- when 't': *b++ = '\t';
- otherwise: *b++ = *p;
- }
- else if (*p == '%')
- switch (*++p) {
- case 'm':
- b += strlen(sprintf(b,"%d",(msg_cnt)? current_msg+1:0));
- when 't':
- b += strlen(sprintf(b, "%d", msg_cnt));
- when 'd':
- b += strlen(sprintf(b, "%d", deleted));
- when 'u':
- b += strlen(sprintf(b, "%d", unread));
- when 'n':
- b += strlen(sprintf(b, "%d", new));
- when 'f':
- {
- char *tail = rindex(mailfile, '/');
- if (tail && tail[1])
- b += Strcpy(b, tail+1);
- else
- /* Fall through */
- case 'F':
- b += Strcpy(b, mailfile);
- if (ison(glob_flags, READ_ONLY))
- b += Strcpy(b, " [read-only]");
- }
- when 'T': case 'D': case 'Y': case 'y':
- case 'M': case 'N': case 'W':
- b += Strcpy(b, Time(p, (long)0));
- otherwise: *b++ = *p;
- }
- else if (*p == '!')
- b += strlen(sprintf(b, "%d", hist_no+1));
- else
- *b++ = *p;
- *b = 0;
- print("%s", buf); /* use %s in case "buf" has any %'s in it */
- return;
- }
- (void) sprintf(buf,"\"%s\"%s: %d message%s, %d new, %d unread",
- mailfile, ison(glob_flags, READ_ONLY)? " [read only]" : "",
- msg_cnt, (msg_cnt != 1)? "s": NO_STRING, new, unread);
- if (istool || iscurses)
- (void) sprintf(buf+strlen(buf), ", %d deleted", deleted);
- #ifdef SUNTOOL
- if (istool) {
- static char ic_text[4];
- extern struct pixrect mail_icon_image1, mail_icon_image2;
- (void) sprintf(ic_text, "%3d", msg_cnt);
- tool_set_attributes(tool,
- WIN_LABEL, buf,
- WIN_ICON_LABEL, ic_text,
- WIN_ICON_IMAGE, ison(glob_flags, NEW_MAIL)?
- &mail_icon_image2 : &mail_icon_image1,
- 0);
- } else
- #endif /* SUNTOOL */
- #ifdef CURSES
- if (iscurses) {
- move (0, 0);
- printw("%-3d %-.*s",
- ((msg_cnt)? current_msg+1 : 0), COLS-5, buf), clrtoeol();
- } else
- #endif /* CURSES */
- puts(buf);
- return;
- }
-
- /*
- * For uucp mailers that use >From lines with "remote from <path>":
- * (where "path" is a hostname or pathnames)
- *
- * a. Set the return_path to the empty string.
- * b. For each From_ or >From_ line:
- * c. Save the username (second token).
- * d. Save the date (3-7 tokens).
- * e. If it has a "remote from" then append the remote host
- * (last token) followed by a "!" to the return_path.
- * f. If the saved username has a '@' but no '!' then convert it
- * to UUCP path form.
- * g. Append the saved username to return_path.
- */
- parse_from(fp, path)
- FILE *fp;
- char path[];
- {
- char user[256], buf[256]; /* max size for each line in a mail file */
- register char *p;
- long save_offset = ftell(fp);
-
- path[0] = '\0';
- while (fgets(buf, sizeof buf, fp)) {
- if (strncmp(buf, ">From ", 6))
- break;
- p = buf + 6;
-
- (void) sscanf(p, "%s", user);
-
- while (p = index(p+1, 'r')) {
- if (!strncmp(p, "remote from ", 12)) {
- char *p2 = path+strlen(path);
- skipspaces(12);
- sscanf(p, "%s", p2); /* add the new machine to current path */
- (void) strcat(p2, "!");
- break;
- }
- }
-
- if (p)
- (void) bang_form(path + strlen(path), user);
- save_offset = ftell(fp);
- }
- fseek(fp, save_offset, L_SET);
- }
-
- /*
- * Scan a file and select messages from it and append them to the current folder
- *
- * If "append" is 1, start where we left off (held in msg[cnt].m_offset)
- * and scan for messages. Append all messages found until EOF.
- *
- * If "append" is 2, we're merging in a new file, so start at the end of
- * the present folder and append all messages found until EOF.
- *
- * If "append" is 0, then the message separator must exist once and
- * only once. All extra occurrences of the separator is preceded by a '>'.
- * The list argument will be the message number to replace in the current
- * folder with the message read in from other filename.
- */
- load_folder(file, append, list)
- char *file, *list;
- int append;
- {
- char buf[BUFSIZ];
- int lines = 0, msg_found = 0, had_error = 1;
- int get_status = 1, cnt;
- long bytes, ftell();
- struct msg old;
- char wkday[4], month[4];
- int day, year, mins, hour;
- FILE *fp;
- #ifdef MMDF
- int begin_sep = 0; /* track beginning vs ending separators */
- #endif /* MMDF */
-
- if (!(fp = fopen(file, "r"))) {
- error("Unable to open %s", file);
- return -1;
- }
-
- if (append) {
- cnt = msg_cnt;
- (void) fseek(fp, append == 1 ? msg[cnt].m_offset : 0L, L_SET);
- } else {
- cnt = (int)list;
- old = msg[cnt];
- }
-
- if (isoff(glob_flags, READ_ONLY)) {
- if (tmpf)
- (void) fclose(tmpf);
- if (!(tmpf = mask_fopen(tempfile, "a"))) {
- error("Unable to open %s for appending", tempfile);
- (void) fclose(fp);
- return -1;
- }
- (void) fseek(tmpf, 0L, 2); /* assure we're at the end of the file */
- } else if (append == 2) {
- /* you can't merge in a folder to a read-only folder */
- (void) fclose(fp);
- return -1;
- }
-
- #ifdef MMDF
- if (!append) {
- strcpy(buf, MSG_SEPARATOR);
- goto do_headers;
- }
- #endif /* MMDF */
- while (fgets(buf, sizeof (buf), fp)) {
- #ifndef MSG_SEPARATOR
- if (!strncmp(buf, "From ", 5) &&
- /* From uucp Wed Jan 11 20:40:00 1989 */
- (sscanf(buf+5, "%*s %3s %3s %d %d:%d:%*d %d",
- wkday, month, &day, &hour, &mins, &year) == 6 ||
- /* From uucp Wed Jan 11 20:40:00 PST 1989 */
- sscanf(buf+5, "%*s %3s %3s %d %d:%d:%*d %*s %d",
- wkday, month, &day, &hour, &mins, &year) == 6 ||
- /* From uucp Wed Jan 11 20:40 PST 1989 */
- sscanf(buf+5, "%*s %3s %3s %d %d:%d %*s %d",
- wkday, month, &day, &hour, &mins, &year) == 6))
- #else /* MSG_SEPARATOR */
- if (!strncmp(buf, MSG_SEPARATOR, strlen(MSG_SEPARATOR)))
- #endif /* MSG_SEPARATOR */
- {
- #ifdef MMDF
- if (!append)
- fputc('>', tmpf);
- else if (begin_sep = !begin_sep)
- do_headers:
- #else /* MMDF */
- if (!append && msg_found)
- fputc('>', tmpf);
- else
- #endif /* MMDF */
- {
- msg_found++;
- had_error = 0;
- if (append && cnt == MAXMSGS-2) {
- wprint("WARNING: exceeded %d messages.\n", MAXMSGS);
- wprint("Not all messages have been loaded.\n");
- had_error++;
- break;
- }
- if (ison(glob_flags, READ_ONLY))
- bytes = ftell(fp) - strlen(buf);
- else {
- char path[256];
- parse_from(fp, path);
- if (path[0])
- (void) sprintf(buf, "From %s %s %s %d %d:%d:00 %d\n",
- path, wkday, month, day, hour, mins, year);
- bytes = ftell(tmpf);
- }
- /* finish up message structure from previous message.
- * if this is incorporating new mail, check "lines" to
- * see if previous message has already been set!
- */
- if (cnt && lines) {
- msg[cnt-1].m_size = bytes - msg[cnt-1].m_offset;
- msg[cnt-1].m_lines = lines;
- }
- if (isoff(glob_flags, READ_ONLY) && fputs(buf, tmpf) == -1) {
- error(tempfile);
- had_error++;
- break;
- }
- msg[cnt].m_offset = bytes;
- msg[cnt].m_flags = 0L;
- lines = 0;
- #ifndef MSG_SEPARATOR
- if (year > 1900)
- year -= 1900;
- (void) sprintf(buf, "%02d%02d%02d%02d%02d%.3s",
- year, month_to_n(month), day, hour, mins, wkday);
- strdup(msg[cnt].m_date_recv, buf);
- #endif /* MSG_SEPARATOR */
- turnon(msg[cnt].m_flags, UNREAD); /* initialize */
-
- /* we've read the "From " line(s), now read the rest of
- * the message headers till we get to a blank line.
- */
- while (fgets(buf, sizeof (buf), fp) && (*buf != '\n')) {
- register char *p = buf;
- if (!strncmp(buf, "Date:", 5))
- strdup(msg[cnt].m_date_sent, parse_date(p+5));
- if (get_status &&
- !(get_status = strncmp(p, "Status:", 7))) {
- /* new mail should not have a Status: field! */
- turnon(msg[cnt].m_flags, OLD);
- for (p += 8 ; *p != '\n'; p++)
- switch(*p) {
- case 'R': turnoff(msg[cnt].m_flags, UNREAD);
- when 'P': turnon(msg[cnt].m_flags, UNREAD);
- when 'S': turnon(msg[cnt].m_flags, SAVED);
- when 'r': turnon(msg[cnt].m_flags, REPLIED);
- when 'O': ; /* do nothing */
- otherwise :
- if (ison(glob_flags, WARNING))
- print("unknown msg status flag: %c",*p);
- }
- }
- if (isoff(glob_flags,READ_ONLY) && fputs(buf, tmpf) == -1) {
- error(tempfile);
- had_error++;
- break;
- }
- lines++;
- }
- if (!msg[cnt].m_date_sent || !*msg[cnt].m_date_sent)
- if (!msg[cnt].m_date_recv || !*msg[cnt].m_date_recv) {
- wprint("Message %d has *no* date!?\n", cnt+1);
- msg[cnt].m_date_sent = msg[cnt].m_date_recv =
- "0000000000XXX";
- } else
- strdup(msg[cnt].m_date_sent, msg[cnt].m_date_recv);
- else if (!msg[cnt].m_date_recv || !*msg[cnt].m_date_recv)
- strdup(msg[cnt].m_date_recv, msg[cnt].m_date_sent);
- if (had_error)
- break;
- if (append && list)
- set_msg_bit(list, cnt);
- if (append)
- cnt = ++msg_cnt;
- get_status = 1;
- }
- }
- if (msg_found) {
- lines++;
- if (isoff(glob_flags, READ_ONLY) && fputs(buf, tmpf) == -1) {
- error(tempfile);
- had_error++;
- break;
- }
- }
- }
- if (msg_found && append != 1)
- turnon(glob_flags, DO_UPDATE);
- #ifdef MMDF
- if (!append)
- fputs(END_MSG_SEP, tmpf);
- #endif /* MMDF */
- if (had_error) {
- if (!append)
- msg[cnt] = old;
- if (!msg_found && !append)
- print("File not left in correct message format.\n");
- } else {
- if (append)
- cnt--;
- if (isoff(glob_flags, READ_ONLY))
- msg[cnt].m_size = ftell(tmpf) - msg[cnt].m_offset;
- else
- msg[cnt].m_size = ftell(fp) - msg[cnt].m_offset;
- msg[cnt].m_lines = lines;
- /* remember where we were to seek to for when we append new mail */
- if (append)
- cnt++;
- }
- if (append)
- msg[cnt].m_offset = ftell(fp);
- fclose(fp);
- if (isoff(glob_flags, READ_ONLY)) {
- fclose(tmpf);
- if (!(tmpf = fopen(tempfile, "r"))) {
- error("Unable to open %s for reading", tempfile);
- return -1;
- }
- }
- return !had_error;
- }
-