Module: Pwnbus::Configdb::Files

Defined in:
lib/pwnbus/configdb/files.rb

Overview

Handling procedures for database files.

Class Method Summary collapse

Class Method Details

.can_access_path?(db_path, options) ⇒ Boolean

True if the file is accessible with the desired Configdb#open options.

Args:

db_path:: path to a database file
options:: same as for Configdb#new

Returns:

  • (Boolean)


74
75
76
77
# File 'lib/pwnbus/configdb/files.rb', line 74

def self.can_access_path?(db_path, options)
  db_stat = File.stat(db_path)
  options[:read] ? db_stat.readable? : db_stat.writable?
end

.crash_recovery_db_path(db_path, options) ⇒ Object

Peforms crash recovery on a database.

Args:

db_path:: path to a file containing a configuration database
options:: same as for Configdb#new

Returns the path to the recovered database. Most of the time, this will be



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/pwnbus/configdb/files.rb', line 28

def self.crash_recovery_db_path(db_path, options)
  new_db_path = db_path + '.new'
  if !File.exist?(db_path)
    # Crashed during rename.
    if options[:read]        
      # Writing to the .new copy completed. The copy will be locked.
      return new_db_path
    else
      # Do the rename.
      File.rename new_db_path, db_path
      return db_path
    end
  end
        
  if File.exist?(new_db_path) && !options[:read]
    # Crashed during new version write. The new version is probably corrupted.
    File.unlink new_db_path
  end
  db_path
end

.create_db(name, options) ⇒ Object

Creates a new database. The database must not exist.

Args:

name:: the database name
options:: same as for Configdb#open

Returns the path to the database file.



98
99
100
101
102
103
104
105
106
107
# File 'lib/pwnbus/configdb/files.rb', line 98

def self.create_db(name, options)
  db_path = File.join ensure_db_dir_exists, name + '.yml'
  File.open(db_path, 'w') do |f|
    f.flock File::LOCK_EX
    YAML.dump empty_db_data(name), f
  end
  permissions = public_db_name?(name) ? 0644 : 0600
  File.chmod permissions, db_path
  db_path
end

.db_dir_global_pathObject

Path to the computer-global databases.



147
148
149
# File 'lib/pwnbus/configdb/files.rb', line 147

def self.db_dir_global_path
  '/etc/pwnbus'
end

.db_dir_pathsObject

Paths to the directory containing database files for the current user.



133
134
135
136
137
138
139
# File 'lib/pwnbus/configdb/files.rb', line 133

def self.db_dir_paths
  if superuser?
    [db_dir_global_path]
  else
    [db_dir_user_path, db_dir_global_path]
  end
end

.db_dir_user_pathObject

Path to the directory holding per-user databases.



142
143
144
# File 'lib/pwnbus/configdb/files.rb', line 142

def self.db_dir_user_path
  File.expand_path('~/.pwnbus')
end

.empty_db_data(name) ⇒ Object

The contents of a empty (newly created) database.

Args:

name:: the database's name


113
114
115
# File 'lib/pwnbus/configdb/files.rb', line 113

def self.empty_db_data(name)
  {}
end

.ensure_db_dir_existsObject

Returns the the database directory. Creates it if it doesn’t exist.



123
124
125
126
127
128
129
130
# File 'lib/pwnbus/configdb/files.rb', line 123

def self.ensure_db_dir_exists
  dir_path = db_dir_paths.first
  unless File.exist? dir_path    
    FileUtils.mkdir_p dir_path
    File.chmod 0755, dir_path
  end
  dir_path
end

.find_db(name) ⇒ Object

The path to a database, or nil if the database doesn’t exist.

Args:

name:: the database name


83
84
85
86
87
88
89
# File 'lib/pwnbus/configdb/files.rb', line 83

def self.find_db(name)
  db_dir_paths.each do |dir_path|
    db_path = File.join dir_path, name + '.yml'
    return db_path if File.exist?(db_path) || File.exist?(db_path + '.new')
  end
  nil
end

.open_db(db_path, options) ⇒ Object

Opens the file for a configuration database. The file must exist.

Returns a File instance.



14
15
16
17
18
19
# File 'lib/pwnbus/configdb/files.rb', line 14

def self.open_db(db_path, options)
  db_path = crash_recovery_db_path db_path, options
  f = File.open db_path, 'r'
  f.flock options[:read] ? File::LOCK_SH : File::LOCK_EX
  f
end

.public_db_name?(name) ⇒ Boolean

Databases whose names start with . are public (global-read, author-write).

Returns:

  • (Boolean)


118
119
120
# File 'lib/pwnbus/configdb/files.rb', line 118

def self.public_db_name?(name)
  name[0] != ?.
end

.superuser?Boolean

True if running as the root user.

Returns:

  • (Boolean)


152
153
154
# File 'lib/pwnbus/configdb/files.rb', line 152

def self.superuser?
  Process.euid == 0
end

.write_db(db_path, options) ⇒ Object

Writes a new database version atomically.

Args:

db_path:: path to a file containing a configuration database
options:: same as for Configdb#new

Returns db_path.



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/pwnbus/configdb/files.rb', line 56

def self.write_db(db_path, options)
  new_db_path = db_path + '.new'
  File.open(new_db_path, 'w') do |f|
    f.flock File::LOCK_EX
    permissions = public_db_name?(File.basename(db_path)) ? 0644 : 0600
    File.chmod permissions, new_db_path      
    yield f
  end
  File.unlink db_path
  File.rename new_db_path, db_path
  db_path
end