1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-10 13:57:47 +03:00
Gerald Carter 704862b687 r4855: add some smb.conf script for add/delete/change share and addprinter hooks
(This used to be commit 073592b7ad539138763c457fe58c1d82b2daa9c1)
2007-10-10 10:54:00 -05:00

316 lines
7.9 KiB
Python

import sys, string, SambaParm
from smbparm import parm_table
######################################################################
##
## smb.conf parser class
##
## Copyright (C) Gerald Carter 2004.
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
######################################################################
#####################################################################
## multi line Samba comment
class SambaComment:
def __init__( self, comment ):
self.comment = comment
def Dump( self, stream, whitespace=None ):
if not self.comment:
return
for line in self.comment:
if whitespace:
stream.write( whitespace )
stream.write( line )
stream.write( "\n" )
#####################################################################
## string smb.conf parms
class SambaParameter :
## indexs into the parm table tuples
DisplayName = 0
ObjectType = 1
DefaultValue = 2
Scope = 3
## Stores a key into the parm_table and creates an
## SambaParmXXX object to store the value
def __init__( self, name, value, comment=None ):
self.key = string.upper(string.strip(name))
self.comment = None
assert parm_table.has_key( self.key ), "Bad parameter name! [%s]" % name
self.parm = parm_table[self.key][self.ObjectType]( value )
if comment :
self.comment = SambaComment( comment )
#if not self.parm.valid:
# self.parm.SetValue( parm_table[self.key][self.DefaultValue] )
## simple test for global or service parameter scope
def isGlobalParm( self ) :
return parm_table[self.key][Scope]
## dump <the parameter to stdout
def Dump( self, stream ):
if self.comment:
self.comment.Dump( stream, "\t" )
stream.write( "\t%s = %s\n" % ( parm_table[self.key][self.DisplayName], self.parm.StringValue() ))
#####################################################################
## Class for parsing and modifying Smb.conf
class SambaConf:
def __init__( self ):
self.services = {}
self.valid = True
self.services["GLOBAL"] = {}
self.services_order = []
## always return a non-empty line of input or None
## if we hit EOF
def ReadLine( self, stream ):
result = None
input_str = None
while True:
input_str = stream.readline()
## Are we done with the file ?
if len(input_str) == 0:
return result
## we need one line of valid input at least
## continue around the loop again if the result
## string is empty
input_str = string.strip( input_str )
if len(input_str) == 0:
if not result:
continue
else:
return result
## we have > 1` character so setup the result
if not result:
result = ""
## Check for comments -- terminated by \n -- no continuation
if input_str[0] == '#' or input_str[0] == ';' :
result = input_str
break
## check for line continuation
if input_str[-1] == "\\" :
result += input_str[0:-1]
contine
## otherwise we have a complete line
result += input_str
break
return result
## convert the parameter name to a form suitable as a dictionary key
def NormalizeParamName( self, param ):
return string.upper( string.join(string.split(param), "") )
## Open the file and parse it into a services dictionary
## if possible
def ReadConfig( self, filename ):
self.filename = filename
try:
fconfig = open( filename, "r" )
except IOError:
self.valid = False
return
section_name = None
## the most recent seen comment is stored as an array
current_comment = []
while True:
str = self.ReadLine( fconfig )
if not str:
break
## Check for comments
if str[0] == '#' or str[0] == ';' :
current_comment.append( str )
continue
## look for a next section name
if str[0]=='[' and str[-1]==']' :
section_name = str[1:-1]
self.AddService( section_name, current_comment )
current_comment = []
continue
str_list = string.split( str, "=" )
if len(str_list) != 2 :
continue
if not section_name :
print "parameter given without section name!"
break
param = self.NormalizeParamName( str_list[0] )
value = string.strip(str_list[1])
self.SetServiceOption( section_name, param, value, current_comment )
self.dirty = False
## reset the comment strinf if we have one
current_comment = []
fconfig.close()
## Add a parameter to the global section
def SetGlobalOption( self, param, value, comment=None ) :
self.SetServiceOption( "GLOBAL", param, value, comment )
## Add a parameter to a specific service
def SetServiceOption( self, servicename, param, value, comment=None ) :
service = string.upper(servicename)
parm = self.NormalizeParamName(param)
self.services[service]['_order_'].append( parm )
self.services[service][parm] = SambaParameter( parm, value, comment )
self.dirty = True
## remove a service from the config file
def DelService( self, servicename ) :
service = string.upper(servicename)
self.services[service] = None
self.dirty = True
## remove a service from the config file
def AddService( self, servicename, comment=None ) :
service = string.upper(servicename)
self.services[service] = {}
self.services[service]['_order_'] = []
if ( comment ):
self.services[service]['_comment_'] = SambaComment( comment )
self.services_order.append( service )
self.dirty = True
def isService( self, servicename ):
service = string.upper(servicename)
return self.services.has_key( service )
## dump a single service to stream
def DumpService( self, stream, servicename ):
## comments first
if self.services[servicename].has_key( '_comment_' ):
self.services[servicename]['_comment_'].Dump( stream )
## section header
stream.write( "[%s]\n" % (servicename) )
## parameter = value
for parm in self.services[servicename]['_order_']:
self.services[servicename][parm].Dump(stream)
## dump the config to stream
def Dump( self, stream ):
self.DumpService( stream, "GLOBAL" )
stream.write("\n")
for section in self.services_order:
## already handled the global section
if section == "GLOBAL":
continue
## check for deleted sections ##
if not self.services[section]:
continue
self.DumpService( stream, section )
stream.write( "\n" )
## write out any changes to disk
def Flush( self ):
if not self.dirty:
return
try:
fconfig = open( self.filename, "w" )
except IOError:
sys.stderr.write( "ERROR!\n" )
return 1
self.Dump( fconfig )
fconfig.close()
return 0
def Services( self ):
service_list = []
for section in self.services.keys():
service_list.append( section )
return service_list
def NumServices( self ):
return len(self.Services())
def Write( self, filename ):
self.filename = filename
self.valid = True
if not self.dirty:
return
self.Flush()
######################################################################
## Unit tests
######################################################################
if __name__ == "__main__" :
x = SambaConf( )
x.ReadConfig( sys.argv[1] )
if not x.valid :
print "Bad file!"
sys.exit(1)
x.Dump( sys.stdout )
## end of SambaConfig.py ######################################################
###############################################################################