|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /proc/22697/root/usr/share/system-config-samba/ |
Upload File : |
## sambaParser.py - the smb.conf file parser for system-config-samba
## Copyright (C) 2002, 2003 Red Hat, Inc.
## Copyright (C) 2002, 2003 Brent Fox <bfox@redhat.com>
## 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.
import os
import errno
import gtk
import sambaToken
import mainWindow
from sambaDefaults import global_keys
from sambaDefaults import section_keys
import sambaDefaults
##
## I18N
##
from rhpl.translate import _, N_
import rhpl.translate as translate
domain = 'system-config-samba'
translate.textdomain (domain)
class SambaSection:
sections = []
sections_dict = {}
def __init__ (self, name = None, prototype = False):
#print "SambaSection.__init__ (name = %s, prototype = %s)" % (name, prototype)
self.name = None
self.content = []
if not prototype and not self.set_name (name):
raise Error ("section %s already defined" % (name))
#print "SambaSection.sections:", SambaSection.sections
#print "SambaSection.sections_dict.keys ():", SambaSection.sections_dict.keys ()
def __str__ (self):
str = ""
if self.name:
str += "%s\n" % (self.name)
for token in self.content:
tokendata = token.getData ()
if tokendata:
# no default value
if tokendata.strip () == "None":
raise Exception ("refusing to write illegal token %s which would yield %s" % (token, tokendata))
else:
str += "%s" % (token.getData ())
return str
def __repr__ (self):
contentstrings = []
for token in self.content:
contentstrings.append (repr (token))
if self.name:
name = self.name
else:
name = "preambel"
return "<%s instance %s:\n%s\n>" % (self.__class__.__name__, name, "\n".join (contentstrings))
def delete (self):
#print "SambaSection.delete (%s)" % (self)
#print "sections before:", SambaSection.sections
#print "sections_dict before", SambaSection.sections
name = self.name.lower ()
if name and SambaSection.sections_dict.has_key (name):
#print " deleting from sections_dict"
del SambaSection.sections_dict[name]
if name in SambaSection.sections:
#print " deleting from sections"
SambaSection.sections.remove (name)
#print "sections after:", SambaSection.sections
#print "sections_dict after", SambaSection.sections
del (self)
def set_name (self, newname):
#print "SambaSection.set_name (%s)" % (newname)
if type (newname) == str:
if newname[0] != "[" and newname[-1] != "]":
raise Exception ("section name must be enclosed in brackets")
_newname = newname.lower ()
else:
_newname = newname
if not newname in SambaSection.sections:
if self.name:
SambaSection.sections[SambaSection.sections.index (self.name.lower ())] = newname.lower ()
del SambaSection.sections_dict[self.name.lower ()]
else:
SambaSection.sections.append (_newname)
self.name = newname
SambaSection.sections_dict[_newname] = self
#print "--SambaSection.sections:", SambaSection.sections
#print "--SambaSection.sections_dict.keys ():", SambaSection.sections_dict.keys ()
return True
return False
def fetchKey (self, name):
#print "SambaSection.fetchKey (%s)" % name
canonicalName = sambaToken.sambaTokenCanonicalNameValue (name, "")[0]
#print "\tcanonicalName", canonicalName
for token in self.content:
if token.type == sambaToken.SambaToken.SAMBA_TOKEN_KEYVAL:
if token.canonicalNameValue ()[0].lower () == canonicalName.lower ():
#print "\ttoken", token
return token
def keyExists (self, name):
if self.fetchKey (name):
return True
else:
return False
def getKey (self, name):
# returns canonical names and values
token = self.fetchKey (name)
if token:
(keyname, keyval, inverted) = token.canonicalNameValue ()
if inverted:
# revert to non inverted value
if keyval.lower () == "no":
keyval = "yes"
elif keyval.lower () == "yes":
keyval = "no"
return keyval
else:
# no explicit token found, assume default
return sambaDefaults.get_default (name)
def setKey (self, name, value, comment = None):
#print "SambaSection.setKey (name = '%s', value = '%s', comment = '%s')" % (name, value, comment)
#print "content before", self.content
token = self.fetchKey (name)
(name, value, inverted) = sambaToken.sambaTokenCanonicalNameValue (name, value)
if token:
self.content[self.content.index (token)] = sambaToken.SambaToken (sambaToken.SambaToken.SAMBA_TOKEN_KEYVAL, (name, value), token.comment)
else:
#print "\tcreating new token (%s/%s)" % (name, value)
token = sambaToken.SambaToken (sambaToken.SambaToken.SAMBA_TOKEN_KEYVAL, (name, value), comment)
# insert before eventual blank lines or comments (which may as well
# be for the next section)
index = len (self.content) - 1
while index >= 0 and (self.content[index].type == sambaToken.SambaToken.SAMBA_TOKEN_STRING or self.content[index].type == sambaToken.SambaToken.SAMBA_TOKEN_BLANKLINE):
index -= 1
self.content.insert (index + 1, token)
if index == len (self.content) - 1:
self.content.append (sambaToken.SambaToken(sambaToken.SambaToken.SAMBA_TOKEN_BLANKLINE, (stripped_line)))
#print "content after", self.content
def delKey (self, name):
#print "SambaSection.delKey (%s)" % name
#print "content before", self.content
token = self.fetchKey (name)
if token:
self.content.remove (token)
del token
#print "content after", self.content
def SambaSection_reset ():
SambaSection.sections = []
for name, section in SambaSection.sections_dict.iteritems ():
del SambaSection.sections_dict[name]
del section
SambaSection.sections_dict = {}
class SambaParser:
def __init__(self, parent):
self.ParentClass = parent
self.warnings = []
self.parseFile ()
def parseFile(self):
path = "/etc/samba/smb.conf"
lines = []
# reset SambaSection lists of sections
SambaSection_reset ()
self.sections = SambaSection.sections
self.sections_dict = SambaSection.sections_dict
if os.access(path, os.F_OK) == 0:
#If path doesn't exist, read template
path = "/usr/share/system-config-samba/smb.conf.template"
if os.access(path, os.R_OK) == 1:
#Check to see if we can read from the file
fd = open(path, 'r')
lines = fd.readlines()
fd.close()
else:
#The file exists, but we can't read it. Not much we can do now but quit.
dlg = gtk.MessageDialog(self.ParentClass.main_window, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK,
(_("Cannot read %s. Program will now exit." % path)))
dlg.set_position(gtk.WIN_POS_CENTER)
dlg.set_modal(True)
dlg.set_icon(mainWindow.iconPixbuf)
dlg.run()
dlg.destroy()
if gtk.__dict__.has_key ("main_quit"):
gtk.main_quit ()
else:
gtk.mainquit()
raise RuntimeError, (_("Cannot read %s. Program will now exit." % path))
if lines:
section = SambaSection (None)
lineno = 0
for line in lines:
lineno += 1
token = self.createToken (line, section)
if token:
if token.type == sambaToken.SambaToken.SAMBA_TOKEN_SECTION_HEADER:
section = SambaSection (token.value)
else:
#If the token is valid, then add it
section.content.append (token)
if token.unknown:
self.warnings.append ([lineno, token])
def createToken(self, line, section):
# eat trailing newline
if len (line) > 0 and line[-1] == '\n':
line = line[:-1]
stripped_line = line.strip ()
if stripped_line != "":
tmp = tuple(stripped_line)
else:
token = sambaToken.SambaToken(sambaToken.SambaToken.SAMBA_TOKEN_BLANKLINE, (line))
return token
if tmp:
if tmp[0] == "#" or tmp[0] == ";":
try:
commented_section = stripped_line[1:].strip ()
if commented_section[0] == '[' and commented_section[-1] == ']':
# we found a commented out section, treat commented out
# key value pairs as comments from now on until next
# section, e.g. for example sections
self.honour_default_value_comments = False
except IndexError:
pass
if tmp[0] == "#":
#The line begins with a "#"
token = sambaToken.SambaToken(sambaToken.SambaToken.SAMBA_TOKEN_STRING, (line))
return token
elif tmp[0] == ";":
# possibly a commented out default key value
name = None
try:
name, value = line.split ("=", 1)
name = name[1:].strip ()
value = value.strip ()
except ValueError:
pass
if name and self.honour_default_value_comments:
if not self.isDuplicateKey(name, section):
default_value = sambaDefaults.get_default (name)
try:
if value.lower () == default_value.lower ():
token = sambaToken.SambaToken(sambaToken.SambaToken.SAMBA_TOKEN_KEYVAL, (name, default_value))
return token
except AttributeError:
pass
else:
return None
# possibly just a comment
token = sambaToken.SambaToken(sambaToken.SambaToken.SAMBA_TOKEN_STRING, (line))
return token
elif tmp[0] == "[" and tmp[-1] == "]":
#The line contains a section header
token = sambaToken.SambaToken(sambaToken.SambaToken.SAMBA_TOKEN_SECTION_HEADER, (line), None)
# honour commented out key value pairs from now on
self.honour_default_value_comments = True
return token
else:
#The line isn't a section header and is probably a key/value line
comment_token = None
#See if there are any comments at the end of the line
if "#" in line:
data, comment = line.split ("#", 1)
comment_token = comment
line = data
else:
#There are no comments in the line
data = line
name, value = line.split ("=", 1)
name = name.strip ()
value = value.strip ()
if comment_token:
token = sambaToken.SambaToken(sambaToken.SambaToken.SAMBA_TOKEN_KEYVAL, (name, value), comment_token)
return token
else:
if not self.isDuplicateKey(name, section):
try:
token = sambaToken.SambaToken(sambaToken.SambaToken.SAMBA_TOKEN_KEYVAL, (name, value))
return token
except AttributeError:
token = sambaToken.SambaToken(sambaToken.SambaToken.SAMBA_TOKEN_KEYVAL, (name, value), accept_unknown = True)
return token
else:
#We've found a duplicate key, so return none. This keeps duplicates from being
#added to the list
return None
def writeFile(self):
path = "/etc/samba/smb.conf"
try:
oldmode = os.stat ("path")[0] & 07777
except OSError:
oldmode = 0644
if os.access (path, os.W_OK) == 1 and os.access (os.path.dirname (path), os.W_OK) == 1:
try:
os.unlink (path + ".new")
except OSError, e:
if e.errno != errno.ENOENT:
raise e
fd = open(path + ".new", 'w', oldmode)
else:
dlg = gtk.MessageDialog(self.ParentClass.main_window, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK,
(_("Cannot write to %s. Program will now exit." % path)))
dlg.set_modal(True)
dlg.set_icon(mainWindow.iconPixbuf)
dlg.set_position(gtk.WIN_POS_CENTER)
dlg.run()
dlg.destroy()
if gtk.__dict__.has_key ("main_quit"):
gtk.main_quit ()
else:
gtk.mainquit()
raise RuntimeError, (_("Cannot write to %s. Program will now exit." % path))
if fd:
for name in SambaSection.sections:
lines = str (self.getSection (name))
if lines:
fd.write(lines)
fd.close()
os.rename (path + ".new", path)
def printSections (self):
for name in self.getSections ():
print str (self.getSection (name))
def getSections (self):
return self.sections
def getSection (self, name):
#print "getSection (%s)" % name
return self.sections_dict[name]
def getShareHeaders(self):
header_list = self.getHeaders ()
share_header_list = []
for header in header_list:
if header != "[global]" and header != "[printers]" and header != "[homes]":
share_header_list.append (header)
return share_header_list
def getHeaders(self):
header_list = []
for name in self.sections:
if name:
header_list.append (name)
return header_list
def isDuplicateKey (self, name, section):
return section.keyExists (name)