1% sendmail.sl -*- mode: slang; mode: fold -*- 2% 3% (Thanks to olesen@weber.me.queensu.ca (mj olesen) for this) 4% 5% Sendmail interface for Unix. 6% 7% Functions: 8% mail_send : send message 9% mail : initiate mail mode 10% mail_insert_signature : append contents of Mail_Signature_File 11% mail_kill_buffer : Delete mail buffer 12% 13% Variables: 14% Mail_Reply_To : Set this to appropriate Reply-To value 15% Mail_Signature_File : Filename of signature (~/.signature is default) 16% SendMail_Cmd : Name of sendmail program including switches 17% Mail_Extra_Headers : Misc headers to insert 18% 19% You might want something like the following in mail_hook 20% 21% define mail_hook () 22% { 23% local_setkey ("mail_send", "^C^C"); 24% local_setkey ("mailalias_expand", "^C^E"); 25% local_setkey ("mail_kill_buffer", "^Xk"); 26% } 27 28autoload ("mailalias_expand", "mailalias"); % the mail-alias package 29 30% Create a dummy function if set_line_readonly is not defined. 31!if (is_defined ("set_line_readonly")) eval (".(pop) set_line_readonly"); 32 33%{{{ Public Variables 34 35$1 = "~/.signature"; 36!if (is_defined ("Mail_Signature_File")) 37{ 38 variable Mail_Signature_File = expand_filename ($1); 39} 40 41!if (is_defined ("Mail_Header_Separator_String")) 42 variable Mail_Header_Separator_String = 43"--- Do not modify this line. Enter your message below ---"; 44 45!if (is_defined ("Mail_Extra_Headers")) 46{ 47 variable Mail_Extra_Headers = NULL; 48} 49 50 51% The sendmail program 52 53$1 = _stkdepth (); 54NULL; 55"/usr/bin/sendmail"; % places to look 56"/usr/lib/sendmail"; 57"/usr/sbin/sendmail"; 58 59!if (is_defined ("SendMail_Cmd")) 60{ 61 variable SendMail_Cmd; 62 63 while (SendMail_Cmd = (), SendMail_Cmd != NULL) 64 { 65 if (1 == file_status (SendMail_Cmd)) 66 { 67 SendMail_Cmd = strcat (SendMail_Cmd, " -t -oem -oi -odb"); 68 break; 69 } 70 } 71 72} 73 74_pop_n (_stkdepth () - $1); 75 76!if (strlen (SendMail_Cmd)) error ("`sendmail' program not found!"); 77 78%!% always Reply-To: here instead. 79!if (is_defined ("Mail_Reply_To")) 80{ 81 variable Mail_Reply_To = Null_String; 82} 83 84%}}} 85 86%{{{ Private Variables 87 88private variable Mail_Previous_Buffer = Null_String; 89private variable Mail_Previous_Windows = 1; 90private variable Mail_This_Buffer = Null_String; 91private variable Mail_Filename = dircat (getenv ("HOME"), ".__jed_mail__"); 92 93%}}} 94 95%{{{ Private Functions 96 97 98define mail_sw2_prev_buf () 99{ 100 if (bufferp (Mail_Previous_Buffer)) sw2buf (Mail_Previous_Buffer); 101 if (1 == Mail_Previous_Windows) onewindow (); 102 if (bufferp (Mail_This_Buffer) and strcmp (Mail_This_Buffer, Mail_Previous_Buffer)) 103 pop2buf (Mail_This_Buffer); 104} 105 106%}}} 107 108define mail_send () %{{{ 109{ 110 variable dir, file, sent, buf = "*mail*"; 111 variable sep_mark, fcc_mark, fcc_file; 112 113 if (buf != whatbuf ()) 114 error ("not *mail* buffer"); 115 116 flush ("Sending..."); 117 118 push_spot (); 119 120 bob (); 121 !if (bol_fsearch (Mail_Header_Separator_String)) 122 { 123 !if (bol_fsearch ("\n")) 124 { 125 pop_spot (); 126 verror ("Cannot find %s\n", Mail_Header_Separator_String); 127 } 128 } 129 130 set_line_readonly (0); 131 del_eol (); 132 sep_mark = create_user_mark (); 133 134 bob (); 135 fcc_mark = NULL; 136 if (bol_fsearch ("Fcc: ")) 137 { 138 push_mark_eol (); 139 go_right_1 (); 140 fcc_file = strtrim (substr (bufsubstr_delete (), 6, -1)); 141 fcc_mark = create_user_mark (); 142 } 143 144 145 mark_buffer (); 146 sent = not (pipe_region (SendMail_Cmd)); 147 148 if (fcc_mark != NULL) 149 { 150 if (sent and strlen (fcc_file)) 151 { 152 variable user = getenv ("USER"); 153 if (user == NULL) 154 { 155 user = getenv ("LOGNAME"); 156 if (user == NULL) 157 user = "user"; 158 } 159 () = append_string_to_file (sprintf ("From %s %s\n", user, time ()), fcc_file); 160 161 % Make sure the buffer ends with two newline characters 162 eob (); 163 push_mark (); 164 bskip_chars (" \t\n"); 165 del_region (); 166 newline (); newline (); 167 168 mark_buffer (); 169 () = append_region_to_file (fcc_file); 170 } 171 goto_user_mark (fcc_mark); 172 vinsert ("Fcc: %s\n", fcc_file); 173 174 % If the marks are on top of one another, make sure sep_mark gets 175 % updated. I added the binary operations on User Marks just for 176 % this purpose. 177 if (fcc_mark == sep_mark) 178 move_user_mark (sep_mark); 179 } 180 181 goto_user_mark (sep_mark); 182 insert (Mail_Header_Separator_String); 183 184 pop_spot (); 185 186 if (sent) 187 { 188 set_buffer_modified_flag (0); 189 flush ("Sending...done"); 190 (file, dir,,) = getbuf_info (); 191 () = delete_file (make_autosave_filename (dir, file)); 192 file = dircat (dir, file); 193 !if (strcmp (Mail_Filename, file)) 194 () = delete_file (Mail_Filename); 195 mail_sw2_prev_buf (); 196 bury_buffer (buf); 197 return; 198 } 199 200 flush ("Error sending message"); 201 beep (); 202} 203add_completion ("mail_send"); 204 205%}}} 206 207define mail_format_buffer () %{{{ 208{ 209 variable erase, opt_headers=NULL; 210 if (_NARGS == 2) 211 opt_headers = (); 212 erase = (); 213 214 variable km = "mail_map"; 215 216 text_mode (); 217 218 setbuf_info (getbuf_info () & ~(0x40)); % turn off buried buffer flag 219 220 !if (keymap_p(km)) make_keymap(km); 221 use_keymap(km); 222 223 if (erase == -1) 224 { 225 if (buffer_modified ()) 226 { 227 !if (get_yes_no("Mail already being composed. Erase it")) 228 erase = 0; 229 } 230 } 231 232 if (erase) 233 { 234 erase_buffer (); 235 236 insert ("To: \nCc: \nBcc: \nSubject: \n"); 237 if (strlen (Mail_Reply_To)) 238 vinsert ("Reply-To: %s\n", Mail_Reply_To); 239 240 if (opt_headers != NULL) 241 { 242 insert (opt_headers); 243 } 244 245 if (Mail_Extra_Headers != NULL) 246 { 247 insert (Mail_Extra_Headers); 248 newline (); 249 } 250 insert (Mail_Header_Separator_String); 251 newline (); 252 253 go_up_1 (); 254 set_line_readonly (1); 255 256 bob (); eol (); 257 set_buffer_modified_flag(0); 258 259 } 260 261 push_spot (); 262 run_mode_hooks("mail_hook"); 263 pop_spot (); 264 265 set_buffer_undo(1); 266} 267 268%}}} 269 270define mail_kill_buffer () %{{{ 271{ 272 call ("kill_buffer"); 273 mail_sw2_prev_buf (); 274} 275 276%}}} 277 278define mail () %{{{ 279{ 280 variable status, dir, file, buf = "*mail*"; 281 variable do_format = -1; 282 283 status = bufferp (buf); 284 Mail_Previous_Windows = nwindows (); 285 Mail_This_Buffer = whatbuf (); 286 287 if (BATCH) 288 { 289 % Mail_Previous_Buffer = whatbuf (); 290 sw2buf (buf); 291 } 292 else 293 { 294 Mail_Previous_Buffer = pop2buf_whatbuf (buf); 295 } 296 297 % if buffer is not old, turn autosave on 298 if (status) 299 { 300 (,,,status) = getbuf_info (); 301 if (buffer_modified ()) 302 return; 303 } 304 else 305 { 306 (dir, file) = parse_filename (Mail_Filename); 307 setbuf_info (file, dir, buf, 2); % autosave 308 309 file = make_autosave_filename(dir, file); 310 if (1 == file_status (file)) 311 { 312 if (get_yes_no ("An autosave file exists. Use it")) 313 { 314 erase_buffer (); 315 () = insert_file (file); 316 do_format = 0; 317 } 318 } 319 } 320 321 () = set_buffer_umask (0077); 322 mail_format_buffer (do_format); 323} 324 325%}}} 326 327define mail_insert_signature () %{{{ 328{ 329 !if (strlen (Mail_Signature_File)) 330 return; 331 332 push_spot (); 333 eob (); 334 insert ("\n-- \n"); 335 () = insert_file (Mail_Signature_File); 336 pop_spot (); 337} 338 339%}}} 340 341