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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#!/usr/local/bin/ruby -w
# $Id$
module Blink
# this is a virtual base class for attributes
# attributes are self-contained building blocks for objects
# Attributes can currently only be used for comparing a virtual "should" value
# against the real state of the system. For instance, you could verify that
# a file's owner is what you want, but you could not create two file objects
# and use these methods to verify that they have the same owner
class Attribute
include Comparable
attr_accessor :value
attr_accessor :should
attr_accessor :object
#-----------------------------------
# every attribute class must tell us what it's name will be (as a symbol)
# this determines how we will refer to the attribute during usage
# e.g., the Owner attribute for Files might say its name is :owner;
# this means that we can say "file[:owner] = 'yayness'"
def Attribute.name
return @name
end
#-----------------------------------
#-----------------------------------
# we aren't actually comparing the attributes themselves, we're only
# comparing the "should" value with the "real" value
def insync?
Blink.debug "%s value is %s, should be %s" % [self,self.value,self.should]
self.value == self.should
end
#-----------------------------------
#-----------------------------------
def initialize(value)
@should = value
end
#-----------------------------------
#-----------------------------------
# DISABLED: we aren't comparing attributes, just attribute values
# are we in sync?
# this could be a comparison between two attributes on two objects,
# or a comparison between an object and the live system -- we'll
# let the object decide that, rather than us
#def <=>(other)
# if (self.value.respond_to?(:<=>))
# return self.value <=> other
# else
# fail TypeError.new("class #{self.value.class} does not respond to <=>")
# end
#end
#-----------------------------------
#-----------------------------------
# each attribute class must define the name() method
def name
return self.class.name
end
#-----------------------------------
#-----------------------------------
# retrieve the current state from the running system
def retrieve
raise "'retrieve' method was not overridden by %s" % self.class
end
#-----------------------------------
#-----------------------------------
def to_s
return @object.name.to_s + " -> " + self.name.to_s
end
#-----------------------------------
#-----------------------------------
# this class is for attributes that don't reflect on disk,
# like 'path' on files and 'name' on processes
# these are basically organizational attributes, not functional ones
#
# we provide stub methods, so that from the outside it looks like
# other attributes
#
# see objects.rb for how this is used
class Symbol
attr_reader :value
attr_reader :should
def initialize(symbol)
@symbol = symbol
end
def name
return @symbol.id2name
end
def retrieve
true
end
def insync?
true
end
def should=(value)
@value = value
@should = value
end
def sync
true
end
def value=(value)
@value = value
@should = value
end
end
end
# this class is supposed to be used to solve cases like file modes,
# where one command (stat) retrieves enough data to cover many attributes
# (e.g., setuid, setgid, world-read, etc.)
class MetaAttribute
include Comparable
attr_accessor :parent
attr_accessor :value
def <=>(other)
raise "'<=>' method was not overridden by %s" % self.class
end
end
end
|