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

Last change on this file was 1, checked in by Paul Smedley, 18 years ago

Initial code import

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