(************************************************************************) (* This file is part of SKS. SKS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) (***********************************************************************) (** Basic key-related operations *) open StdLabels open MoreLabels open Packet module Set = PSet.Set exception Bug of string (*************************************************************) let rec pos_next_rec ps partial = match SStream.peek ps with None -> Some (List.rev partial) | Some (_,packet) -> if packet.packet_type = Public_Key_Packet then Some (List.rev partial) else ( SStream.junk ps; pos_next_rec ps (packet::partial) ) let pos_next ps = match SStream.peek ps with None -> None | Some (pos,pack) -> SStream.junk ps; match pos_next_rec ps [pack] with Some key -> Some (pos,key) | None -> None let pos_get ps = match pos_next ps with None -> raise Not_found | Some key -> key let pos_next_of_channel cin = let ps = SStream.make (fun () -> (try Some (ParsePGP.offset_read_packet cin) with End_of_file -> None)) in (fun () -> pos_next ps) let pos_get_of_channel cin = let ps = SStream.make (fun () -> (try Some (ParsePGP.offset_read_packet cin) with End_of_file -> None)) in (fun () -> pos_get ps) (*************************************************************) let rec next_rec ps partial = match SStream.peek ps with None -> Some (List.rev partial) | Some packet -> if packet.packet_type = Public_Key_Packet then Some (List.rev partial) else ( SStream.junk ps; next_rec ps (packet::partial) ) let next ps = match SStream.peek ps with None -> None | Some pack -> SStream.junk ps; next_rec ps [pack] let get ps = match next ps with None -> raise Not_found | Some key -> key let next_of_channel cin = let ps = SStream.make (fun () -> (try Some (ParsePGP.read_packet cin) with End_of_file -> None)) in (fun () -> next ps) let get_of_channel cin = let ps = SStream.make (fun () -> (try Some (ParsePGP.read_packet cin) with End_of_file -> None)) in (fun () -> get ps) (*************************************************************) let rec get_ids key = match key with [] -> [] | packet::tail -> if packet.packet_type = User_ID_Packet then packet.packet_body::(get_ids tail) else get_ids tail (*************************************************************) let write key cout = List.iter ~f:(fun packet -> write_packet packet cout) key let to_string key = let cout = Channel.new_buffer_outc 0 in write key cout; cout#contents let of_string keystr = let cin = new Channel.string_in_channel keystr 0 in match next_of_channel cin () with None -> raise (Bug "key should have appeared") | Some key -> key let of_string_multiple keystr = let cin = new Channel.string_in_channel keystr 0 in let next = next_of_channel cin in let rec loop () = match next () with None -> [] | Some key -> key::(loop ()) in loop () let to_string_multiple keys = let cout = Channel.new_buffer_outc 0 in List.iter ~f:(fun key -> write key cout) keys; cout#contents (*************************************************************) let to_words key = let userids = get_ids key in let wordsets = List.map ~f:Utils.extract_word_set userids in Set.elements (List.fold_left ~init:Set.empty ~f:Set.union wordsets)