home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume9 / elm2 / part17 < prev    next >
Text File  |  1987-03-10  |  42KB  |  1,457 lines

  1. Subject:  v09i017:  ELM Mail System, Part17/19
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: Dave Taylor <hplabs!taylor>
  6. Mod.sources: Volume 9, Issue 17
  7. Archive-name: elm2/Part17
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If this archive is complete, you will see the message:
  13. #        "End of archive 17 (of 19)."
  14. # Contents:  src/elm.c src/mailmsg2.c
  15. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  16. echo shar: Extracting \"src/elm.c\" \(19751 characters\)
  17. if test -f src/elm.c ; then 
  18.   echo shar: Will not over-write existing file \"src/elm.c\"
  19. else
  20. sed "s/^X//" >src/elm.c <<'END_OF_src/elm.c'
  21. X/**            elm.c            **/
  22. X
  23. X/* Main program of the ELM mail system! 
  24. X
  25. X   This file and all associated files and documentation:
  26. X    (C) Copyright 1986 Dave Taylor
  27. X*/
  28. X
  29. X#include "elm.h"
  30. X
  31. X#ifdef BSD
  32. X# undef toupper
  33. X# undef tolower
  34. X#endif
  35. X
  36. Xlong bytes();
  37. Xchar *format_long();
  38. X
  39. Xmain(argc, argv)
  40. Xint argc;
  41. Xchar *argv[];
  42. X{
  43. X    char ch, address[SLEN], to_whom[LONG_SLEN];
  44. X    int  redraw,         /** do we need to rewrite the entire screen? **/
  45. X         nuhead,         /** or perhaps just the headers section...   **/
  46. X         nucurr,         /** or just the current message pointer...   **/
  47. X         nufoot;         /** clear lines 16 thru bottom and new menu  **/
  48. X    int  i;              /** Random counting variable (etc)           **/
  49. X    int  pageon,         /** for when we receive new mail...          **/
  50. X         last_in_mailbox;    /** for when we receive new mail too...      **/
  51. X
  52. X    parse_arguments(argc, argv, to_whom);
  53. X
  54. X    if (mail_only) {
  55. X
  56. X       initialize(FALSE);
  57. X
  58. X       Raw(ON);
  59. X       dprint1(3,"Mail-only: mailing to\n-> \"%s\"\n", 
  60. X           format_long(to_whom, 3));
  61. X       (void) send(to_whom, "", TRUE, NO); 
  62. X       leave(0);
  63. X    }
  64. X
  65. X    initialize(TRUE);
  66. X
  67. X    ScreenSize(&LINES, &COLUMNS);
  68. X
  69. X    showscreen();
  70. X
  71. X    mailfile_size = bytes(infile);
  72. X
  73. X    Raw(ON);
  74. X
  75. X    while (1) {
  76. X      redraw = 0;
  77. X      nuhead = 0;
  78. X      nufoot = 0;
  79. X      nucurr = 0;
  80. X      if ((i = bytes(infile)) != mailfile_size) {
  81. X        dprint1(2,"Just received %d bytes more mail (elm)\n", 
  82. X            i - mailfile_size);
  83. X        error("New mail has arrived!   Hang on...");
  84. X        last_in_mailbox = message_count;
  85. X        pageon = header_page;
  86. X        newmbox(2, FALSE, TRUE);    /* last won't be touched! */
  87. X        clear_error();
  88. X        header_page = pageon;
  89. X
  90. X        if (on_page(current))   /* do we REALLY have to rewrite? */
  91. X          showscreen();
  92. X        else {
  93. X          update_title();
  94. X          ClearLine(LINES-1);         /* remove reading message... */
  95. X          error2("%d new message%s received", 
  96. X             message_count - last_in_mailbox,
  97. X             plural(message_count - last_in_mailbox));
  98. X        }
  99. X        mailfile_size = i;
  100. X        if (cursor_control)
  101. X          transmit_functions(ON);    /* insurance */
  102. X      }
  103. X
  104. X      prompt("Command: ");
  105. X
  106. X      CleartoEOLN();
  107. X      ch = tolower(GetPrompt()); 
  108. X      CleartoEOS();
  109. X      dprint1(4, "\nCommand: %c\n\n", ch);
  110. X
  111. X      set_error("");    /* clear error buffer */
  112. X
  113. X      MoveCursor(LINES-3,strlen("Command: "));
  114. X
  115. X      switch (ch) {
  116. X
  117. X        case '?'     :  if (help())
  118. X                   redraw++;
  119. X               else
  120. X                 nufoot++;
  121. X               break;
  122. X
  123. X        case '$'    : resync();                     break;
  124. X
  125. X        case ' '    : 
  126. X        case '+'    :  header_page++; nuhead++;    
  127. X               if (move_when_paged && header_page <=
  128. X                  (message_count / headers_per_page)) {
  129. X                 current = header_page*headers_per_page + 1;
  130. X                 if (selected)
  131. X                   current = visible_to_index(current)+1;
  132. X                       }
  133. X               break;
  134. X
  135. X        case '-'    :  header_page--; nuhead++;    
  136. X               if (move_when_paged && header_page >= 0) {
  137. X                 current = header_page*headers_per_page + 1;
  138. X                 if (selected)
  139. X                   current = visible_to_index(current)+1;
  140. X               }
  141. X               break;
  142. X
  143. X        case '='    :  if (selected)
  144. X                 current = visible_to_index(1)+1;
  145. X                       else
  146. X                 current = 1;
  147. X                       if (get_page(current))
  148. X                 nuhead++;    
  149. X               else
  150. X                 nucurr++;             break;
  151. X
  152. X        case '*'    :  if (selected) 
  153. X                 current = (visible_to_index(selected)+1);
  154. X               else
  155. X                 current = message_count;    
  156. X                       if (get_page(current))
  157. X                 nuhead++;    
  158. X               else
  159. X                 nucurr++;             break;
  160. X
  161. X        case '|'    :  Writechar('|'); 
  162. X                   softkeys_off();
  163. X                           redraw = do_pipe();        
  164. X                       softkeys_on();         break;
  165. X
  166. X        case '!'    :  Writechar('!'); 
  167. X                   softkeys_off();
  168. X                           redraw = subshell();        
  169. X                       softkeys_on();         break;
  170. X
  171. X        case '%'    :  get_return(address);
  172. X               clear_error();
  173. X               PutLine1(LINES,(COLUMNS-strlen(address))/2,
  174. X                        "%.78s", address);    
  175. X                   break;
  176. X
  177. X        case '/'    :  if (pattern_match()) {
  178. X                         if (get_page(current))
  179. X                   nuhead++;
  180. X                         else
  181. X                           nucurr++;
  182. X                       }
  183. X               else 
  184. X                  error("pattern not found!");
  185. X               break;
  186. X
  187. X        case '<'    :  /* scan current message for calendar information */
  188. X#ifdef ENABLE_CALENDAR
  189. X               PutLine0(LINES-3, strlen("Command: "),     
  190. X                   "Scan message for calendar entries...");
  191. X               scan_calendar();
  192. X#else
  193. X                error("Sorry - calendar function disabled");
  194. X#endif
  195. X               break;
  196. X
  197. X        case 'a'    :  alias();     
  198. X               nufoot++;     
  199. X               define_softkeys(MAIN);     break;
  200. X            
  201. X        case 'b'    :  PutLine0(LINES-3, strlen("Command: "), 
  202. X                     "Bounce message");
  203. X               fflush(stdout);
  204. X               if (message_count < 1)
  205. X                   error("No mail to bounce!");
  206. X               else 
  207. X                 nufoot = remail();
  208. X               break;
  209. X
  210. X        case 'c'    :  PutLine0(LINES-3, strlen("Command: "), 
  211. X                  "Change mailbox");
  212. X               define_softkeys(CHANGE);
  213. X               if ((file_changed = leave_mbox(FALSE)) != -1) {
  214. X                         redraw = newmbox(0, TRUE, TRUE);
  215. X                     dprint1(1, "** redraw returned as %d **\n",
  216. X                     redraw);
  217. X                 mailfile_size = bytes(infile);    
  218. X                         }
  219. X               else {
  220. X                 file_changed = 0;
  221. X                 sort_mailbox(message_count, FALSE);
  222. X               }
  223. X               define_softkeys(MAIN);
  224. X               break;
  225. X
  226. X        case '^'    :
  227. X        case 'd'    :  if (message_count < 1)
  228. X                 error("No mail to delete!");
  229. X               else {
  230. X                          delete_msg((ch == 'd'));            
  231. X                 if (resolve_mode)     /* move after mail resolved */
  232. X                   if (current < message_count) {
  233. X                             current++;          
  234. X                     if (get_page(current))
  235. X                       nuhead++;
  236. X                     else
  237. X                       nucurr++;
  238. X                   }
  239. X                       }
  240. X               break;
  241. X
  242. X        case ctrl('D') : if (message_count < 1)
  243. X                   error("No mail to delete!");
  244. X                 else 
  245. X                   meta_match(DELETED);
  246. X                 break;
  247. X
  248. X        case 'e'    :  PutLine0(LINES-3,strlen("Command: "),"Edit mailbox");
  249. X               if (current > 0) {
  250. X                 edit_mailbox();
  251. X                     if (cursor_control)
  252. X                           transmit_functions(ON);    /* insurance */
  253. X                  }
  254. X               else
  255. X                 error("Mailbox is empty!");
  256. X               break;
  257. X        
  258. X        case 'f'    :  PutLine0(LINES-3, strlen("Command: "), "Forward");
  259. X               define_softkeys(YESNO);
  260. X               if (current > 0)  
  261. X                         redraw = forward();   
  262. X               else 
  263. X                         error("No mail to forward!");
  264. X               define_softkeys(MAIN);
  265. X               break;
  266. X
  267. X        case 'g'    :  PutLine0(LINES-3,strlen("Command: "), "Group reply");
  268. X                   fflush(stdout);
  269. X               if (current > 0) {
  270. X                 if (header_table[current-1].status & FORM_LETTER)
  271. X                   error("Can't group reply to a Form!!");
  272. X                 else {
  273. X                   PutLine0(LINES-3,COLUMNS-40,
  274. X                                       "building addresses...");
  275. X                   define_softkeys(YESNO);
  276. X                           redraw = reply_to_everyone();    
  277. X                   define_softkeys(MAIN);
  278. X                         }
  279. X                       }
  280. X               else 
  281. X                 error("No mail to reply to!"); 
  282. X               break;
  283. X
  284. X        case 'h'    :  if (filter)
  285. X                         PutLine0(LINES-3, strlen("Command: "), 
  286. X                "Message with headers...");
  287. X                       else
  288. X                 PutLine0(LINES-3, strlen("Command: "),"Read message");
  289. X               fflush(stdout);
  290. X               i = filter;
  291. X               filter = FALSE;
  292. X               redraw = show_msg(current);
  293. X               filter = i;
  294. X               break;
  295. X
  296. X        case 'j'    :  if (selected) {
  297. X                 if ((current = next_visible(current)) < 0)
  298. X                           current = visible_to_index(selected)+1;
  299. X               }
  300. X               else 
  301. X                         current++;  
  302. X               if (get_page(current))
  303. X                 nuhead++;
  304. X               else
  305. X                 nucurr++;            break;
  306. X
  307. X        case 'k'    :  if (selected) 
  308. X                 current = previous_visible(current);
  309. X                    else
  310. X                         current--;  
  311. X               if (get_page(current))
  312. X                 nuhead++;
  313. X               else
  314. X                 nucurr++;            break;
  315. X
  316. X        case 'l'    :  PutLine0(LINES-3, strlen("Command: "),
  317. X                       "Limit displayed messages by...");
  318. X               if (limit() != 0) {
  319. X                         nuhead++;
  320. X                    update_title();    /* poof! */
  321. X               }
  322. X               else
  323. X                     nufoot++;
  324. X               break;
  325. X
  326. X        case 'm'    :  PutLine0(LINES-3, strlen("Command: "), "Mail");
  327. X               redraw = send("", "", TRUE, allow_forms); 
  328. X               break;
  329. X
  330. X        case ctrl('J'):
  331. X        case ctrl('M'):PutLine0(LINES-3, strlen("Command: "), "Read Message");    
  332. X               fflush(stdout);
  333. X               define_softkeys(READ);
  334. X               redraw = show_msg(current);
  335. X               break;
  336. X
  337. X        case 'n'    :  PutLine0(LINES-3, strlen("Command: "), "Next Message");
  338. X               fflush(stdout);
  339. X               define_softkeys(READ);
  340. X               redraw = show_msg(current);
  341. X               current += redraw;        
  342. X               if (current > message_count)
  343. X                 current = message_count;
  344. X               (void) get_page(current); /* rewrites ANYway */
  345. X               break;
  346. X
  347. X        case 'o'    :  PutLine0(LINES-3, strlen("Command: "), "Options");
  348. X               options();
  349. X               redraw++;    /* always fix da screen... */
  350. X               break;
  351. X
  352. X        case 'p'    :  PutLine0(LINES-3, strlen("Command: "), "Print mail");
  353. X               fflush(stdout);
  354. X               if (message_count < 1)
  355. X                 error("No mail to print!");
  356. X               else
  357. X                 printmsg();            
  358. X               break;
  359. X
  360. X        case 'q'    :  PutLine0(LINES-3, strlen("Command: "), "Quit");
  361. X
  362. X               if (mbox_specified == 0) lock(OUTGOING);
  363. X
  364. X               if (mailfile_size != bytes(infile)) {
  365. X                 error("New Mail!  Quit cancelled...");
  366. X                   if (mbox_specified == 0) unlock();
  367. X                       }
  368. X                   else
  369. X                 quit();        
  370. X
  371. X               break;
  372. X
  373. X        case 'r'    :  PutLine0(LINES-3, strlen("Command: "), 
  374. X                  "Reply to message");
  375. X               if (current > 0) 
  376. X                         redraw = reply();    
  377. X               else 
  378. X                 error("No mail to reply to!"); 
  379. X               softkeys_on();
  380. X               break;
  381. X
  382. X        case '>'    : /** backwards compatibility **/
  383. X
  384. X        case 's'    :  if  (message_count < 1)
  385. X                 error("No mail to save!");
  386. X               else {
  387. X                         PutLine0(LINES-3, strlen("Command: "),
  388. X                      "Save Message");
  389. X                 PutLine0(LINES-3,COLUMNS-40,
  390. X                "(Use '?' to list your folders)");
  391. X                 if (save(&redraw) && resolve_mode) {
  392. X                   if (current < message_count) {
  393. X                     current++;    /* move to next message */
  394. X                     if (get_page(current))
  395. X                       nuhead++;
  396. X                     else
  397. X                       nucurr++;        
  398. X                   }
  399. X                 }
  400. X               }
  401. X               ClearLine(LINES-2);        
  402. X               break;
  403. X
  404. X            case ctrl('T') :
  405. X        case 't'       :  if (message_count < 1)
  406. X                    error("no mail to tag!");
  407. X                  else if (ch == 't')
  408. X                    tag_message(); 
  409. X                  else
  410. X                    meta_match(TAGGED);
  411. X                          break;
  412. X
  413. X        case 'u'    :  if (message_count < 1)
  414. X                 error("no mail to mark as undeleted!");
  415. X               else {
  416. X                         undelete_msg();                
  417. X                 if (resolve_mode)     /* move after mail resolved */
  418. X                   if (current < message_count) {
  419. X                             current++;          
  420. X                     if (get_page(current))
  421. X                       nuhead++;
  422. X                     else
  423. X                       nucurr++;
  424. X                   }
  425. X               }
  426. X               break;
  427. X
  428. X        case ctrl('U') : if (message_count < 1)
  429. X                   error("No mail to undelete!");
  430. X                 else 
  431. X                   meta_match(UNDELETE);
  432. X                 break;
  433. X
  434. X        case ctrl('Q') :
  435. X        case ctrl('?') : 
  436. X        case 'x'    :  PutLine0(LINES-3, strlen("Command: "), "Exit");  
  437. X                           fflush(stdout);              leave();
  438. X
  439. X        case ctrl('L') : redraw++;    break;
  440. X        
  441. X        case '@'    : debug_screen();  redraw++;    break;
  442. X    
  443. X        case '#'    : debug_message(); redraw++;    break;
  444. X
  445. X        case NO_OP_COMMAND : break;    /* noop for timeout loop */
  446. X
  447. X        case ESCAPE : if (cursor_control) {
  448. X                ch = ReadCh(); 
  449. X                        if (ch == up[1]) {
  450. X                  if (selected)
  451. X                    current = previous_visible(current);
  452. X                  else 
  453. X                    current--;
  454. X                  if (get_page(current))
  455. X                    nuhead++;
  456. X                  else
  457. X                    nucurr++;            
  458. X                        }
  459. X                else if (ch == down[1]) {
  460. X                  if (selected) {
  461. X                    if ((current = next_visible(current)) < 0)
  462. X                              current = visible_to_index(selected)+1;
  463. X                  }
  464. X                  else 
  465. X                    current++;
  466. X                  if (get_page(current))
  467. X                    nuhead++;
  468. X                  else
  469. X                    nucurr++;            
  470. X                }
  471. X                else if (hp_terminal) { 
  472. X
  473. X                 switch (ch) {
  474. X                  case 'U' :    /* <NEXT> */
  475. X                     header_page++; 
  476. X                 nuhead++;
  477. X                     if (move_when_paged && header_page 
  478. X                         <= (message_count / headers_per_page)) {
  479. X                       current = header_page*headers_per_page + 1;
  480. X                       if (selected)
  481. X                         current = visible_to_index(current)+1;
  482. X                     }
  483. X                 break;
  484. X
  485. X                  case 'V' :       /* <PREV> */
  486. X                    header_page--; 
  487. X                nuhead++;
  488. X                    if (move_when_paged && header_page >= 0) {
  489. X                       current = header_page*headers_per_page + 1;
  490. X                       if (selected)
  491. X                         current = visible_to_index(current)+1;
  492. X                     }
  493. X                break;
  494. X
  495. X                  case 'h' :     
  496. X                  case 'H' :     /* <HOME UP> */
  497. X                        if (selected)
  498. X                      current = visible_to_index(1)+1;
  499. X                            else
  500. X                      current = 1;
  501. X                            if (get_page(current))
  502. X                      nuhead++;
  503. X                            else
  504. X                              nucurr++;
  505. X                break;
  506. X
  507. X                  case 'F' :     /* <HOME DOWN> */
  508. X                        if (selected)
  509. X                      current = visible_to_index(selected)+1;
  510. X                            else
  511. X                      current = message_count;
  512. X                            if (get_page(current))
  513. X                      nuhead++;
  514. X                            else
  515. X                              nucurr++;
  516. X                    break;
  517. X
  518. X                  /** let's continue, what the heck... **/
  519. X
  520. X                  case 'A' :     /* <UP> */
  521. X                  case 'D' :     /* <BACKTAB> */
  522. X                  case 'i' :     /* <LEFT> */
  523. X                     if (selected)
  524. X                       current = previous_visible(current);
  525. X                     else 
  526. X                       current--;
  527. X                     if (get_page(current))
  528. X                       nuhead++;
  529. X                     else
  530. X                       nucurr++;            
  531. X                 break;
  532. X
  533. X                  case 'B' :     /* <UP> */
  534. X                  case 'I' :     /* <BACKTAB> */
  535. X                  case 'C' :     /* <LEFT> */
  536. X                     if (selected) {
  537. X                       if ((current = next_visible(current)) < 0)
  538. X                                 current = visible_to_index(selected)+1;
  539. X                     }
  540. X                     else 
  541. X                       current++;
  542. X                     if (get_page(current))
  543. X                       nuhead++;
  544. X                     else
  545. X                       nucurr++;            
  546. X                     break;
  547. X
  548. X                  default: PutLine2(LINES-3, strlen("Command: "), 
  549. X                          "%c%c", ESCAPE, ch);
  550. X                 }
  551. X                }
  552. X                else /* false hit - output */
  553. X                  PutLine2(LINES-3, strlen("Command: "), 
  554. X                          "%c%c", ESCAPE, ch);
  555. X                break;
  556. X              }
  557. X
  558. X              /* else fall into the default error message! */
  559. X
  560. X        default    : if (ch > '0' && ch <= '9') {
  561. X                PutLine0(LINES-3, strlen("Command: "), 
  562. X                    "New Current Message");
  563. X                current = read_number(ch);
  564. X                if (selected) {
  565. X                  if ((current = visible_to_index(current)+1) >
  566. X                  message_count)
  567. X                    goto too_big;
  568. X                        }
  569. X                        if (get_page(current))
  570. X                  nuhead++;
  571. X                        else
  572. X                          nucurr++;
  573. X              }
  574. X              else
  575. X                 error("Unknown command: Use '?' for commands");
  576. X      }
  577. X
  578. X      dprint5(4,"redraw=%s, current=%d, nuhead=%s, nufoot=%s, nucurr=%s\n",
  579. X          onoff(redraw), current, onoff(nuhead), onoff(nufoot),
  580. X          onoff(nucurr));
  581. X
  582. X      if (redraw)
  583. X        showscreen();
  584. X
  585. X      if (current < 1) {
  586. X        if (message_count > 0) {
  587. X          error("already at message #1!");
  588. X          if (selected)
  589. X            current = compute_visible(0);    /* get to #0 */
  590. X          else
  591. X            current = 1;
  592. X        }
  593. X        else if (current < 0) {
  594. X          error("No messages to read!");
  595. X          current = 0;
  596. X        }
  597. X      }
  598. X      else if (current > message_count) {
  599. X        if (message_count > 0) {
  600. Xtoo_big:
  601. X          if (selected) {
  602. X            error2("only %d message%s selected!", selected, 
  603. X            plural(selected));
  604. X            current = compute_visible(selected);
  605. X          }
  606. X          else {
  607. X            error2("only %d message%s!", message_count, 
  608. X               plural(message_count));
  609. X            current = message_count;
  610. X          }
  611. X        }
  612. X        else {
  613. X          error("No messages to read!");
  614. X          current = 0;
  615. X        }
  616. X      }
  617. X      else if (selected && (i=visible_to_index(selected)) > message_count) {
  618. X        error2("only %d message%s selected!", selected, plural(selected));
  619. X        current = i+1;    /* FIXED!  Phew! */
  620. X      }
  621. X        
  622. X      if (nuhead) 
  623. X        show_headers();
  624. X      else if (nucurr)
  625. X        show_current();
  626. X      else if (nufoot) {
  627. X        if (mini_menu) {
  628. X          MoveCursor(LINES-7, 0);  
  629. X              CleartoEOS();
  630. X          show_menu();
  631. X        }
  632. X        else {
  633. X          MoveCursor(LINES-4, 0);
  634. X          CleartoEOS();
  635. X        }
  636. X      }
  637. X
  638. X    } /* the BIG while loop! */
  639. X}
  640. X
  641. Xdebug_screen()
  642. X{
  643. X    /**** spit out all the current variable settings and the table
  644. X          entries for the current 'n' items displayed. ****/
  645. X
  646. X    register int i, j;
  647. X    char     buffer[SLEN];
  648. X
  649. X    ClearScreen();
  650. X    Raw(OFF);
  651. X
  652. X    PutLine2(0,0,"Current message number = %d\t\t%d message(s) total\n",
  653. X            current, message_count);
  654. X    PutLine2(2,0,"Header_page = %d           \t\t%d possible page(s)\n",
  655. X        header_page, (int) (message_count / headers_per_page) + 1);
  656. X
  657. X    PutLine1(4,0,"\nCurrent mailfile is %s.\n\n", infile);
  658. X
  659. X    i = header_page*headers_per_page;    /* starting header */
  660. X
  661. X    if ((j = i + (headers_per_page-1)) >= message_count) 
  662. X      j = message_count-1;
  663. X
  664. X    Write_to_screen(
  665. X"Num      From                     Subject                         Lines  Offset\n\n",0);
  666. X
  667. X    while (i <= j) {
  668. X       sprintf(buffer, 
  669. X       "%3d  %-16.16s  %-40.40s  %4d  %d\n",
  670. X            i+1,
  671. X                header_table[i].from, 
  672. X                header_table[i].subject,
  673. X            header_table[i].lines,
  674. X            header_table[i].offset);
  675. X        Write_to_screen(buffer, 0);
  676. X      i++;
  677. X    }
  678. X    
  679. X    Raw(ON);
  680. X
  681. X    PutLine0(LINES,0,"Press any key to return: ");
  682. X    (void) ReadCh();
  683. X}
  684. X
  685. X
  686. Xdebug_message()
  687. X{
  688. X    /**** Spit out the current message record.  Include EVERYTHING
  689. X          in the record structure. **/
  690. X    
  691. X    char buffer[SLEN];
  692. X
  693. X    ClearScreen();
  694. X    Raw(OFF);
  695. X
  696. X    Write_to_screen("\t\t\t----- Message %d -----\n\n\n\n", 1,
  697. X        current);
  698. X
  699. X    Write_to_screen("Lines : %-5d\t\t\t\tStatus: N  E  A  P  D  T  V\n", 1,
  700. X        header_table[current-1].lines);
  701. X    Write_to_screen("            \t\t\t\t        e  x  c  r  e  a  i\n", 0);
  702. X    Write_to_screen("            \t\t\t\t        w  p  t  i  l  g  s\n", 0);
  703. X
  704. X    sprintf(buffer, 
  705. X        "\nOffset: %ld\t\t\t\t          %d  %d  %d  %d  %d  %d  %d\n",
  706. X        header_table[current-1].offset,
  707. X        (header_table[current-1].status & NEW) != 0,
  708. X        (header_table[current-1].status & EXPIRED) != 0,
  709. X        (header_table[current-1].status & ACTION) != 0,
  710. X        (header_table[current-1].status & PRIORITY) != 0,
  711. X        (header_table[current-1].status & DELETED) != 0,
  712. X            (header_table[current-1].status & TAGGED) != 0,
  713. X        (header_table[current-1].status & VISIBLE) != 0);
  714. X    Write_to_screen(buffer, 0);
  715. X
  716. X    sprintf(buffer, "\nReceived on: %d/%d/%d at %d:%02d\n\n",
  717. X            header_table[current-1].received.month+1,
  718. X            header_table[current-1].received.day,
  719. X            header_table[current-1].received.year,
  720. X            header_table[current-1].received.hour,
  721. X            header_table[current-1].received.minute);
  722. X    Write_to_screen(buffer, 0);
  723. X
  724. X    sprintf(buffer, "Message sent on: %s, %s %s, %s at %s\n\n",
  725. X            header_table[current-1].dayname,
  726. X            header_table[current-1].month,
  727. X            header_table[current-1].day,
  728. X            header_table[current-1].year,
  729. X            header_table[current-1].time);
  730. X    Write_to_screen(buffer, 0);
  731. X    
  732. X    Write_to_screen("\nFrom: %s\n\nSubject: %s", 2,
  733. X        header_table[current-1].from,
  734. X            header_table[current-1].subject);
  735. X
  736. X    Write_to_screen("\nTo: %s\n\nIndex = %d\n", 2,
  737. X        header_table[current-1].to,
  738. X        header_table[current-1].index_number);
  739. X    
  740. X    Raw(ON);
  741. X
  742. X    PutLine0(LINES,0,"Press any key to return: ");
  743. X    (void) ReadCh();
  744. X}
  745. END_OF_src/elm.c
  746. if test 19751 -ne `wc -c <src/elm.c`; then
  747.     echo shar: \"src/elm.c\" unpacked with wrong size!?
  748. fi
  749. # end of overwriting check
  750. fi
  751. echo shar: Extracting \"src/mailmsg2.c\" \(19017 characters\)
  752. if test -f src/mailmsg2.c ; then 
  753.   echo shar: Will not over-write existing file \"src/mailmsg2.c\"
  754. else
  755. sed "s/^X//" >src/mailmsg2.c <<'END_OF_src/mailmsg2.c'
  756. X/**             mailmsg2.c            **/
  757. X
  758. X/** Interface to allow mail to be sent to users.  Part of ELM  **/
  759. X
  760. X/** (C) Copyright 1986, Dave Taylor                    **/
  761. X
  762. X#include "headers.h"
  763. X#include <errno.h>
  764. X
  765. Xextern int errno;
  766. X
  767. Xchar *error_name(), *error_description(), *strip_parens();
  768. Xchar *strcat(), *strcpy();
  769. Xchar *format_long(), *strip_commas(), *tail_of_string(); 
  770. X
  771. Xunsigned long sleep();
  772. X
  773. X#ifdef SITE_HIDING 
  774. X char *get_ctime_date();
  775. X#endif
  776. XFILE *write_header_info();
  777. X
  778. Xextern char subject[SLEN], action[SLEN], reply_to[SLEN], expires[SLEN], 
  779. X        priority [SLEN], to[VERY_LONG_STRING], cc[VERY_LONG_STRING],
  780. X            in_reply_to[SLEN], expanded_to[VERY_LONG_STRING], 
  781. X        expanded_cc[VERY_LONG_STRING], user_defined_header[SLEN];
  782. X#ifdef ALLOW_BCC
  783. Xextern char bcc[VERY_LONG_STRING], expanded_bcc[VERY_LONG_STRING];
  784. X#endif
  785. X
  786. Xint gotten_key = 0;
  787. X
  788. Xchar *bounce_off_remote();
  789. X
  790. Xmail(copy_msg, edit_message, batch, form)
  791. Xint  copy_msg, edit_message, batch, form;
  792. X{
  793. X    /** Given the addresses and various other miscellany (specifically, 
  794. X        'copy-msg' indicates whether a copy of the current message should 
  795. X        be included, 'edit_message' indicates whether the message should 
  796. X        be edited and 'batch' indicates that the message should be read 
  797. X        from stdin) this routine will invoke an editor for the user and 
  798. X        then actually mail off the message. 'form' can be YES, NO, or
  799. X        MAYBE.  YES=add "Content-Type: mailform" header, MAYBE=add the
  800. X        M)ake form option to last question, and NO=don't worry about it!
  801. X        Also, if 'copy_msg' = FORM, then grab the form temp file and use
  802. X        that...
  803. X    **/
  804. X
  805. X    FILE *reply, *real_reply; /* second is post-input buffer */
  806. X    char filename[SLEN], filename2[SLEN], fname[SLEN],
  807. X             very_long_buffer[VERY_LONG_STRING];
  808. X    char ch;
  809. X    register int retransmit = FALSE; 
  810. X    int      already_has_text = FALSE;        /* we need an ADDRESS */
  811. X
  812. X    static int cancelled_msg = 0;
  813. X
  814. X    dprint2(4,"\nMailing to '%s'(with%s editing)\n",
  815. X          expanded_to, edit_message? "" : "out");
  816. X    
  817. X    /** first generate the temporary filename **/
  818. X
  819. X    sprintf(filename,"%s%d",temp_file, getpid());
  820. X
  821. X    /** if possible, let's try to recall the last message? **/
  822. X
  823. X    if (! batch && copy_msg != FORM && user_level != 0)
  824. X      retransmit = recall_last_msg(filename, copy_msg, &cancelled_msg, 
  825. X               &already_has_text);
  826. X
  827. X    /** if we're not retransmitting, create the file.. **/
  828. X
  829. X    if (! retransmit)
  830. X      if ((reply = fopen(filename,"w")) == NULL) {
  831. X        dprint2(1,
  832. X               "Attempt to write to temp file %s failed with error %s (mail)\n",
  833. X         filename, error_name(errno));
  834. X        error2("Could not create file %s (%s)",filename,
  835. X         error_name(errno));
  836. X        return(1);
  837. X      }
  838. X
  839. X    if (batch) {
  840. X      Raw(OFF);
  841. X      if (isatty(fileno(stdin))) {
  842. X        fclose(reply);    /* let edit-the-message open it! */
  843. X        printf("To: %s\nSubject: %s\n", expanded_to, subject);
  844. X        strcpy(editor, "none");    /* force inline editor */
  845. X        if (no_editor_edit_the_message(filename)) {
  846. X          return(0);    /* confused?  edit_the_msg returns 1 if bad */
  847. X        }
  848. X        if (verify_transmission(filename, &form) == 'f')
  849. X          return(0);
  850. X      }
  851. X      else {
  852. X        while (gets(very_long_buffer) != NULL) 
  853. X          fprintf(reply, "%s\n", very_long_buffer);
  854. X      }
  855. X    }
  856. X
  857. X    if (copy_msg == FORM) {
  858. X      sprintf(fname, "%s%d", temp_form_file, getpid());
  859. X      fclose(reply);    /* we can't retransmit a form! */
  860. X      if (access(fname,ACCESS_EXISTS) != 0) {
  861. X        error("couldn't find forms file!");
  862. X        return(0);
  863. X      }
  864. X      unlink(filename);
  865. X      dprint2(4, "-- linking existing file %s to file %s --\n",
  866. X          fname, filename);
  867. X      link(fname, filename);
  868. X      unlink(fname);
  869. X    }
  870. X    else if (copy_msg && ! retransmit)    /* if retransmit we have it! */
  871. X      if (edit_message) {
  872. X        copy_message(prefixchars, reply, noheader, FALSE);
  873. X        already_has_text = TRUE;    /* we just added it, right? */
  874. X      }
  875. X      else
  876. X        copy_message("", reply, noheader, FALSE);
  877. X
  878. X    if (!batch && ! retransmit && signature && copy_msg != FORM) {
  879. X      fprintf(reply, "\n--\n");    /* News 2.11 compatibility? */
  880. X      if (chloc(expanded_to, '!') == -1 && chloc(expanded_to, '@') == -1) {
  881. X        if (strlen(local_signature) > 0) {
  882. X          if (local_signature[0] != '/')
  883. X            sprintf(filename2, "%s/%s", home, local_signature);
  884. X          else    
  885. X             strcpy(filename2, local_signature);
  886. X          (void) append(reply, filename2);
  887. X          already_has_text = TRUE;    /* added signature... */
  888. X        }
  889. X      }
  890. X      else {
  891. X        if (remote_signature[0] != '/')
  892. X          sprintf(filename2, "%s/%s", home, remote_signature);
  893. X        else    
  894. X           strcpy(filename2, remote_signature);
  895. X        (void) append(reply, filename2);
  896. X        already_has_text = TRUE;    /* added signature... */
  897. X      }
  898. X    }
  899. X
  900. X    if (! retransmit && copy_msg != FORM)
  901. X      (void) fclose(reply);    /* on replies, it won't be open! */
  902. X
  903. X    /** Edit the message **/
  904. X
  905. X    if (edit_message)
  906. X      create_readmsg_file();    /* for "readmsg" routine */
  907. X
  908. X    ch = edit_message? 'e' : ' ';    /* drop through if needed... */
  909. X
  910. X    if (! batch) {
  911. X      do {
  912. X        switch (ch) {
  913. X          case 'e': if (edit_the_message(filename, already_has_text)) {
  914. X              cancelled_msg = TRUE;
  915. X              return(1);
  916. X            }
  917. X            break;
  918. X          case 'h': edit_headers();                    break;
  919. X          default : /* do nothing */ ;
  920. X        }
  921. X
  922. X        /** ask that silly question again... **/
  923. X  
  924. X        if ((ch = verify_transmission(filename, &form)) == 'f') {
  925. X          cancelled_msg = TRUE;
  926. X          return(1);
  927. X        }
  928. X      } while (ch != 's');
  929. X
  930. X      if (form == YES) 
  931. X        if (format_form(filename) < 1) {
  932. X          cancelled_msg = TRUE;
  933. X          return(1);
  934. X        }
  935. X
  936. X      if ((reply = fopen(filename,"r")) == NULL) {
  937. X          dprint2(1,
  938. X        "Attempt to open file %s for reading failed with error %s (mail)\n",
  939. X                filename, error_name(errno));
  940. X          error1("Could not open reply file (%s)", error_name(errno));
  941. X          return(1);
  942. X      }
  943. X    }
  944. X    else if ((reply = fopen(filename,"r")) == NULL) {
  945. X      dprint2(1,
  946. X        "Attempt to open file %s for reading failed with error %s (mail)\n",
  947. X             filename, error_name(errno));
  948. X      error1("Could not open reply file (%s)", error_name(errno));
  949. X      return(1);
  950. X    }
  951. X
  952. X    cancelled_msg = FALSE;    /* it ain't cancelled, is it? */
  953. X
  954. X    /** ask about bounceback if the user wants us to.... **/
  955. X
  956. X    if (uucp_hops(to) > bounceback && bounceback > 0 && copy_msg != FORM) 
  957. X      if (verify_bounceback() == TRUE) {
  958. X        if (strlen(cc) > 0) strcat(expanded_cc, ", ");
  959. X        strcat(expanded_cc, bounce_off_remote(to));
  960. X      }
  961. X
  962. X    /** grab a copy if the user so desires... **/
  963. X
  964. X    if (auto_cc && !batch) 
  965. X      save_copy(subject, expanded_to, expanded_cc, filename, to);
  966. X
  967. X    /** write all header information into real_reply **/
  968. X
  969. X    sprintf(filename2,"%s%d",temp_file, getpid()+1);
  970. X    
  971. X    /** try to write headers to new temp file **/
  972. X
  973. X    dprint2(6, "Composition file='%s' and mail buffer='%s'\n", 
  974. X            filename, filename2);
  975. X
  976. X    if ((real_reply=write_header_info(filename2, expanded_to, expanded_cc,
  977. X#ifdef ALLOW_BCC
  978. X                       expanded_bcc,
  979. X#endif
  980. X                              form == YES)) == NULL) {
  981. X
  982. X      /** IT FAILED!!  MEIN GOTT!  Use a dumb mailer instead! **/
  983. X
  984. X      dprint1(3,"** write_header failed: %s\n", error_name(errno));
  985. X
  986. X      if (cc[0] != '\0')          /* copies! */
  987. X        sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
  988. X
  989. X      sprintf(very_long_buffer, "( (%s -s \"%s\" %s ; %s %s) & ) < %s",
  990. X                  mailx, subject, strip_parens(strip_commas(expanded_to)), 
  991. X          remove, filename, filename);
  992. X
  993. X      error1("Message sent using dumb mailer - %s", mailx);
  994. X      sleep(2);    /* ensure time to see this prompt! */
  995. X
  996. X    }
  997. X    else {
  998. X      copy_message_across(reply, real_reply);
  999. X
  1000. X      fclose(real_reply);
  1001. X
  1002. X      if (cc[0] != '\0')                           /* copies! */
  1003. X        sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
  1004. X
  1005. X#ifdef ALLOW_BCC
  1006. X      if (bcc[0] != '\0') {
  1007. X        strcat(expanded_to, " ");
  1008. X        strcat(expanded_to, expanded_bcc);
  1009. X      }
  1010. X#endif
  1011. X
  1012. X      if (access(sendmail, EXECUTE_ACCESS) == 0 
  1013. X#ifdef SITE_HIDING
  1014. X          && ! is_a_hidden_user(username))
  1015. X#else
  1016. X         )
  1017. X#endif
  1018. X        sprintf(very_long_buffer,"( (%s %s %s ; %s %s) & ) < %s",
  1019. X                  sendmail, smflags, strip_parens(strip_commas(expanded_to)), 
  1020. X          remove, filename2, filename2);
  1021. X      else                    /* oh well, use default mailer... */
  1022. X            sprintf(very_long_buffer,"( (%s %s ; %s %s) & ) < %s", 
  1023. X                  mailer, strip_parens(strip_commas(expanded_to)), 
  1024. X          remove, filename2, filename2);
  1025. X    }
  1026. X    
  1027. X    fclose(reply);
  1028. X
  1029. X    if (mail_only) {
  1030. X      printf("sending mail...");
  1031. X      fflush(stdout);
  1032. X    }
  1033. X    else {    
  1034. X      PutLine0(LINES,0,"sending mail...");
  1035. X      CleartoEOLN();
  1036. X    }
  1037. X
  1038. X    system_call(very_long_buffer, SH);
  1039. X
  1040. X    if (mail_only) 
  1041. X      printf("\rmail sent!      \n\r");
  1042. X    else 
  1043. X      set_error("Mail sent!");
  1044. X
  1045. X    return(TRUE);
  1046. X}
  1047. X
  1048. Xmail_form(address, subj)
  1049. Xchar *address, *subj;
  1050. X{
  1051. X    /** copy the appropriate variables to the shared space... */
  1052. X
  1053. X    strcpy(subject, subj);
  1054. X    strcpy(to, address);
  1055. X    strcpy(expanded_to, address);
  1056. X
  1057. X    return(mail(FORM, NO, NO, NO));
  1058. X}
  1059. X
  1060. Xint
  1061. Xrecall_last_msg(filename, copy_msg, cancelled_msg, already_has_text)
  1062. Xchar *filename;
  1063. Xint  copy_msg, *cancelled_msg, *already_has_text;
  1064. X{
  1065. X    /** If filename exists and we've recently cancelled a message,
  1066. X        the ask if the user wants to use that message instead!  This
  1067. X        routine returns TRUE if the user wants to retransmit the last
  1068. X        message, FALSE otherwise...
  1069. X    **/
  1070. X
  1071. X    register int retransmit = FALSE;
  1072. X
  1073. X    if (access(filename, EDIT_ACCESS) == 0 && *cancelled_msg) {
  1074. X      Raw(ON);
  1075. X      CleartoEOLN();
  1076. X      if (copy_msg)
  1077. X        PutLine1(LINES-1,0,"Recall last kept message instead? (y/n) y%c",
  1078. X             BACKSPACE);
  1079. X      else
  1080. X        PutLine1(LINES-1,0,"Recall last kept message? (y/n) y%c", 
  1081. X             BACKSPACE);
  1082. X      fflush(stdout);
  1083. X      if (tolower(ReadCh()) != 'n') {
  1084. X        Write_to_screen("Yes",0);    
  1085. X            retransmit++;
  1086. X        *already_has_text = TRUE;
  1087. X      }
  1088. X      else 
  1089. X        Write_to_screen("No",0);    
  1090. X
  1091. X      fflush(stdout);
  1092. X
  1093. X      *cancelled_msg = 0;
  1094. X    }
  1095. X
  1096. X    return(retransmit);
  1097. X}
  1098. X
  1099. Xint
  1100. Xverify_transmission(filename, form_letter)
  1101. Xchar *filename;
  1102. Xint  *form_letter;
  1103. X{
  1104. X    /** Ensure the user wants to send this.  This routine returns
  1105. X        the character entered.  Modified compliments of Steve Wolf 
  1106. X        to add the'dead.letter' feature.
  1107. X        Also added form letter support... 
  1108. X    **/
  1109. X
  1110. X    FILE *deadfd, *messagefd;
  1111. X    char ch, buffer[LONG_SLEN], fname[SLEN];
  1112. X
  1113. X    if (mail_only) {
  1114. X      if (isatty(fileno(stdin))) {
  1115. X        printf("\n\rAre you sure you want to send this? (y/n) ");
  1116. X        CleartoEOLN();
  1117. X        printf("y%c", BACKSPACE);
  1118. X        fflush(stdin);                /* wait for answer! */
  1119. X        fflush(stdout);
  1120. X        if (tolower(ReadCh()) == 'n') {             /* >SIGH< */
  1121. X          printf("No\n\r\n\r");
  1122. X          /** try to save it as a dead letter file **/
  1123. X          
  1124. X          sprintf(fname, "%s/%s", home, dead_letter);
  1125. X
  1126. X          if ((deadfd = fopen(fname,"a")) == NULL) {
  1127. X        dprint2(1,
  1128. X           "\nAttempt to append to deadletter file '%s' failed: %s\n\r",
  1129. X            fname, error_name(errno));
  1130. X            printf("Message not saved, Sorry.\n\r\n\r");
  1131. X        return('f');
  1132. X          }
  1133. X          else if ((messagefd = fopen(filename, "r")) == NULL) {
  1134. X        dprint2(1,"\nAttempt to read reply file '%s' failed: %s\n\r",
  1135. X            filename, error_name(errno));
  1136. X            printf("Message not saved, Sorry.\n\r\n\r");
  1137. X        return('f');
  1138. X          }
  1139. X    
  1140. X          /* if we get here we're okay for everything, right? */
  1141. X
  1142. X          while (fgets(buffer, LONG_SLEN, messagefd) != NULL)
  1143. X        fputs(buffer, deadfd);
  1144. X
  1145. X          fclose(messagefd);
  1146. X          fclose(deadfd);
  1147. X
  1148. X          printf("Message saved in file \"$HOME/%s\"\n\r\n\r", dead_letter);
  1149. X
  1150. X          return('f');    /* forget it! */
  1151. X        }
  1152. X        else
  1153. X          printf("Yes\n\r\n\r");
  1154. X        return('s');       /* send this baby! */
  1155. X      }
  1156. X      else
  1157. X        return('s');    /*    ditto       */
  1158. X    }
  1159. X    else if (check_first) {    /* used to check strlen(infile) > 0 too? */
  1160. Xreprompt:
  1161. X      MoveCursor(LINES,0);
  1162. X      CleartoEOLN();
  1163. X      ClearLine(LINES-1);
  1164. X
  1165. X      if (user_level == 0)
  1166. X        PutLine1(LINES-1,0, "Are you sure you want to send this? (y/n) y%c",
  1167. X               BACKSPACE);
  1168. X      else if (*form_letter == PREFORMATTED) 
  1169. X        PutLine1(LINES-1, 0, 
  1170. X                 "Choose: edit H)eaders, S)end, or F)orget : s%c",
  1171. X             BACKSPACE);
  1172. X      else if (*form_letter == YES) 
  1173. X        PutLine1(LINES-1, 0, 
  1174. X                 "Choose: E)dit form, edit H)eaders, S)end, or F)orget : s%c",
  1175. X             BACKSPACE);
  1176. X      else if (*form_letter == MAYBE) 
  1177. X        PutLine1(LINES-1, 0, 
  1178. X        "Choose: E)dit msg, edit H)eaders, M)ake form, S)end, or F)orget : s%c",
  1179. X         BACKSPACE);
  1180. X      else
  1181. X        PutLine1(LINES-1, 0, 
  1182. X         "Please choose: E)dit msg, edit H)eaders, S)end, or F)orget : s%c",
  1183. X         BACKSPACE);
  1184. X
  1185. X      fflush(stdin);    /* wait for answer! */
  1186. X      fflush(stdout);
  1187. X      Raw(ON);    /* double check... testing only... */
  1188. X      ch = tolower(ReadCh());
  1189. X
  1190. X      if (user_level == 0) {
  1191. X        if (ch == 'n') {
  1192. X          set_error("message cancelled");
  1193. X          return('f');
  1194. X        }
  1195. X        else
  1196. X          return('s');
  1197. X      }
  1198. X
  1199. X      /* otherwise someone who knows what's happenin' so...  */
  1200. X
  1201. X      switch (ch) {
  1202. X         case 'f': Write_to_screen("Forget",0);
  1203. X                   set_error(
  1204. X          "Message kept - Can be restored at next F)orward, M)ail or R)eply ");
  1205. X               break;
  1206. X
  1207. X         case '\n' :
  1208. X         case '\r' :
  1209. X         case 's'  : Write_to_screen("Send",0);
  1210. X             ch = 's';        /* make sure! */
  1211. X             break;
  1212. X
  1213. X         case 'm'  : if (*form_letter == MAYBE) {
  1214. X               *form_letter = YES;
  1215. X                   switch (check_form_file(filename)) {
  1216. X                 case -1 : return('f');
  1217. X                 case 0  : *form_letter = MAYBE;  /* check later!*/
  1218. X                       error("No fields in form!");
  1219. X                       return('e');
  1220. X                 default : goto reprompt;
  1221. X                       }
  1222. X             }
  1223. X             else {
  1224. X                        Write_to_screen("%c??", 1, 07);    /* BEEP */
  1225. X                sleep(1);
  1226. X                    goto reprompt;        /* yech */
  1227. X                     }
  1228. X         case 'e'  :  if (*form_letter != PREFORMATTED) {
  1229. X                Write_to_screen("Edit",0);
  1230. X                     if (*form_letter == YES) 
  1231. X                  *form_letter = MAYBE;
  1232. X                      }
  1233. X              else {
  1234. X                        Write_to_screen("%c??", 1, 07);    /* BEEP */
  1235. X                sleep(1);
  1236. X                    goto reprompt;        /* yech */
  1237. X                     }
  1238. X             break;
  1239. X         case 'h'  : Write_to_screen("Headers",0);
  1240. X             break;
  1241. X
  1242. X         default   : Write_to_screen("%c??", 1, 07);    /* BEEP */
  1243. X             sleep(1);
  1244. X                 goto reprompt;        /* yech */
  1245. X       }
  1246. X
  1247. X       return(ch);
  1248. X    }
  1249. X    else return('s');
  1250. X}
  1251. X
  1252. XFILE *
  1253. X#ifdef ALLOW_BCC
  1254. X write_header_info(filename, long_to, long_cc, long_bcc, form)
  1255. X char *filename, *long_to, *long_cc, *long_bcc;
  1256. X#else
  1257. X write_header_info(filename, long_to, long_cc, form)
  1258. X char *filename, *long_to, *long_cc;
  1259. X#endif
  1260. Xint   form;
  1261. X{
  1262. X    /** Try to open filedesc as the specified filename.  If we can,
  1263. X        then write all the headers into the file.  The routine returns
  1264. X        'filedesc' if it succeeded, NULL otherwise.  Added the ability
  1265. X        to have backquoted stuff in the users .elmheaders file!
  1266. X    **/
  1267. X
  1268. X    static FILE *filedesc;        /* our friendly file descriptor  */
  1269. X
  1270. X#ifdef SITE_HIDING
  1271. X    char  buffer[SLEN];
  1272. X    int   is_hidden_user;        /* someone we should know about?  */
  1273. X#endif
  1274. X
  1275. X    char  *get_arpa_date();
  1276. X
  1277. X    if ((filedesc = fopen(filename, "w")) == NULL) {
  1278. X      dprint1(1,
  1279. X        "Attempt to open file %s for writing failed! (write_header_info)\n",
  1280. X         filename);
  1281. X      dprint2(1,"** %s - %s **\n\n", error_name(errno),
  1282. X         error_description(errno));
  1283. X      error2("Error %s encountered trying to write to %s", 
  1284. X        error_name(errno), filename);
  1285. X      sleep(2);
  1286. X      return(NULL);        /* couldn't open it!! */
  1287. X    }
  1288. X
  1289. X#ifdef SITE_HIDING
  1290. X    if ((is_hidden_user = is_a_hidden_user(username))) {
  1291. X      /** this is the interesting part of this trick... **/
  1292. X      sprintf(buffer, "From %s!%s %s\n",  HIDDEN_SITE_NAME,
  1293. X          username, get_ctime_date());
  1294. X      fprintf(filedesc, "%s", buffer);
  1295. X      dprint1(1,"\nadded: %s", buffer);
  1296. X      /** so is this perverted or what? **/
  1297. X    }
  1298. X#endif
  1299. X
  1300. X    fprintf(filedesc, "To: %s\n", format_long(long_to, strlen("To:")));
  1301. X
  1302. X    fprintf(filedesc,"Date: %s\n", get_arpa_date());
  1303. X
  1304. X#ifndef DONT_ADD_FROM
  1305. X# ifdef SITE_HIDING
  1306. X    if (is_hidden_user)
  1307. X      fprintf(filedesc,"From: %s <%s!%s!%s>\n", full_username,
  1308. X          hostname, HIDDEN_SITE_NAME, username);
  1309. X    else
  1310. X# endif
  1311. X# ifdef  INTERNET_ADDRESS_FORMAT
  1312. X#  ifdef  USE_DOMAIN
  1313. X    fprintf(filedesc,"From: %s <%s@%s%s>\n", full_username, 
  1314. X        username, hostname, DOMAIN);
  1315. X#  else
  1316. X    fprintf(filedesc,"From: %s <%s@%s>\n", full_username,
  1317. X        username, hostname);
  1318. X#  endif
  1319. X# else
  1320. X    fprintf(filedesc,"From: %s <%s!%s>\n", full_username,
  1321. X        hostname, username);
  1322. X# endif
  1323. X#endif
  1324. X
  1325. X    fprintf(filedesc, "Subject: %s\n", subject);
  1326. X
  1327. X    if (cc[0] != '\0')
  1328. X      fprintf(filedesc, "Cc: %s\n", format_long(long_cc, strlen("Cc: ")));
  1329. X
  1330. X#ifdef ALLOW_BCC
  1331. X    if (bcc[0] != '\0')
  1332. X     fprintf(filedesc, "Bcc: %s\n", format_long(long_bcc, strlen("Bcc: ")));
  1333. X#endif
  1334. X
  1335. X    if (strlen(action) > 0)
  1336. X        fprintf(filedesc, "Action: %s\n", action);
  1337. X    
  1338. X    if (strlen(priority) > 0)
  1339. X        fprintf(filedesc, "Priority: %s\n", priority);
  1340. X    
  1341. X    if (strlen(expires) > 0)
  1342. X        fprintf(filedesc, "Expiration-Date: %s\n", expires);
  1343. X    
  1344. X    if (strlen(reply_to) > 0)
  1345. X        fprintf(filedesc, "Reply-To: %s\n", reply_to);
  1346. X
  1347. X    if (strlen(in_reply_to) > 0)
  1348. X        fprintf(filedesc, "In-Reply-To: %s\n", in_reply_to);
  1349. X
  1350. X    if (strlen(user_defined_header) > 0)
  1351. X        fprintf(filedesc, "%s\n", user_defined_header);
  1352. X
  1353. X    add_mailheaders(filedesc);
  1354. X
  1355. X    if (form)
  1356. X      fprintf(filedesc, "Content-Type: mailform\n");
  1357. X
  1358. X    fprintf(filedesc, "X-Mailer: Elm [version %s]\n\n", VERSION);
  1359. X
  1360. X    return((FILE *) filedesc);
  1361. X}
  1362. X
  1363. Xcopy_message_across(source, dest)
  1364. XFILE *source, *dest;
  1365. X{
  1366. X    /** copy the message in the file pointed to by source to the
  1367. X        file pointed to by dest.  **/
  1368. X
  1369. X    int  crypted = FALSE;            /* are we encrypting?  */
  1370. X    int  encoded_lines = 0;            /* # lines encoded     */
  1371. X    char buffer[LONG_SLEN];            /* file reading buffer */
  1372. X
  1373. X    while (fgets(buffer, LONG_SLEN, source) != NULL) {
  1374. X      if (buffer[0] == '[') {
  1375. X        if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
  1376. X          crypted = TRUE;
  1377. X         else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
  1378. X          crypted = FALSE;
  1379. X         else if (strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0)
  1380. X          continue;    /* next line? */
  1381. X        }
  1382. X        else if (crypted) {
  1383. X          if (! gotten_key++)
  1384. X            getkey(ON);
  1385. X          else if (! encoded_lines++)
  1386. X            get_key_no_prompt();        /* reinitialize.. */
  1387. X         
  1388. X          encode(buffer);
  1389. X        }
  1390. X        fputs(buffer, dest);
  1391. X      }
  1392. X}
  1393. X
  1394. Xint
  1395. Xverify_bounceback()
  1396. X{
  1397. X    /** Ensure the user wants to have a bounceback copy too.  (This is
  1398. X        only called on messages that are greater than the specified 
  1399. X        threshold hops and NEVER for non-uucp addresses.... Returns
  1400. X        TRUE iff the user wants to bounce a copy back.... 
  1401. X     **/
  1402. X
  1403. X    if (mail_only) {
  1404. X      printf("Would you like a copy \"bounced\" off the remote? (y/n) ");
  1405. X      CleartoEOLN();
  1406. X      printf("n%c", BACKSPACE);
  1407. X      fflush(stdin);                /* wait for answer! */
  1408. X      fflush(stdout);
  1409. X      if (tolower(ReadCh()) != 'y') {
  1410. X        printf("No\n\r");
  1411. X        return(FALSE);
  1412. X      }
  1413. X      else
  1414. X        printf("Yes - Bounceback included\n\r");
  1415. X    }
  1416. X    else {
  1417. X      MoveCursor(LINES,0);
  1418. X      CleartoEOLN();
  1419. X      PutLine1(LINES,0, 
  1420. X        "\"Bounce\" a copy off the remote machine? (y/n) y%c",
  1421. X        BACKSPACE);
  1422. X      fflush(stdin);    /* wait for answer! */
  1423. X      fflush(stdout);
  1424. X      if (tolower(ReadCh()) != 'y') { 
  1425. X        Write_to_screen("No", 0);
  1426. X        fflush(stdout);
  1427. X        return(FALSE);
  1428. X      }
  1429. X      Write_to_screen("Yes!", 0);
  1430. X      fflush(stdout);
  1431. X    }
  1432. X
  1433. X    return(TRUE);
  1434. X}
  1435. END_OF_src/mailmsg2.c
  1436. if test 19017 -ne `wc -c <src/mailmsg2.c`; then
  1437.     echo shar: \"src/mailmsg2.c\" unpacked with wrong size!?
  1438. fi
  1439. # end of overwriting check
  1440. fi
  1441. echo shar: End of archive 17 \(of 19\).
  1442. cp /dev/null ark17isdone
  1443. DONE=true
  1444. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  1445.     if test ! -f ark${I}isdone ; then
  1446.     echo shar: You still need to run archive ${I}.
  1447.     DONE=false
  1448.     fi
  1449. done
  1450. if test "$DONE" = "true" ; then
  1451.     echo You have unpacked all 19 archives.
  1452.     echo "See the Instructions file"
  1453.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1454. fi
  1455. ##  End of shell archive.
  1456. exit 0
  1457.