source: branches/samba-3.3.x/examples/scripts/shares/python/SambaConfig.py

Last change on this file was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 7.8 KB
Line 
1import sys, string, SambaParm
2from smbparm import parm_table
3
4######################################################################
5##
6## smb.conf parser class
7##
8## Copyright (C) Gerald Carter 2004.
9##
10## This program is free software; you can redistribute it and/or modify
11## it under the terms of the GNU General Public License as published by
12## the Free Software Foundation; either version 3 of the License, or
13## (at your option) any later version.
14##
15## This program is distributed in the hope that it will be useful,
16## but WITHOUT ANY WARRANTY; without even the implied warranty of
17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18## GNU General Public License for more details.
19##
20## You should have received a copy of the GNU General Public License
21## along with this program; if not, see <http://www.gnu.org/licenses/>.
22##
23######################################################################
24
25
26#####################################################################
27## multi line Samba comment
28class SambaComment:
29
30 def __init__( self, comment ):
31 self.comment = comment
32
33 def Dump( self, stream, whitespace=None ):
34 if not self.comment:
35 return
36 for line in self.comment:
37 if whitespace:
38 stream.write( whitespace )
39 stream.write( line )
40 stream.write( "\n" )
41
42
43#####################################################################
44## string smb.conf parms
45class SambaParameter :
46
47 ## indexs into the parm table tuples
48 DisplayName = 0
49 ObjectType = 1
50 DefaultValue = 2
51 Scope = 3
52
53 ## Stores a key into the parm_table and creates an
54 ## SambaParmXXX object to store the value
55 def __init__( self, name, value, comment=None ):
56 self.key = string.upper(string.strip(name))
57 self.comment = None
58 assert parm_table.has_key( self.key ), "Bad parameter name! [%s]" % name
59 self.parm = parm_table[self.key][self.ObjectType]( value )
60 if comment :
61 self.comment = SambaComment( comment )
62
63 #if not self.parm.valid:
64 # self.parm.SetValue( parm_table[self.key][self.DefaultValue] )
65
66 ## simple test for global or service parameter scope
67 def isGlobalParm( self ) :
68 return parm_table[self.key][Scope]
69
70 ## dump <the parameter to stdout
71 def Dump( self, stream ):
72 if self.comment:
73 self.comment.Dump( stream, "\t" )
74 stream.write( "\t%s = %s\n" % ( parm_table[self.key][self.DisplayName], self.parm.StringValue() ))
75
76
77#####################################################################
78## Class for parsing and modifying Smb.conf
79class SambaConf:
80
81 def __init__( self ):
82 self.services = {}
83 self.valid = True
84 self.services["GLOBAL"] = {}
85 self.services_order = []
86
87
88 ## always return a non-empty line of input or None
89 ## if we hit EOF
90 def ReadLine( self, stream ):
91 result = None
92 input_str = None
93
94 while True:
95 input_str = stream.readline()
96
97 ## Are we done with the file ?
98
99 if len(input_str) == 0:
100 return result
101
102 ## we need one line of valid input at least
103 ## continue around the loop again if the result
104 ## string is empty
105
106 input_str = string.strip( input_str )
107 if len(input_str) == 0:
108 if not result:
109 continue
110 else:
111 return result
112
113 ## we have > 1` character so setup the result
114 if not result:
115 result = ""
116
117 ## Check for comments -- terminated by \n -- no continuation
118
119 if input_str[0] == '#' or input_str[0] == ';' :
120 result = input_str
121 break
122
123 ## check for line continuation
124
125 if input_str[-1] == "\\" :
126 result += input_str[0:-1]
127 contine
128
129 ## otherwise we have a complete line
130 result += input_str
131 break
132
133 return result
134
135 ## convert the parameter name to a form suitable as a dictionary key
136 def NormalizeParamName( self, param ):
137 return string.upper( string.join(string.split(param), "") )
138
139 ## Open the file and parse it into a services dictionary
140 ## if possible
141 def ReadConfig( self, filename ):
142 self.filename = filename
143
144 try:
145 fconfig = open( filename, "r" )
146 except IOError:
147 self.valid = False
148 return
149
150 section_name = None
151
152 ## the most recent seen comment is stored as an array
153 current_comment = []
154
155 while True:
156
157 str = self.ReadLine( fconfig )
158 if not str:
159 break
160
161 ## Check for comments
162 if str[0] == '#' or str[0] == ';' :
163 current_comment.append( str )
164 continue
165
166 ## look for a next section name
167 if str[0]=='[' and str[-1]==']' :
168 section_name = str[1:-1]
169 self.AddService( section_name, current_comment )
170 current_comment = []
171 continue
172
173 str_list = string.split( str, "=" )
174
175 if len(str_list) != 2 :
176 continue
177
178 if not section_name :
179 print "parameter given without section name!"
180 break
181
182 param = self.NormalizeParamName( str_list[0] )
183 value = string.strip(str_list[1])
184
185 self.SetServiceOption( section_name, param, value, current_comment )
186 self.dirty = False
187
188 ## reset the comment strinf if we have one
189 current_comment = []
190
191 fconfig.close()
192
193 ## Add a parameter to the global section
194 def SetGlobalOption( self, param, value, comment=None ) :
195 self.SetServiceOption( "GLOBAL", param, value, comment )
196
197 ## Add a parameter to a specific service
198 def SetServiceOption( self, servicename, param, value, comment=None ) :
199 service = string.upper(servicename)
200 parm = self.NormalizeParamName(param)
201 self.services[service]['_order_'].append( parm )
202 self.services[service][parm] = SambaParameter( parm, value, comment )
203 self.dirty = True
204
205 ## remove a service from the config file
206 def DelService( self, servicename ) :
207 service = string.upper(servicename)
208 self.services[service] = None
209 self.dirty = True
210
211 ## remove a service from the config file
212 def AddService( self, servicename, comment=None ) :
213 service = string.upper(servicename)
214
215 self.services[service] = {}
216 self.services[service]['_order_'] = []
217
218 if ( comment ):
219 self.services[service]['_comment_'] = SambaComment( comment )
220
221 self.services_order.append( service )
222
223 self.dirty = True
224
225 def isService( self, servicename ):
226 service = string.upper(servicename)
227 return self.services.has_key( service )
228
229 ## dump a single service to stream
230 def DumpService( self, stream, servicename ):
231
232 ## comments first
233 if self.services[servicename].has_key( '_comment_' ):
234 self.services[servicename]['_comment_'].Dump( stream )
235
236 ## section header
237 stream.write( "[%s]\n" % (servicename) )
238
239 ## parameter = value
240 for parm in self.services[servicename]['_order_']:
241 self.services[servicename][parm].Dump(stream)
242
243 ## dump the config to stream
244 def Dump( self, stream ):
245 self.DumpService( stream, "GLOBAL" )
246 stream.write("\n")
247
248 for section in self.services_order:
249 ## already handled the global section
250 if section == "GLOBAL":
251 continue
252
253 ## check for deleted sections ##
254 if not self.services[section]:
255 continue
256
257 self.DumpService( stream, section )
258 stream.write( "\n" )
259
260 ## write out any changes to disk
261 def Flush( self ):
262 if not self.dirty:
263 return
264
265 try:
266 fconfig = open( self.filename, "w" )
267 except IOError:
268 sys.stderr.write( "ERROR!\n" )
269 return 1
270
271 self.Dump( fconfig )
272 fconfig.close()
273 return 0
274
275 def Services( self ):
276 service_list = []
277 for section in self.services.keys():
278 service_list.append( section )
279
280 return service_list
281
282 def NumServices( self ):
283 return len(self.Services())
284
285 def Write( self, filename ):
286 self.filename = filename
287 self.valid = True
288
289 if not self.dirty:
290 return
291
292 self.Flush()
293
294
295
296######################################################################
297## Unit tests
298######################################################################
299
300if __name__ == "__main__" :
301
302 x = SambaConf( )
303 x.ReadConfig( sys.argv[1] )
304 if not x.valid :
305 print "Bad file!"
306 sys.exit(1)
307
308 x.Dump( sys.stdout )
309
310
311
312## end of SambaConfig.py ######################################################
313###############################################################################
314
Note: See TracBrowser for help on using the repository browser.