#! /usr/bin/python

# $Id$
# Copyright (c) 2003 Richard Offer. All rights reserved.


import sys
import getopt
import os
import string
import stat
import socket
import urlparse

import httplib

url="http://services.xmethods.net/soap/servlet/rpcrouter"

cmdletsdir=os.path.abspath('%s/../libexec/gforge' % (os.path.dirname(sys.argv[0])))
os.environ['PATH']=cmdletsdir+":"+os.environ['PATH']

def usage():
	print """
gforge: [gforge options] <command> [command options] 
  gforge options:
	  -v 
	  -u|-url URL of service
	  -h|-help"""
	sys.exit(0)


# need to sublass the system HTTPConenction since it doesn't make the file handler
# or descriptor available until there are replies to be read.
class myHTTPConnection(httplib.HTTPConnection):

	def __init__(self,host,port=None):
	
		httplib.HTTPConnection.__init__(self,host,port)
		
	def fileno(self):
	
		return self.sock.fileno()


if len(sys.argv) == 1:
	usage()
	
# the first argument that is not an option stops the parsing and treats
# the rest as options to the command
for o in xrange(1,len(sys.argv)):
	if sys.argv[o][0] == "-":
			if sys.argv[o] == "-v":
				print "$Revision$"
				sys.exit(0);
			elif sys.argv[o] == "-u" or sys.argv[o] == "-url" :
				url=sys.argv[o+1]
			elif sys.argv[o] == "-h" or sys.argv[o] == "-help" :
				usage()

	else:
		break

abscmd=sys.argv[o]

for f in string.split(os.environ['PATH'], ':'):
	if os.path.exists("%s/%s" % (f, sys.argv[o]) ):
		abscmd="%s/%s" % (f, sys.argv[o] )

args=[]
args.append("/bin/sh")
args.append("-c")
args.append("%s %s" % (abscmd, string.join(sys.argv[o+1:])))

(scheme, netloc, netpath, param, query, fragment)=urlparse.urlparse(url,"http")

host=netloc	
i = host.find(':')
if i >= 0:
	host = host[:i]

server=myHTTPConnection(netloc)
try:
	server.connect()
except socket.error, e:
	if e[0] == 7:
		print "%s: No such host." % host
	else:
		print e[1]	
	sys.exit(1)
	

server.putrequest('POST', netpath)
server.putheader('Host', host)
server.putheader('User-Agent', "gforge/3.0 ($Revision$)")

has_fork = hasattr(os, 'fork')

if has_fork:

	pid = os.fork()
	if pid != 0:
		# parent
		pid, status = os.waitpid(pid,0)
		if status:
			print "%s (parent): %s" % ( sys.argv[0], os.strerror(status))
	else:
		try:
			# child

			# replace the childs environment with a controlled one that includes 
			# some variables that are useful to the command.
			env={}
			env['SERVER_NAME']="%s" % host
			env['SCRIPT_NAME']="%s" % os.path.basename(netpath)
			env['PATH_INFO']="%s" % netpath
			env['QUERY_STRING']="%s" % query
			env['URL']="%s" % url
				
			os.dup2(server.fileno(),3)

			try:
				os.execvpe(args[0], args, env)
			except OSError, e:
				print "%s: %s (%s)" % ( sys.argv[0], os.strerror(e.errno), args[0])
	
		except OSError, e:
				print "%s (child): %s (%s)" % ( sys.argv[0], os.strerror(e.errno), args[0])
				sys.exit(127)
			
else:
	print "no fork"
		
	