|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T e
Length: 19751 (0x4d27) Types: TextFile Names: »elm.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec1/elm/src/elm.c«
/** elm.c **/ /* Main program of the ELM mail system! This file and all associated files and documentation: (C) Copyright 1986 Dave Taylor */ #include "elm.h" #ifdef BSD # undef toupper # undef tolower #endif long bytes(); char *format_long(); main(argc, argv) int argc; char *argv[]; { char ch, address[SLEN], to_whom[LONG_SLEN]; int redraw, /** do we need to rewrite the entire screen? **/ nuhead, /** or perhaps just the headers section... **/ nucurr, /** or just the current message pointer... **/ nufoot; /** clear lines 16 thru bottom and new menu **/ int i; /** Random counting variable (etc) **/ int pageon, /** for when we receive new mail... **/ last_in_mailbox; /** for when we receive new mail too... **/ parse_arguments(argc, argv, to_whom); if (mail_only) { initialize(FALSE); Raw(ON); dprint1(3,"Mail-only: mailing to\n-> \"%s\"\n", format_long(to_whom, 3)); (void) send(to_whom, "", TRUE, NO); leave(0); } initialize(TRUE); ScreenSize(&LINES, &COLUMNS); showscreen(); mailfile_size = bytes(infile); Raw(ON); while (1) { redraw = 0; nuhead = 0; nufoot = 0; nucurr = 0; if ((i = bytes(infile)) != mailfile_size) { dprint1(2,"Just received %d bytes more mail (elm)\n", i - mailfile_size); error("New mail has arrived! Hang on..."); last_in_mailbox = message_count; pageon = header_page; newmbox(2, FALSE, TRUE); /* last won't be touched! */ clear_error(); header_page = pageon; if (on_page(current)) /* do we REALLY have to rewrite? */ showscreen(); else { update_title(); ClearLine(LINES-1); /* remove reading message... */ error2("%d new message%s received", message_count - last_in_mailbox, plural(message_count - last_in_mailbox)); } mailfile_size = i; if (cursor_control) transmit_functions(ON); /* insurance */ } prompt("Command: "); CleartoEOLN(); ch = tolower(GetPrompt()); CleartoEOS(); dprint1(4, "\nCommand: %c\n\n", ch); set_error(""); /* clear error buffer */ MoveCursor(LINES-3,strlen("Command: ")); switch (ch) { case '?' : if (help()) redraw++; else nufoot++; break; case '$' : resync(); break; case ' ' : case '+' : header_page++; nuhead++; if (move_when_paged && header_page <= (message_count / headers_per_page)) { current = header_page*headers_per_page + 1; if (selected) current = visible_to_index(current)+1; } break; case '-' : header_page--; nuhead++; if (move_when_paged && header_page >= 0) { current = header_page*headers_per_page + 1; if (selected) current = visible_to_index(current)+1; } break; case '=' : if (selected) current = visible_to_index(1)+1; else current = 1; if (get_page(current)) nuhead++; else nucurr++; break; case '*' : if (selected) current = (visible_to_index(selected)+1); else current = message_count; if (get_page(current)) nuhead++; else nucurr++; break; case '|' : Writechar('|'); softkeys_off(); redraw = do_pipe(); softkeys_on(); break; case '!' : Writechar('!'); softkeys_off(); redraw = subshell(); softkeys_on(); break; case '%' : get_return(address); clear_error(); PutLine1(LINES,(COLUMNS-strlen(address))/2, "%.78s", address); break; case '/' : if (pattern_match()) { if (get_page(current)) nuhead++; else nucurr++; } else error("pattern not found!"); break; case '<' : /* scan current message for calendar information */ #ifdef ENABLE_CALENDAR PutLine0(LINES-3, strlen("Command: "), "Scan message for calendar entries..."); scan_calendar(); #else error("Sorry - calendar function disabled"); #endif break; case 'a' : alias(); nufoot++; define_softkeys(MAIN); break; case 'b' : PutLine0(LINES-3, strlen("Command: "), "Bounce message"); fflush(stdout); if (message_count < 1) error("No mail to bounce!"); else nufoot = remail(); break; case 'c' : PutLine0(LINES-3, strlen("Command: "), "Change mailbox"); define_softkeys(CHANGE); if ((file_changed = leave_mbox(FALSE)) != -1) { redraw = newmbox(0, TRUE, TRUE); dprint1(1, "** redraw returned as %d **\n", redraw); mailfile_size = bytes(infile); } else { file_changed = 0; sort_mailbox(message_count, FALSE); } define_softkeys(MAIN); break; case '^' : case 'd' : if (message_count < 1) error("No mail to delete!"); else { delete_msg((ch == 'd')); if (resolve_mode) /* move after mail resolved */ if (current < message_count) { current++; if (get_page(current)) nuhead++; else nucurr++; } } break; case ctrl('D') : if (message_count < 1) error("No mail to delete!"); else meta_match(DELETED); break; case 'e' : PutLine0(LINES-3,strlen("Command: "),"Edit mailbox"); if (current > 0) { edit_mailbox(); if (cursor_control) transmit_functions(ON); /* insurance */ } else error("Mailbox is empty!"); break; case 'f' : PutLine0(LINES-3, strlen("Command: "), "Forward"); define_softkeys(YESNO); if (current > 0) redraw = forward(); else error("No mail to forward!"); define_softkeys(MAIN); break; case 'g' : PutLine0(LINES-3,strlen("Command: "), "Group reply"); fflush(stdout); if (current > 0) { if (header_table[current-1].status & FORM_LETTER) error("Can't group reply to a Form!!"); else { PutLine0(LINES-3,COLUMNS-40, "building addresses..."); define_softkeys(YESNO); redraw = reply_to_everyone(); define_softkeys(MAIN); } } else error("No mail to reply to!"); break; case 'h' : if (filter) PutLine0(LINES-3, strlen("Command: "), "Message with headers..."); else PutLine0(LINES-3, strlen("Command: "),"Read message"); fflush(stdout); i = filter; filter = FALSE; redraw = show_msg(current); filter = i; break; case 'j' : if (selected) { if ((current = next_visible(current)) < 0) current = visible_to_index(selected)+1; } else current++; if (get_page(current)) nuhead++; else nucurr++; break; case 'k' : if (selected) current = previous_visible(current); else current--; if (get_page(current)) nuhead++; else nucurr++; break; case 'l' : PutLine0(LINES-3, strlen("Command: "), "Limit displayed messages by..."); if (limit() != 0) { nuhead++; update_title(); /* poof! */ } else nufoot++; break; case 'm' : PutLine0(LINES-3, strlen("Command: "), "Mail"); redraw = send("", "", TRUE, allow_forms); break; case ctrl('J'): case ctrl('M'):PutLine0(LINES-3, strlen("Command: "), "Read Message"); fflush(stdout); define_softkeys(READ); redraw = show_msg(current); break; case 'n' : PutLine0(LINES-3, strlen("Command: "), "Next Message"); fflush(stdout); define_softkeys(READ); redraw = show_msg(current); current += redraw; if (current > message_count) current = message_count; (void) get_page(current); /* rewrites ANYway */ break; case 'o' : PutLine0(LINES-3, strlen("Command: "), "Options"); options(); redraw++; /* always fix da screen... */ break; case 'p' : PutLine0(LINES-3, strlen("Command: "), "Print mail"); fflush(stdout); if (message_count < 1) error("No mail to print!"); else printmsg(); break; case 'q' : PutLine0(LINES-3, strlen("Command: "), "Quit"); if (mbox_specified == 0) lock(OUTGOING); if (mailfile_size != bytes(infile)) { error("New Mail! Quit cancelled..."); if (mbox_specified == 0) unlock(); } else quit(); break; case 'r' : PutLine0(LINES-3, strlen("Command: "), "Reply to message"); if (current > 0) redraw = reply(); else error("No mail to reply to!"); softkeys_on(); break; case '>' : /** backwards compatibility **/ case 's' : if (message_count < 1) error("No mail to save!"); else { PutLine0(LINES-3, strlen("Command: "), "Save Message"); PutLine0(LINES-3,COLUMNS-40, "(Use '?' to list your folders)"); if (save(&redraw) && resolve_mode) { if (current < message_count) { current++; /* move to next message */ if (get_page(current)) nuhead++; else nucurr++; } } } ClearLine(LINES-2); break; case ctrl('T') : case 't' : if (message_count < 1) error("no mail to tag!"); else if (ch == 't') tag_message(); else meta_match(TAGGED); break; case 'u' : if (message_count < 1) error("no mail to mark as undeleted!"); else { undelete_msg(); if (resolve_mode) /* move after mail resolved */ if (current < message_count) { current++; if (get_page(current)) nuhead++; else nucurr++; } } break; case ctrl('U') : if (message_count < 1) error("No mail to undelete!"); else meta_match(UNDELETE); break; case ctrl('Q') : case ctrl('?') : case 'x' : PutLine0(LINES-3, strlen("Command: "), "Exit"); fflush(stdout); leave(); case ctrl('L') : redraw++; break; case '@' : debug_screen(); redraw++; break; case '#' : debug_message(); redraw++; break; case NO_OP_COMMAND : break; /* noop for timeout loop */ case ESCAPE : if (cursor_control) { ch = ReadCh(); if (ch == up[1]) { if (selected) current = previous_visible(current); else current--; if (get_page(current)) nuhead++; else nucurr++; } else if (ch == down[1]) { if (selected) { if ((current = next_visible(current)) < 0) current = visible_to_index(selected)+1; } else current++; if (get_page(current)) nuhead++; else nucurr++; } else if (hp_terminal) { switch (ch) { case 'U' : /* <NEXT> */ header_page++; nuhead++; if (move_when_paged && header_page <= (message_count / headers_per_page)) { current = header_page*headers_per_page + 1; if (selected) current = visible_to_index(current)+1; } break; case 'V' : /* <PREV> */ header_page--; nuhead++; if (move_when_paged && header_page >= 0) { current = header_page*headers_per_page + 1; if (selected) current = visible_to_index(current)+1; } break; case 'h' : case 'H' : /* <HOME UP> */ if (selected) current = visible_to_index(1)+1; else current = 1; if (get_page(current)) nuhead++; else nucurr++; break; case 'F' : /* <HOME DOWN> */ if (selected) current = visible_to_index(selected)+1; else current = message_count; if (get_page(current)) nuhead++; else nucurr++; break; /** let's continue, what the heck... **/ case 'A' : /* <UP> */ case 'D' : /* <BACKTAB> */ case 'i' : /* <LEFT> */ if (selected) current = previous_visible(current); else current--; if (get_page(current)) nuhead++; else nucurr++; break; case 'B' : /* <UP> */ case 'I' : /* <BACKTAB> */ case 'C' : /* <LEFT> */ if (selected) { if ((current = next_visible(current)) < 0) current = visible_to_index(selected)+1; } else current++; if (get_page(current)) nuhead++; else nucurr++; break; default: PutLine2(LINES-3, strlen("Command: "), "%c%c", ESCAPE, ch); } } else /* false hit - output */ PutLine2(LINES-3, strlen("Command: "), "%c%c", ESCAPE, ch); break; } /* else fall into the default error message! */ default : if (ch > '0' && ch <= '9') { PutLine0(LINES-3, strlen("Command: "), "New Current Message"); current = read_number(ch); if (selected) { if ((current = visible_to_index(current)+1) > message_count) goto too_big; } if (get_page(current)) nuhead++; else nucurr++; } else error("Unknown command: Use '?' for commands"); } dprint5(4,"redraw=%s, current=%d, nuhead=%s, nufoot=%s, nucurr=%s\n", onoff(redraw), current, onoff(nuhead), onoff(nufoot), onoff(nucurr)); if (redraw) showscreen(); if (current < 1) { if (message_count > 0) { error("already at message #1!"); if (selected) current = compute_visible(0); /* get to #0 */ else current = 1; } else if (current < 0) { error("No messages to read!"); current = 0; } } else if (current > message_count) { if (message_count > 0) { too_big: if (selected) { error2("only %d message%s selected!", selected, plural(selected)); current = compute_visible(selected); } else { error2("only %d message%s!", message_count, plural(message_count)); current = message_count; } } else { error("No messages to read!"); current = 0; } } else if (selected && (i=visible_to_index(selected)) > message_count) { error2("only %d message%s selected!", selected, plural(selected)); current = i+1; /* FIXED! Phew! */ } if (nuhead) show_headers(); else if (nucurr) show_current(); else if (nufoot) { if (mini_menu) { MoveCursor(LINES-7, 0); CleartoEOS(); show_menu(); } else { MoveCursor(LINES-4, 0); CleartoEOS(); } } } /* the BIG while loop! */ } debug_screen() { /**** spit out all the current variable settings and the table entries for the current 'n' items displayed. ****/ register int i, j; char buffer[SLEN]; ClearScreen(); Raw(OFF); PutLine2(0,0,"Current message number = %d\t\t%d message(s) total\n", current, message_count); PutLine2(2,0,"Header_page = %d \t\t%d possible page(s)\n", header_page, (int) (message_count / headers_per_page) + 1); PutLine1(4,0,"\nCurrent mailfile is %s.\n\n", infile); i = header_page*headers_per_page; /* starting header */ if ((j = i + (headers_per_page-1)) >= message_count) j = message_count-1; Write_to_screen( "Num From Subject Lines Offset\n\n",0); while (i <= j) { sprintf(buffer, "%3d %-16.16s %-40.40s %4d %d\n", i+1, header_table[i].from, header_table[i].subject, header_table[i].lines, header_table[i].offset); Write_to_screen(buffer, 0); i++; } Raw(ON); PutLine0(LINES,0,"Press any key to return: "); (void) ReadCh(); } debug_message() { /**** Spit out the current message record. Include EVERYTHING in the record structure. **/ char buffer[SLEN]; ClearScreen(); Raw(OFF); Write_to_screen("\t\t\t----- Message %d -----\n\n\n\n", 1, current); Write_to_screen("Lines : %-5d\t\t\t\tStatus: N E A P D T V\n", 1, header_table[current-1].lines); Write_to_screen(" \t\t\t\t e x c r e a i\n", 0); Write_to_screen(" \t\t\t\t w p t i l g s\n", 0); sprintf(buffer, "\nOffset: %ld\t\t\t\t %d %d %d %d %d %d %d\n", header_table[current-1].offset, (header_table[current-1].status & NEW) != 0, (header_table[current-1].status & EXPIRED) != 0, (header_table[current-1].status & ACTION) != 0, (header_table[current-1].status & PRIORITY) != 0, (header_table[current-1].status & DELETED) != 0, (header_table[current-1].status & TAGGED) != 0, (header_table[current-1].status & VISIBLE) != 0); Write_to_screen(buffer, 0); sprintf(buffer, "\nReceived on: %d/%d/%d at %d:%02d\n\n", header_table[current-1].received.month+1, header_table[current-1].received.day, header_table[current-1].received.year, header_table[current-1].received.hour, header_table[current-1].received.minute); Write_to_screen(buffer, 0); sprintf(buffer, "Message sent on: %s, %s %s, %s at %s\n\n", header_table[current-1].dayname, header_table[current-1].month, header_table[current-1].day, header_table[current-1].year, header_table[current-1].time); Write_to_screen(buffer, 0); Write_to_screen("\nFrom: %s\n\nSubject: %s", 2, header_table[current-1].from, header_table[current-1].subject); Write_to_screen("\nTo: %s\n\nIndex = %d\n", 2, header_table[current-1].to, header_table[current-1].index_number); Raw(ON); PutLine0(LINES,0,"Press any key to return: "); (void) ReadCh(); }