~ubuntu-branches/ubuntu/precise/topal/precise

« back to all changes in this revision

Viewing changes to sending.adb

  • Committer: Bazaar Package Importer
  • Author(s): Phil Brooke
  • Date: 2008-07-18 07:57:38 UTC
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20080718075738-i1szqvmxz0evz32p
Tags: upstream-62
ImportĀ upstreamĀ versionĀ 62

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
--
2
 
--
3
 
--
4
 
--
 
1
-- Topal: GPG/GnuPG and Alpine/Pine integration
 
2
-- Copyright (C) 2001--2008  Phillip J. Brooke
 
3
--
 
4
-- This program is free software: you can redistribute it and/or modify
 
5
-- it under the terms of the GNU General Public License version 3 as
 
6
-- published by the Free Software Foundation.
 
7
--
 
8
-- This program is distributed in the hope that it will be useful,
 
9
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
-- GNU General Public License for more details.
 
12
--
 
13
-- You should have received a copy of the GNU General Public License
 
14
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
5
15
 
6
16
with Ada.Command_Line;
7
17
with Ada.Text_IO;
 
18
with Attachments;
8
19
with Configuration;
9
20
with Externals;             use Externals;
10
21
with Externals.GPG;
26
24
with Keys;
27
25
with Menus;                 use Menus;
28
26
with Misc;                  use Misc;
 
27
with Readline;
 
28
with Remote_Mode;
29
29
 
30
30
package body Sending is
31
31
 
32
32
   Exit_Send_Loop : exception; -- Subroutine says `bail out, please'.
33
33
 
34
34
   procedure Key_Preselect (K          : in out Keys.Key_List;
35
 
                            Recipients : in     UBS_Array) is
 
35
                            Recipients : in     UBS_Array;
 
36
                            Alt_Sign   : in     String       := "") is
36
37
   begin
37
38
      -- Can we preselect any keys?
38
39
      Keys.Empty_Keylist(K);
39
40
      Keys.Use_Keylist(Recipients, K);
40
 
      -- Add our own key.
 
41
      -- Add our own key.  If Alt_Sign is non-empty, then try and add
 
42
      --  keys for that instead.
41
43
      declare
42
 
         Found : Boolean;
 
44
         AKL     : Keys.Key_List;
 
45
         Found   : Boolean       := False;
 
46
         KC      : Natural;
 
47
         The_Key : UBS;
43
48
      begin
44
 
         if ToStr(Config.My_Key) = "" then
45
 
            Ada.Text_IO.Put_Line("my-key is empty; not selecting any keys for self");
46
 
         else
47
 
            Keys.Add_Keys_By_Fingerprint(Value_Nonempty(Config.My_Key),
48
 
                                         K,
49
 
                                         Found);
 
49
         if Alt_Sign /= "" then
 
50
            Ada.Text_IO.Put_Line("Looking for signing key for `"&Alt_Sign&"' on SAKE list...");
 
51
            for J in 1..Config.SAKE_Count loop
 
52
               if ToStr(UAP.Value(Config.SAKE_Email, J)) = Alt_Sign then
 
53
                  Keys.Add_Keys_By_Fingerprint(UAP.Value(Config.SAKE_Key, J),
 
54
                                               K, Keys.Both, Found);
 
55
                  if Found then
 
56
                     Ada.Text_IO.Put_Line("Added key `"&ToStr(UAP.Value(Config.SAKE_Key, J))&"' for signing...");
 
57
                     Config.My_Key := UAP.Value(Config.SAKE_Key, J);
 
58
                  else
 
59
                     Ada.Text_IO.Put_Line("Couldn't add key `"&ToStr(UAP.Value(Config.SAKE_Key, J))&"' for signing...");
 
60
                  end if;
 
61
               end if;
 
62
            end loop;
 
63
         end if;
 
64
         if Alt_Sign /= "" and (not Found) then
 
65
            Keys.Empty_Keylist(AKL);
 
66
            Ada.Text_IO.Put_Line("Looking for signing key for `"&Alt_Sign&"' via keyring (& XK list)...");
 
67
            Keys.Add_Secret_Keys(ToUBS(Alt_Sign),
 
68
                                 AKL,
 
69
                                 Keys.Both);
 
70
            -- Any keys to remove on the SXK list?
 
71
            for J in 1..Config.SXK_Count loop
 
72
               Keys.Remove_Key(UAP.Value(Config.SXK_Key, J), AKL);
 
73
            end loop;
 
74
            KC := Keys.Count(AKL);
 
75
            Found := KC > 0;
50
76
            if Found then
51
 
               Ada.Text_IO.Put_Line("Info: Added `my-key' key(s) for self");
52
 
            else
53
 
               Ada.Text_IO.Put_Line("Warning: my-key="
54
 
                                    & ToStr(Config.My_key)
55
 
                                    & " does not find keys");
 
77
               if KC = 1 then
 
78
                  Ada.Text_IO.Put_Line("Added one signing key...");
 
79
                  -- Add this one.
 
80
                  Keys.First_Key_From_List(AKL, The_Key);
 
81
                  Keys.Add_Key(The_Key, K, Keys.Both);
 
82
                  Config.My_Key := The_Key;
 
83
               else
 
84
                  -- Multiple keys...
 
85
                  Ada.Text_IO.Put_Line("Found multiple possible signing keys...");
 
86
                  -- Choose one.  If aborted, fall-back to my-key.
 
87
                  Keys.Select_Key_From_List(AKL, The_Key, Found);
 
88
                  -- Found is not aborted...
 
89
                  Found := not Found;
 
90
                  if Found then
 
91
                     Keys.Add_Key(The_Key, K, Keys.Both);
 
92
                     Config.My_Key := The_Key;
 
93
                  else
 
94
                     Ada.Text_IO.Put_Line("Aborted selection of secret key, will consider my-key instead");
 
95
                  end if;
 
96
               end if;
 
97
            else
 
98
               Ada.Text_IO.Put_Line("Can't find alternative key, trying my-key...");
 
99
            end if;
 
100
         end if;
 
101
         if Alt_Sign = "" or (not Found) then
 
102
            if ToStr(Config.My_Key) = "" then
 
103
               Ada.Text_IO.Put_Line("my-key is empty; not selecting any keys for self");
 
104
            else
 
105
               Keys.Add_Keys_By_Fingerprint(Value_Nonempty(Config.My_Key),
 
106
                                            K,
 
107
                                            Keys.Encrypter,
 
108
                                            Found);
 
109
               if Found then
 
110
                  Ada.Text_IO.Put_Line("Added `my-key' key(s) for self");
 
111
               else
 
112
                  Ada.Text_IO.Put_Line("Warning: my-key="
 
113
                                       & ToStr(Config.My_key)
 
114
                                       & " does not find keys");
 
115
               end if;
56
116
            end if;
57
117
         end if;
58
118
      end;
70
130
   begin
71
131
      if not Non_Pine then
72
132
         if Mime then
73
 
            Ada.Text_IO.Put_Line("The Content-Type being returned is: ");
74
 
            Cat(Mimefile);
 
133
            if Externals.Simple.Test_R(Mimefile) then
 
134
               Ada.Text_IO.Put_Line("The Content-Type being returned is: ");
 
135
               Cat(Mimefile);
 
136
            else
 
137
               Ada.Text_IO.Put_Line("Unchanged Content-Type.");
 
138
            end if;
75
139
         end if;
76
140
         Wait;
77
141
         Pager(Tmpfile);
92
156
                      Mime      : in Boolean;
93
157
                      Mimefile  : in String;
94
158
                      Send_Keys : in Keys.Key_List;
95
 
                      Selection : in Send_Index) is
96
 
      Out_File       : String := Temp_File_Name("out");
 
159
                      Selection : in Send_Index;
 
160
                      AL        : in Attachments.Attachment_List) is
 
161
      Out_File       : constant String := Temp_File_Name("out");
97
162
      -- PCT = Prepend content-type.
98
163
      Mime_Selection : MIME_Send_Index;
99
164
   begin
105
170
               Ada.Command_Line.Set_Exit_Status(Ada.Command_Line.Failure);
106
171
               raise Exit_Send_Loop;
107
172
            elsif Mime_Selection = Multipart then
108
 
               Echo_Out("Content-Type: text/plain",
109
 
                        Temp_File_Name("pct"));
110
 
               Echo_Append("", Temp_File_Name("pct"));
111
 
               Cat_Append(Tmpfile, Temp_File_Name("pct"));
112
 
               Mv_F(Temp_File_Name("pct"), Tmpfile);
 
173
               declare
 
174
                  PCT : constant String := Temp_File_Name("pct");
 
175
               begin
 
176
                  Echo_Out("Content-Type: text/plain", PCT);
 
177
                  Echo_Append("", PCT);
 
178
                  Cat_Append(Tmpfile, PCT);
 
179
                  Mv_F(PCT, Tmpfile);
 
180
                  -- Call out to attachments in case we have to modify Tmpfile.
 
181
                  Attachments.Replace_Tmpfile(Tmpfile, AL);
 
182
               end;
113
183
            end if;
114
184
         exception
115
185
            when others =>
119
189
         end;
120
190
      end if;
121
191
 
 
192
      if not (Mime and then Mime_Selection = Multipart) then
 
193
         if Attachments.Count(AL) > 0 then
 
194
            Ada.Text_IO.Put_Line("WARNING: attachments not included in non-MIME emails!");
 
195
            Ada.Text_IO.New_Line;
 
196
         end if;
 
197
      end if;
 
198
 
122
199
      begin
123
200
         -- Run GPG.
124
 
         GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
 
201
         Externals.GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
125
202
                      & " --encrypt --armor "
126
203
                      & ToStr(Config.general_options)
127
204
                      & " "
170
247
               when Multipart => -- RFC2015 multipart
171
248
                                 -- This is the nasty one.
172
249
                  declare
173
 
                     Blk1   : String := Temp_File_Name("mp1");
174
 
                     Blk2   : String := Temp_File_Name("mp2");
175
 
                     MC     : String := Temp_File_Name("mc");
 
250
                     Blk1   : constant String := Temp_File_Name("mp1");
 
251
                     Blk2   : constant String := Temp_File_Name("mp2");
 
252
                     MC     : constant String := Temp_File_Name("mc");
176
253
                  begin
177
254
                     -- We first create the two blocks.
178
255
                     -- The first block is easy:
188
265
                     Echo_Append("", Blk2);
189
266
                     Cat_Append(Tmpfile, Blk2);
190
267
                     -- Now we put them together.
191
 
                     Mail.Mimeconstruct2(Part1_Filename  => Blk1,
 
268
                     Externals.Mail.Mimeconstruct2(Part1_Filename  => Blk1,
192
269
                                         Part2_Filename  => Blk2,
193
270
                                         Output_Filename => MC,
194
271
                                         Content_Type    => "multipart/encrypted; protocol=""application/pgp-encrypted""");
221
298
                            Mime      : in Boolean;
222
299
                            Mimefile  : in String;
223
300
                            Send_Keys : in Keys.Key_List;
224
 
                            Selection : in Send_Index) is
225
 
      Out_File       : String          := Temp_File_Name("out");
226
 
      DTBL_File      : String          := Temp_File_Name("dtbl");
227
 
      QP_File        : String          := Temp_File_Name("qp");
228
 
      TDS_File       : String          := Temp_File_Name("tds");
 
301
                            Selection : in Send_Index;
 
302
                            AL        : in Attachments.Attachment_List) is
 
303
      Out_File       : constant String   := Temp_File_Name("out");
 
304
      DTBL_File      : constant String   := Temp_File_Name("dtbl");
 
305
      QP_File        : constant String   := Temp_File_Name("qp");
 
306
      TDS_File       : constant String   := Temp_File_Name("tds");
229
307
      Mime_Selection : MIME_Send_Index;
230
308
   begin
231
309
      if Mime then
244
322
         end;
245
323
      end if;
246
324
 
 
325
      if not (Mime
 
326
              and then (Mime_Selection = MultipartEncap
 
327
                        or Mime_Selection = Multipart)) then
 
328
         if Attachments.Count(AL) > 0 then
 
329
            Ada.Text_IO.Put_Line("WARNING: attachments not included in non-MIME emails!");
 
330
            Ada.Text_IO.New_Line;
 
331
         end if;
 
332
      end if;
 
333
 
247
334
      -- Run GPG.
248
335
      if Mime and then Mime_Selection = MultipartEncap then
249
336
         -- We need to do something different with Tmpfile.
253
340
                                             Outfile => DTBL_File);
254
341
            -- Then we turn it into quoted printable.
255
342
            -- Also turn it into DOS line endings.
256
 
            Mail.Mimeconstruct_Subpart(Infile       => DTBL_File,
 
343
            Externals.Mail.Mimeconstruct_Subpart(Infile       => DTBL_File,
257
344
                                       Outfile      => QP_File,
258
345
                                       Content_Type => "text/plain",
259
346
                                       Dos2UnixU    => True,
261
348
                                       Header       => "Content-Type: text/plain",
262
349
                                       Use_Encoding => True,
263
350
                                       Encoding     => "quoted-printable");
 
351
            -- Call out to attachments in case we have to modify QP_File.
 
352
            Attachments.Replace_Tmpfile(QP_File, AL);
264
353
            -- Then we clearsign it.
265
 
            GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
 
354
            Externals.GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
266
355
                         & " --detach-sign --armor --local-user "
267
356
                         & Value_Nonempty(Config.my_key)
268
357
                         & " "
292
381
                                                Outfile => DTBL_File);
293
382
               -- Then we turn it into quoted printable.
294
383
               -- Also turn it into DOS line endings.
295
 
               Mail.Mimeconstruct_Subpart(Infile       => DTBL_File,
 
384
               Externals.Mail.Mimeconstruct_Subpart(Infile       => DTBL_File,
296
385
                                          Outfile      => QP_File,
297
386
                                          Content_Type => "text/plain",
298
387
                                          Dos2UnixU    => True,
300
389
                                          Header       => "Content-Type: text/plain",
301
390
                                          Use_Encoding => True,
302
391
                                          Encoding     => "quoted-printable");
 
392
               -- Call out to attachments in case we have to modify QP_File.
 
393
               Attachments.Replace_Tmpfile(QP_File, AL);
 
394
               -- Then rename QP_File to Tmpfile...
303
395
               Mv_F(QP_File, Tmpfile);
304
396
            exception
305
397
               when others =>
310
402
         end if;
311
403
 
312
404
         begin
313
 
            GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
 
405
            Externals.GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
314
406
                         & " --encrypt --sign --armor --local-user "
315
407
                         & Value_Nonempty(Config.my_key)
316
408
                         & " "
331
423
                                    "Exception raised in Sending.Sign_Encrypt (GPG block)");
332
424
               raise;
333
425
         end;
 
426
 
334
427
      end if;
335
428
 
336
429
      begin
365
458
                                 -- This is the nasty one.
366
459
                                 -- We are using the combined method allowed in section 6.2.
367
460
                  declare
368
 
                     Blk1   : String := Temp_File_Name("mp1");
369
 
                     Blk2   : String := Temp_File_Name("mp2");
370
 
                     MC     : String := Temp_File_Name("mc");
 
461
                     Blk1   : constant String := Temp_File_Name("mp1");
 
462
                     Blk2   : constant String := Temp_File_Name("mp2");
 
463
                     MC     : constant String := Temp_File_Name("mc");
371
464
                  begin
372
465
                     -- We first create the two blocks.
373
466
                     -- The first block is easy:
383
476
                     Echo_Append("", Blk2);
384
477
                     Cat_Append(Tmpfile, Blk2);
385
478
                     -- Now we put them together.
386
 
                     Mail.Mimeconstruct2(Part1_Filename  => Blk1,
 
479
                     Externals.Mail.Mimeconstruct2(Part1_Filename  => Blk1,
387
480
                                         Part2_Filename  => Blk2,
388
481
                                         Output_Filename => MC,
389
482
                                         Content_Type    => "multipart/encrypted; protocol=""application/pgp-encrypted""");
396
489
                                      -- encapsulating, so we have to sign then
397
490
                                      -- encrypt.
398
491
                  declare
399
 
                     Blk1   : String := Temp_File_Name("mp1");
400
 
                     Blk2   : String := Temp_File_Name("mp2");
401
 
                     MCS    : String := Temp_File_Name("mcs");
402
 
                     MC     : String := Temp_File_Name("mc");
 
492
                     Blk1   : constant String := Temp_File_Name("mp1");
 
493
                     Blk2   : constant String := Temp_File_Name("mp2");
 
494
                     MCS    : constant String := Temp_File_Name("mcs");
 
495
                     MC     : constant String := Temp_File_Name("mc");
403
496
                  begin
404
497
                     -- We first create the two blocks.
405
 
                     Mail.Mimeconstruct_Subpart(Infile       => TDS_File,
 
498
                     Externals.Mail.Mimeconstruct_Subpart(Infile       => TDS_File,
406
499
                                                Outfile      => Blk2,
407
500
                                                Content_Type => "application/pgp-signature",
408
501
                                                Dos2UnixU    => False,
409
502
                                                Use_Header   => False,
410
503
                                                Use_Encoding => False);
411
 
                     Mail.Mimeconstruct2(Part1_Filename  => QP_File,
 
504
                     Externals.Mail.Mimeconstruct2(Part1_Filename  => QP_File,
412
505
                                         Part2_Filename  => Blk2,
413
506
                                         Output_Filename => MCS,
414
507
                                         Content_Type    => "multipart/signed; protocol=""application/pgp-signature""; micalg="""
415
 
                                           & GPG.Micalg_From_Filename(TDS_File)
416
 
                                           & """");
 
508
                                         & Externals.GPG.Micalg_From_Filename(TDS_File)
 
509
                                         & """");
417
510
                     -- Now the encrypt bit....
418
511
                     Rm_File(Tmpfile);
419
 
                     GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
 
512
                     Externals.GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
420
513
                                  & " --encrypt --armor "
421
514
                                  & ToStr(Config.general_options)
422
515
                                  & " "
442
535
                     Echo_Append("", Blk2);
443
536
                     Cat_Append(Tmpfile, Blk2);
444
537
                     -- Now we put them together.
445
 
                     Mail.Mimeconstruct2(Part1_Filename => Blk1,
 
538
                     Externals.Mail.Mimeconstruct2(Part1_Filename => Blk1,
446
539
                                         Part2_Filename => Blk2,
447
540
                                         Output_Filename => MC,
448
541
                                         Content_Type => "multipart/encrypted; protocol=""application/pgp-encrypted""");
472
565
                         Non_Pine  : in Boolean;
473
566
                         Mime      : in Boolean;
474
567
                         Mimefile  : in String;
475
 
                         Selection : in Send_Index) is
476
 
      Out_File       : String          := Temp_File_Name("out");
477
 
      DTBL_File      : String          := Temp_File_Name("dtbl");
478
 
      QP_File        : String          := Temp_File_Name("qp");
479
 
      TDS_File       : String          := Temp_File_Name("tds");
 
568
                         Selection : in Send_Index;
 
569
                         AL        : in Attachments.Attachment_List) is
 
570
      Out_File       : constant String   := Temp_File_Name("out");
 
571
      DTBL_File      : constant String   := Temp_File_Name("dtbl");
 
572
      QP_File        : constant String   := Temp_File_Name("qp");
 
573
      TDS_File       : constant String   := Temp_File_Name("tds");
480
574
      Mime_Selection : MIME_Send_Index;
481
575
   begin
482
576
      if Mime then
504
598
            Mail.Delete_Trailing_Blank_Lines(Tmpfile, DTBL_File);
505
599
            -- Then we turn it into quoted printable.
506
600
            -- Also turn it into DOS line endings.
507
 
            Mail.Mimeconstruct_Subpart(Infile       => DTBL_File,
 
601
            Externals.Mail.Mimeconstruct_Subpart(Infile       => DTBL_File,
508
602
                                       Outfile      => QP_File,
509
603
                                       Content_Type => "text/plain",
510
604
                                       Dos2UnixU    => True,
512
606
                                       Header       => "Content-Type: text/plain",
513
607
                                       Use_Encoding => True,
514
608
                                       Encoding     => "quoted-printable");
 
609
            -- Call out to attachments in case we have to modify QP_File.
 
610
            Attachments.Replace_Tmpfile(QP_File, AL);
515
611
            -- Then we clearsign it.
516
 
            GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
 
612
            Externals.GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
517
613
                         & " --detach-sign --armor --local-user "
518
614
                         & Value_Nonempty(Config.my_key)
519
615
                         & " "
533
629
               raise;
534
630
         end;
535
631
      else
 
632
         if Attachments.Count(AL) > 0 then
 
633
            Ada.Text_IO.Put_Line("WARNING: attachments not included in non-MIME emails!");
 
634
            Ada.Text_IO.New_Line;
 
635
         end if;
536
636
         begin
537
 
            GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
 
637
            Externals.GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
538
638
                         & " --clearsign --local-user "
539
639
                         & Value_Nonempty(Config.my_key)
540
640
                         & " "
556
656
      end if;
557
657
 
558
658
      begin
559
 
         if (not (Mime and then Mime_Selection = Multipart)) then
 
659
         if not (Mime and then Mime_Selection = Multipart) then
560
660
            if Selection = ClearsignPO then
561
661
               -- Rename the file appropriately.
562
662
               Mv_F(Out_File, Tmpfile & ".asc");
586
686
                                 -- This is the _really_ nasty one.
587
687
                                 -- At this point, we have QP_File, the quoted-printable, and TDS_File, then detached signature.
588
688
                  declare
589
 
                     Blk2   : String := Temp_File_Name("mp2");
590
 
                     MC     : String := Temp_File_Name("mc");
 
689
                     Blk2   : constant String := Temp_File_Name("mp2");
 
690
                     MC     : constant String := Temp_File_Name("mc");
591
691
                  begin
592
 
                     Mail.Mimeconstruct_Subpart(Infile       => TDS_File,
 
692
                     Externals.Mail.Mimeconstruct_Subpart(Infile       => TDS_File,
593
693
                                                Outfile      => Blk2,
594
694
                                                Content_Type => "application/pgp-signature",
595
695
                                                Dos2UnixU    => False,
596
696
                                                Use_Header   => False,
597
697
                                                Use_Encoding => False);
598
 
                     Mail.Mimeconstruct2(Part1_Filename  => QP_File,
 
698
                     Externals.Mail.Mimeconstruct2(Part1_Filename  => QP_File,
599
699
                                         Part2_Filename  => Blk2,
600
700
                                         Output_Filename => MC,
601
701
                                         Content_Type    => "multipart/signed; protocol=""application/pgp-signature""; micalg="""
602
 
                                           & GPG.Micalg_From_Filename(TDS_File)
603
 
                                           & """");
 
702
                                         & Externals.GPG.Micalg_From_Filename(TDS_File)
 
703
                                         & """");
604
704
                     -- Now we need to split these up.
605
705
                     Mail.Extract_Content_Type_From_Header(MC, Mimefile);
606
706
                     Mail.Extract_Body(MC, Tmpfile);
628
728
   procedure Detached_Sig  (Tmpfile   : in String) is
629
729
   begin
630
730
      -- Run GPG.
631
 
      GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
 
731
      Externals.GPG.GPG_Wrap(ToStr(Config.Gpg_Options)
632
732
                   & " --detach-sign --armor --local-user "
633
733
                   & Value_Nonempty(Config.my_key)
634
734
                   & " "
654
754
                              Mime      : in Boolean;
655
755
                              Mimefile  : in String) is
656
756
   begin
657
 
      if Mime then
658
 
         -- Splat the text into text/plain.
659
 
         -- We hope that Pine only ever sends us plain text....
660
 
         Echo_Out("Content-Type: text/plain", Mimefile);
661
 
      end if;
662
757
      Check_Send(Tmpfile, Non_Pine, Mime, Mimefile);
663
758
   exception
664
759
      when others =>
675
770
                   Mimefile   : in String    := "") is
676
771
      Send_Keys      : Keys.Key_List;
677
772
      Selection      : Send_Index;
 
773
      Originfile     : constant String := Temp_File_Name("origin");
 
774
      Hdrfile        : constant String := Temp_File_Name("hdr");
 
775
      Tmpfile2       : constant String := Temp_File_Name("tmp2");
 
776
      Fromfile       : constant String := Temp_File_Name("from");
 
777
      Fromfile2      : constant String := Temp_File_Name("from2");
 
778
      Alt_Sign       : UBS;
 
779
      AL             : Attachments.Attachment_List;
678
780
   begin
679
781
      Debug("+Send");
 
782
      -- Save the original input.
 
783
      Externals.Simple.Cat_Out(Tmpfile, Originfile);
 
784
      -- If Config.All_Headers is set, then split tmpfile into header
 
785
      --  and body.  But we'll copy the tmpfile into another tmp
 
786
      --  first, then put the body alone back in Tmpfile.
 
787
      if Config.All_Headers then
 
788
         Externals.Simple.Mv_F(Tmpfile, Tmpfile2);
 
789
         -- Make sure the line endings are correct.
 
790
         Externals.Simple.Dos2Unix(Tmpfile2);
 
791
         Externals.Mail.Extract_Header(Email_Filename => Tmpfile2,
 
792
                                       Target_Filename => Hdrfile);
 
793
         Externals.Mail.Extract_Body(Email_Filename => Tmpfile2,
 
794
                                     Target_Filename => Tmpfile);
 
795
      end if;
 
796
      -- If Config.Read_From is set, then parse the header to find the
 
797
      --  fromline and set my-key appropriately.  This implies that
 
798
      --  All_Headers was set, too.
 
799
      if Config.Read_From then
 
800
         Externals.Mail.Formail_Concat_Extract_InOut("From:",
 
801
                                                     Hdrfile,
 
802
                                                     Fromfile);
 
803
         Externals.Simple.Sed_InOut("s/^.*<//; s/>.*$//",
 
804
                                    Fromfile, Fromfile2);
 
805
         declare
 
806
            F : Ada.Text_IO.File_Type;
 
807
         begin
 
808
            Ada.Text_IO.Open(File => F,
 
809
                             Mode => Ada.Text_IO.In_File,
 
810
                             Name => Fromfile2);
 
811
            Alt_Sign := Unbounded_Get_Line(F);
 
812
            Ada.Text_IO.Close(F);
 
813
         end;
 
814
      end if;
680
815
      -- Sort out the send menus/msgs.
681
 
      Key_Preselect(Send_Keys, Recipients);
 
816
      Key_Preselect(Send_Keys, Recipients, ToStr(Alt_Sign));
 
817
      -- Initialise attachments.
 
818
      Attachments.Empty_Attachment_List(AL);
682
819
      -- Loop around doingstuff, now.
683
820
  Send_Loop:
684
821
      loop
685
 
         Ada.Text_IO.New_Line(2);
 
822
         Ada.Text_IO.New_Line(5);
 
823
         Ada.Text_IO.Put_Line("** Main send menu:");
 
824
         Ada.Text_IO.Put(Integer'Image(Keys.Count(Send_Keys))
 
825
                         & " key(s) in key list     ");
686
826
         if Non_Pine then
 
827
            Ada.Text_IO.New_Line;
687
828
            Selection := Send_Menu_NP;
688
829
         else
 
830
            Ada.Text_IO.Put_Line(Integer'Image(Attachments.Count(AL))
 
831
                                 & " attachment(s)");
689
832
            Selection := Send_Menu_Pine;
690
833
         end if;
691
834
         begin
699
842
                  Ada.Text_IO.Put_Line("my-key is empty; not selecting any keys for self");
700
843
                  else
701
844
                     Keys.Add_Keys_By_Fingerprint(Value_Nonempty(Config.My_Key),
702
 
                                                  Send_Keys);
 
845
                                                  Send_Keys,
 
846
                                                  Keys.Encrypter);
703
847
                  end if;
 
848
               when EditOwn => -- Change own key
 
849
                  Configuration.Edit_Own_Key;
 
850
               when ViewMail => -- View the input email.
 
851
                  Pager(Tmpfile);
 
852
               when EditMail => -- Edit the input email.
 
853
                  declare
 
854
                     Editor_Command : UBS;
 
855
                     Dummy          : Integer;
 
856
                     use Ada.Text_IO;
 
857
                     use type UBS;
 
858
                     pragma Unreferenced(Dummy);
 
859
                  begin
 
860
                     New_Line(1);
 
861
                     Put_Line("Edit input email:");
 
862
                     Editor_Command
 
863
                       := ToUBS(Readline.Get_String("Which editor command? (filename will be appended) "));
 
864
                     if ToStr(Editor_Command)'Length > 0 then
 
865
                        Dummy := Externals.Simple.System(Editor_Command & ToUBS(" " & Tmpfile));
 
866
                     end if;
 
867
                  end;
 
868
               when AttachEdit => -- Edit the attachment list.
 
869
                  Attachments.List(AL);
704
870
               when Encrypt | EncryptPO => -- Do GPG: encrypt
705
871
                  Encrypt(Tmpfile, Non_Pine,
706
872
                          Mime, Mimefile,
707
 
                          Send_Keys, Selection);
 
873
                          Send_Keys, Selection,
 
874
                          AL);
708
875
                  exit Send_Loop;
709
876
               when SignEncrypt | SignEncryptPO => -- Do GPG:  sign-encrypt
710
877
                  Sign_Encrypt(Tmpfile, Non_Pine,
711
878
                               Mime, Mimefile,
712
 
                               Send_Keys, Selection);
 
879
                               Send_Keys, Selection,
 
880
                               AL);
713
881
                  exit Send_Loop;
714
882
               when Clearsign | ClearSignPO => -- Do GPG:  clearsign
715
883
                  Clearsign(Tmpfile, Non_Pine,
716
884
                            Mime, Mimefile,
717
 
                            Selection);
 
885
                            Selection,
 
886
                            AL);
718
887
                  exit Send_Loop;
719
888
               when DetachSignPO => -- Do GPG:  create detached signature
720
889
                  Detached_Sig(Tmpfile);
726
895
               when NoGPG => -- Pass thu' unchanged.
727
896
                  Send_Unchanged(Tmpfile, Non_Pine, Mime, Mimefile);
728
897
                  exit Send_Loop;
 
898
               when Remote => -- Run remote connection
 
899
                              -- Restore original tmpfile from origin.
 
900
                  Externals.Simple.Cat_Out(Originfile, Tmpfile);
 
901
                  Remote_Mode.Send(Tmpfile, Mime, Mimefile, Recipients);
 
902
                  exit Send_Loop;
729
903
            end case;
730
904
         exception
731
905
            when Exit_Send_Loop =>