Class: Yast::FileChangesClass

Inherits:
Module
  • Object
show all
Defined in:
library/system/src/modules/FileChanges.rb

Instance Method Summary collapse

Instance Method Details

#CheckFiles(files) ⇒ Boolean

Check files if any of them were changed Issue a question whether to continue if some were chaned

Parameters:

  • files (Array<String>)

    a list of files to check

Returns:

  • (Boolean)

    true if either none was changed or user agreed to continue



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'library/system/src/modules/FileChanges.rb', line 170

def CheckFiles(files)
  files = deep_copy(files)
  files = Builtins.filter(files) { |f| FileChanged(f) }

  return true unless Ops.greater_than(Builtins.size(files), 0)

  msg = n_(
    # Continue/Cancel question, %1 is a coma separated list of file names
    _("Files %1 have been changed manually.\nYaST might lose some of the changes"),
    # Continue/Cancel question, %1 is a file name
    _("File %1 has been changed manually.\nYaST might lose some of the changes.\n"),
    files.size
  )

  msg = Builtins.sformat(msg, Builtins.mergestring(files, ", "))
  popup_file = "/filechecks_non_verbose"

  stat = SCR.Read(path(".target.stat"), Ops.add(Directory.vardir, popup_file))
  return true unless stat == {}

  content = VBox(
    Label(msg),
    Left(CheckBox(Id(:disable), _("Do not show this message anymore"))),
    ButtonBox(
      PushButton(Id(:ok), Opt(:okButton), Label.ContinueButton),
      PushButton(Id(:cancel), Opt(:cancelButton), Label.CancelButton)
    )
  )
  UI.OpenDialog(content)
  UI.SetFocus(:ok)

  ret = UI.UserInput
  Builtins.y2milestone("ret = %1", ret)

  if ret == :ok && Convert.to_boolean(UI.QueryWidget(:disable, :Value))
    Builtins.y2milestone("Disabled checksum popups")
    SCR.Write(
      path(".target.string"),
      Ops.add(Directory.vardir, popup_file),
      ""
    )
  end
  UI.CloseDialog
  ret == :ok
end

#CheckNewCreatedFiles(files) ⇒ Boolean

Check if any of the possibly new created files is really new Issue a question whether to continue if such file was manually created

Parameters:

  • files (Array<String>)

    a list of files to check

Returns:

  • (Boolean)

    true if either none was changed or user agreed to continue



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'library/system/src/modules/FileChanges.rb', line 230

def CheckNewCreatedFiles(files)
  new_files = created_files(files)

  return true if new_files.empty?

  # TRANSLATORS: Continue/Cancel question, %s is a single file name or
  # a comma separated list of file names.
  msg = n_(
    "File %s has been created manually.\nYaST might lose this file.",
    "Files %s have been created manually.\nYaST might lose these files.",
    new_files.size
  ) % new_files.join(", ")

  popup_file = "/filechecks_non_verbose"
  popup_file_path = File.join(Directory.vardir, popup_file)

  return true if FileUtils.Exists(popup_file_path)

  content = VBox(
    Label(msg),
    Left(CheckBox(Id(:disable), Message.DoNotShowMessageAgain())),
    ButtonBox(
      PushButton(Id(:ok), Opt(:okButton), Label.ContinueButton()),
      PushButton(Id(:cancel), Opt(:cancelButton), Label.CancelButton())
    )
  )
  UI.OpenDialog(content)
  UI.SetFocus(:ok)
  ret = UI.UserInput
  Builtins.y2milestone("ret = %1", ret)
  if ret == :ok && UI.QueryWidget(:disable, :Value)
    Builtins.y2milestone("Disabled checksum popups")
    SCR.Write(
      path(".target.string"),
      popup_file_path,
      ""
    )
  end
  UI.CloseDialog
  ret == :ok
end

#ComputeFileChecksum(file) ⇒ String

Compute the checksum of a file

Parameters:

  • file (String)

    string the file to compute checksum of

Returns:



95
96
97
98
99
100
101
102
# File 'library/system/src/modules/FileChanges.rb', line 95

def ComputeFileChecksum(file)
  # See also FileUtils::MD5sum()
  cmd = Builtins.sformat("/usr/bin/md5sum %1", file.shellescape)
  out = Convert.to_map(SCR.Execute(path(".target.bash_output"), cmd))
  # NOTE: it also contains file name, but since it is only to be compared
  # it does not matter
  Ops.get_string(out, "stdout", "")
end

#created_files(files) ⇒ Array<String>

Files that are really new

Parameters:

  • files (Array<String>)

    candidate files that may be new

Returns:



220
221
222
# File 'library/system/src/modules/FileChanges.rb', line 220

def created_files(files)
  files - @file_checksums.keys
end

#FileChanged(file) ⇒ Boolean

Check if a file was modified externally (without YaST)

Parameters:

  • file (String)

    string boolean the file to check

Returns:

  • (Boolean)

    true if was changed externally



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'library/system/src/modules/FileChanges.rb', line 136

def FileChanged(file)
  # when generating AutoYaST configuration, they are not written back
  return false if Mode.config

  ReadSettings()
  ret = false
  if Builtins.haskey(@file_checksums, file)
    Builtins.y2milestone("Comparing file %1 to stored checksum", file)
    sum = ComputeFileChecksum(file)
    ret = sum != Ops.get(@file_checksums, file, "")
  else
    Builtins.y2milestone("Comparing file %1 to RPM database", file)
    ret = FileChangedFromPackage(file)
  end
  Builtins.y2milestone("File differs: %1", ret)
  ret
end

#FileChangedFromPackage(file) ⇒ Boolean

Check if file was modified compared to the one distributed with the RPM package

Parameters:

  • file (String)

    string the file to check

Returns:

  • (Boolean)

    true of was changed



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'library/system/src/modules/FileChanges.rb', line 108

def FileChangedFromPackage(file)
  # queryformat: no trailing newline!
  cmd = Builtins.sformat(
    "/usr/bin/rpm -qf %1 --qf %%{NAME}-%%{VERSION}-%%{RELEASE}",
    file.shellescape
  )
  out = Convert.to_map(SCR.Execute(path(".target.bash_output"), cmd))
  package = Ops.get_string(out, "stdout", "")
  Builtins.y2milestone("Package owning %1: %2", file, package)
  return false if package == "" || Ops.get_integer(out, "exit", -1) != 0

  cmd = Builtins.sformat("/usr/bin/rpm -V %1 |grep %2", package.shellescape, " #{file}$".shellescape)
  out = Convert.to_map(SCR.Execute(path(".target.bash_output"), cmd))
  changes = Ops.get_string(out, "stdout", "")
  Builtins.y2milestone("File possibly changed: %1", changes)
  lines = Builtins.splitstring(changes, "\n")
  changed = false
  Builtins.foreach(lines) do |line|
    changed = true if Builtins.regexpmatch(line, "^S")
    changed = true if Builtins.regexpmatch(line, "^..5")
    changed = true if Builtins.regexpmatch(line, "^.......T")
  end
  changed
end

#mainObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'library/system/src/modules/FileChanges.rb', line 50

def main
  Yast.import "UI"

  textdomain "base"

  Yast.import "Mode"
  Yast.import "Popup"
  Yast.import "Directory"
  Yast.import "Label"
  Yast.import "FileUtils"

  @data_file = "/var/lib/YaST2/file_checksums.ycp"

  @file_checksums = {}
end

#ReadSettingsObject

Read the data file containing file checksums



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'library/system/src/modules/FileChanges.rb', line 67

def ReadSettings
  if Ops.less_or_equal(
    Convert.to_integer(SCR.Read(path(".target.size"), @data_file)),
    0
  )
    @file_checksums = {}
    return
  end
  @file_checksums = Convert.convert(
    SCR.Read(path(".target.ycp"), @data_file),
    from: "any",
    to:   "map <string, string>"
  )
  @file_checksums = {} if @file_checksums.nil?

  nil
end

#StoreFileCheckSum(file) ⇒ Object

Store checksum of a file to the store

Parameters:

  • file (String)

    string filename to compute and store



156
157
158
159
160
161
162
163
# File 'library/system/src/modules/FileChanges.rb', line 156

def StoreFileCheckSum(file)
  ReadSettings()
  sum = ComputeFileChecksum(file)
  Ops.set(@file_checksums, file, sum)
  WriteSettings()

  nil
end

#WriteSettingsObject

Write the data file containing checksums



86
87
88
89
90
# File 'library/system/src/modules/FileChanges.rb', line 86

def WriteSettings
  SCR.Write(path(".target.ycp"), @data_file, @file_checksums)

  nil
end