# Path: snap/osregistry.py
# class OSUtils:
# 
#     def null_file():
#         if OS.is_windows():
#             return 'nul'
#         else:
#             return '/dev/null'
#     null_file = staticmethod(null_file)
# 
#     def chown(cfile, uid=None, gid=None, username=None):
#         if os.path.isdir(cfile):
#             for f in os.listdir(cfile):
#                 OSUtils.chown(os.path.join(cfile, f),
#                               uid=uid, gid=gid, username=username)
#         
#         if OS.is_windows() and username != None:
#             # we don't actually change owner, just assign the user full permissions
#             null_file = open(OSUtils.null_file(), 'w')
#             popen = subprocess.Popen(["icacls", cfile, "/grant:r", username + ":F"],
#                                      stdout=null_file, stderr=null_file)
#             popen.wait()
#         elif OS.is_linux():
#             if (uid == None or gid == None) and username != None:
#                 import pwd
#                 user = pwd.getpwnam(username)
#                 uid = user.pw_uid
#                 gid = user.pw_gid
#             if uid != None and gid != None:
#                 os.chown(cfile, uid, gid)
#     chown = staticmethod(chown)
#     
#     def is_superuser():
#         if OS.is_windows():
#             # checks if snap is running under elevated privileges 
#             # Note this means more than running it as a user in the admin group. You must launch
#             # snaptool, the snap gui, or the development environment (cmd terminal, eclipse, or other)
#             # by right clicking the program and selecting 'run as administrator',
#             # even if your user is marked as an admin in the windows users control panel
#             
#             # XXX hacky way of doing this, but simplest way I could find outside of using the win32 api
#             try:
#                 file("C:\Windows\snap-check", "w")
#             except IOError, e:
#                 return False
#             
#             # We also check to see if the current user is in the admin group
#             user_name = os.environ["USERNAME"]            
#             process = subprocess.Popen(["net", "localgroup", "administrators"], stdout=subprocess.PIPE)
#             while True:
#                 line = process.stdout.readline()
#                 if not line:
#                     return False
#                 if re.match("^.*" + user_name + ".*$", line):
#                     return True
#         else:
#             return os.geteuid() == 0
#     is_superuser = staticmethod(is_superuser)
# 
# Path: snap/backends/services/dispatcher.py
# class Dispatcher(snap.snapshottarget.SnapshotTarget):
#     '''implements the snap! services target backend, dispatching to handlers '''
#     
#     def os_dispatcher():
#         '''helper to get the os specific dispatcher'''
#         if OS.is_windows():
#             import snap.backends.services.windowsdispatcher
#             return snap.backends.services.windowsdispatcher.WindowsDispatcher
#         else:
#             import snap.backends.services.linuxdispatcher
#             return snap.backends.services.linuxdispatcher.LinuxDispatcher
#     os_dispatcher = staticmethod(os_dispatcher)
# 
#     def load_service(self, service):
#         '''initialize the specified service adapter'''
# 
#         # Dynamically load the module
#         service_module_name = "snap.backends.services.adapters." + service
#         class_name = service.capitalize()
#         service_module = __import__(service_module_name, globals(), locals(), [class_name])
# 
#         # instantiate the backend class
#         service_class = getattr(service_module, class_name)
#         service_instance = service_class()
# 
#         return service_instance
# 
#     def backup(self, basedir, include=[], exclude=[]):
#         """run backup on each of the services included"""
#         services = []
# 
#         for service in include:
#             if snap.config.options.log_level_at_least('verbose'):
#                 snap.callback.snapcallback.message("Backing up service " + service);
#             service_instance = self.load_service(service)
#             # check if service is running / available on machine b4 backing up
#             if service_instance.is_available():
#                 sservice = service_instance.backup(basedir)
#                 services.append(Service(name=service))
# 
#         record = ServicesRecordFile(basedir + "/services.xml")
#         record.write(services)
# 
#     def restore(self, basedir):
#         """run restore on the snapfile"""
#         # if files record file isn't found, simply return
#         if not os.path.isfile(basedir + "/services.xml"):
#             return
# 
#         record = ServicesRecordFile(basedir + "/services.xml")
#         services = record.read()
# 
#         for sservice in services:
#             if snap.config.options.log_level_at_least('verbose'):
#                 snap.callback.snapcallback.message("Restoring service " + sservice.name);
#             service_instance = self.load_service(sservice.name)
#             # install the prerequisites if the services is not available
#             if not service_instance.is_available():
#                 service_instance.install_prereqs()
#             
#             if service_instance.is_available():
#                 service_instance.restore(basedir)
#                 
#             # if service is still not available, log this and skip it    
#             elif snap.config.options.log_level_at_least('normal'):
#                 snap.callback.snapcallback.message("Could not restore " + sservice.name + " service")


import re
import time
import subprocess
from snap.osregistry import OSUtils
from snap.backends.services.dispatcher import Dispatcher
# Methods to dispatch service backup/restore operations to specific handlers
#   on windows systems
#
# (C) Copyright 2011 Mo Morsi (mo@morsi.org)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, Version 3,
# as published by the Free Software Foundation
#
# 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.



class WindowsDispatcher(Dispatcher):
    '''implements the snap! services target backend, dispatching to handlers '''

    # XXX hack service may not yet be started/stopped after the sc command
    #  so we use a number of tries to wait for it
    SERVICE_QUERY_TRIES = 5
    SERVICE_QUERY_DELAY = 1

    def service_running(service):
        '''helper to return boolean indicating if the specified service is running'''
        for i in range(WindowsDispatcher.SERVICE_QUERY_TRIES):

# Path: snap/osregistry.py
# class OSUtils:
# 
#     def null_file():
#         if OS.is_windows():
#             return 'nul'
#         else:
#             return '/dev/null'
#     null_file = staticmethod(null_file)
# 
#     def chown(cfile, uid=None, gid=None, username=None):
#         if os.path.isdir(cfile):
#             for f in os.listdir(cfile):
#                 OSUtils.chown(os.path.join(cfile, f),
#                               uid=uid, gid=gid, username=username)
#         
#         if OS.is_windows() and username != None:
#             # we don't actually change owner, just assign the user full permissions
#             null_file = open(OSUtils.null_file(), 'w')
#             popen = subprocess.Popen(["icacls", cfile, "/grant:r", username + ":F"],
#                                      stdout=null_file, stderr=null_file)
#             popen.wait()
#         elif OS.is_linux():
#             if (uid == None or gid == None) and username != None:
#                 import pwd
#                 user = pwd.getpwnam(username)
#                 uid = user.pw_uid
#                 gid = user.pw_gid
#             if uid != None and gid != None:
#                 os.chown(cfile, uid, gid)
#     chown = staticmethod(chown)
#     
#     def is_superuser():
#         if OS.is_windows():
#             # checks if snap is running under elevated privileges 
#             # Note this means more than running it as a user in the admin group. You must launch
#             # snaptool, the snap gui, or the development environment (cmd terminal, eclipse, or other)
#             # by right clicking the program and selecting 'run as administrator',
#             # even if your user is marked as an admin in the windows users control panel
#             
#             # XXX hacky way of doing this, but simplest way I could find outside of using the win32 api
#             try:
#                 file("C:\Windows\snap-check", "w")
#             except IOError, e:
#                 return False
#             
#             # We also check to see if the current user is in the admin group
#             user_name = os.environ["USERNAME"]            
#             process = subprocess.Popen(["net", "localgroup", "administrators"], stdout=subprocess.PIPE)
#             while True:
#                 line = process.stdout.readline()
#                 if not line:
#                     return False
#                 if re.match("^.*" + user_name + ".*$", line):
#                     return True
#         else:
#             return os.geteuid() == 0
#     is_superuser = staticmethod(is_superuser)
# 
# Path: snap/backends/services/dispatcher.py
# class Dispatcher(snap.snapshottarget.SnapshotTarget):
#     '''implements the snap! services target backend, dispatching to handlers '''
#     
#     def os_dispatcher():
#         '''helper to get the os specific dispatcher'''
#         if OS.is_windows():
#             import snap.backends.services.windowsdispatcher
#             return snap.backends.services.windowsdispatcher.WindowsDispatcher
#         else:
#             import snap.backends.services.linuxdispatcher
#             return snap.backends.services.linuxdispatcher.LinuxDispatcher
#     os_dispatcher = staticmethod(os_dispatcher)
# 
#     def load_service(self, service):
#         '''initialize the specified service adapter'''
# 
#         # Dynamically load the module
#         service_module_name = "snap.backends.services.adapters." + service
#         class_name = service.capitalize()
#         service_module = __import__(service_module_name, globals(), locals(), [class_name])
# 
#         # instantiate the backend class
#         service_class = getattr(service_module, class_name)
#         service_instance = service_class()
# 
#         return service_instance
# 
#     def backup(self, basedir, include=[], exclude=[]):
#         """run backup on each of the services included"""
#         services = []
# 
#         for service in include:
#             if snap.config.options.log_level_at_least('verbose'):
#                 snap.callback.snapcallback.message("Backing up service " + service);
#             service_instance = self.load_service(service)
#             # check if service is running / available on machine b4 backing up
#             if service_instance.is_available():
#                 sservice = service_instance.backup(basedir)
#                 services.append(Service(name=service))
# 
#         record = ServicesRecordFile(basedir + "/services.xml")
#         record.write(services)
# 
#     def restore(self, basedir):
#         """run restore on the snapfile"""
#         # if files record file isn't found, simply return
#         if not os.path.isfile(basedir + "/services.xml"):
#             return
# 
#         record = ServicesRecordFile(basedir + "/services.xml")
#         services = record.read()
# 
#         for sservice in services:
#             if snap.config.options.log_level_at_least('verbose'):
#                 snap.callback.snapcallback.message("Restoring service " + sservice.name);
#             service_instance = self.load_service(sservice.name)
#             # install the prerequisites if the services is not available
#             if not service_instance.is_available():
#                 service_instance.install_prereqs()
#             
#             if service_instance.is_available():
#                 service_instance.restore(basedir)
#                 
#             # if service is still not available, log this and skip it    
#             elif snap.config.options.log_level_at_least('normal'):
#                 snap.callback.snapcallback.message("Could not restore " + sservice.name + " service")


# Path: snap/backends/services/windowsdispatcher.py
import re
import time
import subprocess
from snap.osregistry import OSUtils
from snap.backends.services.dispatcher import Dispatcher

# Methods to dispatch service backup/restore operations to specific handlers
#   on windows systems
#
# (C) Copyright 2011 Mo Morsi (mo@morsi.org)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, Version 3,
# as published by the Free Software Foundation
#
# 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.



class WindowsDispatcher(Dispatcher):
    '''implements the snap! services target backend, dispatching to handlers '''

    # XXX hack service may not yet be started/stopped after the sc command
    #  so we use a number of tries to wait for it
    SERVICE_QUERY_TRIES = 5
    SERVICE_QUERY_DELAY = 1

    def service_running(service):
        '''helper to return boolean indicating if the specified service is running'''
        for i in range(WindowsDispatcher.SERVICE_QUERY_TRIES):

            out = open(OSUtils.null_file(), 'w')