aboutsummaryrefslogtreecommitdiffstats
path: root/src/copy_client.rb
blob: b58a8bb7818aa472afe749bbd5ba8488d5bafc63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
=begin
This file is part of softSIM.

softSIM 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 3 of the License, or
(at your option) any later version.

softSIM 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 sofSIM.  If not, see <http://www.gnu.org/licenses/>.

Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
=end
# this class copies all files from the SIM to an xml file
require 'sap/client'
require 'lib/apdu'
require 'xml'

class Copy

  include APDU
  
  # to show the exact file being processed
  VERBOSE = false
  
  # create a Copy class
  # io : I/O to the SAP server
  def initialize(io)
    @client = Client.new(io)
    @client.start
    @client.connect
  end
  
  # tell APDU methods how to send
  def transmit_apdu(apdu)
    return @client.apdu(apdu)
  end
  
  # copy the content to a file
  def copy(file="sim.xml")
    @sim = XML::Node.new("sim")
    # get the ATR
    @sim["atr"] = @client.atr.to_hex
  end
  
  # get all the files in the current directory
  # does a recursive call
  # files are saved in the xml file
  # path is an arry of MF/DF
  # return xml node representing the folder and content
  def explore(path)

    puts "exploring #{path.flatten.to_hex_disp}" if VERBOSE
    # go to parent folder
    cd path[0..-2]
    # get info and select folder
    data = file(path[-1])
    return nil unless data
    node = file2node(data)

    # read all EF
    ef_id = EF_LEVELS[path.length]
    if ef_id then
      0x100.times do |i|
        id = [ef_id,i]
        begin
          data=file(id)
          next unless data # if file does not exist
          if VERBOSE then
            puts "found EF #{id.to_hex_disp}"
          elsif PROGRESS
            print "."
            STDOUT.flush
          end
          ef_node = file2node(data)
          node << ef_node
          @nb_files = 0 unless @nb_files
          @nb_files += 1
        rescue Exception => e
          puts "file error : #{e.to_s}"
          select_decode(select(id))
        end
      end
    end

    # read all DF
    df_id = DF_LEVELS[path.length]
    if df_id then
      # read all DF
      0x100.times do |i|
        id = [df_id,i]
        df_node = explore(path+[id])
        next unless df_node
        if VERBOSE then
          puts "found DF #{id.to_hex_disp}"
        elsif PROGRESS
          print ","
          STDOUT.flush
        end
        node << df_node
        @nb_directories = 0 unless @nb_directories
        @nb_directories += 1
      end
    end

    return node
  end
  
  # close the copy
  def close
    @client.disconnect
  end
end