mirror of
				https://github.com/Mikaela/Limnoria.git
				synced 2025-10-30 23:27:24 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			145 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python
 | |
| 
 | |
| ###
 | |
| # Copyright (c) 2005, Jeremiah Fincher
 | |
| # Copyright (c) 2009, James Vega
 | |
| # All rights reserved.
 | |
| #
 | |
| # Redistribution and use in source and binary forms, with or without
 | |
| # modification, are permitted provided that the following conditions are met:
 | |
| #
 | |
| #   * Redistributions of source code must retain the above copyright notice,
 | |
| #     this list of conditions, and the following disclaimer.
 | |
| #   * Redistributions in binary form must reproduce the above copyright notice,
 | |
| #     this list of conditions, and the following disclaimer in the
 | |
| #     documentation and/or other materials provided with the distribution.
 | |
| #   * Neither the name of the author of this software nor the name of
 | |
| #     contributors to this software may be used to endorse or promote products
 | |
| #     derived from this software without specific prior written consent.
 | |
| #
 | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | |
| # ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 | |
| # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | |
| # POSSIBILITY OF SUCH DAMAGE.
 | |
| ###
 | |
| 
 | |
| VERBOSE = False
 | |
| 
 | |
| def readPid(filename):
 | |
|     fd = file(filename)
 | |
|     try:
 | |
|         return int(fd.read().strip())
 | |
|     finally:
 | |
|         fd.close()
 | |
| 
 | |
| def isAlive(pid):
 | |
|     try:
 | |
|         os.kill(pid, 0)
 | |
|         return True
 | |
|     except OSError:
 | |
|         return False
 | |
| 
 | |
| def debug(s):
 | |
|     if VERBOSE:
 | |
|         if not s.endswith(os.linesep):
 | |
|             s += os.linesep
 | |
|         sys.stdout.write(s)
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     # XXX I wanted this for conf.version, but this will create directories. We
 | |
|     # really need to refactor conf so it either doesn't create directories, or
 | |
|     # so that static information (like the version) can be imported from
 | |
|     # somewhere else.
 | |
|     # import supybot.conf as conf
 | |
|     import os
 | |
|     import sys
 | |
|     import optparse
 | |
|     import subprocess
 | |
| 
 | |
|     parser = optparse.OptionParser(usage='Usage: %prog [options]')
 | |
|     parser.add_option('', '--verbose', action='store_true',
 | |
|                       help='Makes output verbose.')
 | |
|     parser.add_option('', '--botdir',
 | |
|                       help='Determines what directory the bot resides in and '
 | |
|                       'should be started from.')
 | |
|     parser.add_option('', '--pidfile',
 | |
|                       help='Determines what file to look in for the pid of '
 | |
|                       'the running bot.  This should be relative to the '
 | |
|                       'given bot directory. Note that for this to actually '
 | |
|                       'work, you have to make a matching entry in the '
 | |
|                       'supybot.pidFile config in the supybot registry.')
 | |
|     parser.add_option('', '--supybot', default='supybot',
 | |
|                       help='Determines where the supybot executable is '
 | |
|                       'located.  If not given, assumes that supybot is '
 | |
|                       'in $PATH.')
 | |
|     parser.add_option('', '--conffile',
 | |
|                       help='Determines what configuration file should be '
 | |
|                       'given to the supybot executable when (re)starting the '
 | |
|                       'bot.')
 | |
| 
 | |
|     (options, args) = parser.parse_args()
 | |
|     VERBOSE = options.verbose
 | |
| 
 | |
|     if args:
 | |
|         parser.error('Extra arguments given.')
 | |
|     if not options.botdir:
 | |
|         parser.error('No botdir given.')
 | |
|     if not options.pidfile:
 | |
|         parser.error('No pidfile given.')
 | |
|     if not options.conffile:
 | |
|         parser.error('No conffile given.')
 | |
| 
 | |
|     os.chdir(options.botdir)
 | |
|     os.system('touch %s' % options.pidfile)
 | |
| 
 | |
|     pid = None
 | |
|     try:
 | |
|         pid = readPid(options.pidfile)
 | |
|         debug('Found pidFile with proper pid contents of %s' % pid)
 | |
|     except ValueError, e:
 | |
|         foundBot = False
 | |
| 
 | |
|     if pid is not None:
 | |
|         foundBot = isAlive(pid)
 | |
|         if foundBot:
 | |
|             debug('Pid %s is alive and belongs to us.' % pid)
 | |
|         else:
 | |
|             debug('Pid %s is not the bot.' % pid)
 | |
| 
 | |
|     if not foundBot:
 | |
|         # First, we check if the pidfile is writable.  If not, supybot will just exit,
 | |
|         # so we go ahead and refuse to start it.
 | |
|         try:
 | |
|             file(options.pidfile, 'r+')
 | |
|         except EnvironmentError, e:
 | |
|             debug('pidfile (%s) is not writable: %s' % (options.pidfile, e))
 | |
|             sys.exit(-1)
 | |
|         debug('Bot not found, starting.')
 | |
|         home = os.environ['HOME']
 | |
|         inst = subprocess.Popen('sh', close_fds=True, stderr=subprocess.STDOUT,
 | |
|                                 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
 | |
|         for filename in ('.login', '.bash_profile', '.profile', '.bashrc'):
 | |
|             filename = os.path.join(home, filename)
 | |
|             if os.path.exists(filename):
 | |
|                 debug('Found %s, sourcing.' % filename)
 | |
|                 inst.stdin.write('source %s' % filename + os.linesep)
 | |
|         cmdline = '%s --daemon %s' % (options.supybot, options.conffile)
 | |
|         debug('Sending cmdline to sh process.')
 | |
|         inst.stdin.write(cmdline + os.linesep)
 | |
|         inst.stdin.close()
 | |
|         debug('Received from sh process: %r' % inst.stdout.read())
 | |
|         ret = inst.wait()
 | |
|         debug('Bot started, command line %r returned %s.' % (cmdline, ret))
 | |
|         sys.exit(ret)
 | |
|     else:
 | |
|         sys.exit(0)
 | |
| 
 | |
| # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
 | 
