#!/usr/pkg/bin/python """enforce my (John Comeau's) software licensing policies since most of my code is GPL'd, and I want Windows users to pay for software (so they will switch to an Open Source OS), this module will attempt to implement such.""" Copyright = """ jclicense.py - library of licensing functions Copyright (C) 2004 John Comeau 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. """ errormessage = "Not all needed libraries found, upgrade or check path" try: True # not defined in older Python releases except: True, False = 1, 0 try: import sys, os, types, re except exception: try: sys.stderr.write("%s\n" % errormessage) except: print errormessage raise exception # get name this program was called as self = os.path.split(sys.argv[0])[1] command = os.path.splitext(self)[0] # chop any suffix (extension) # now get name we gave it when we wrote it originalself = re.compile('[0-9A-Za-z]+').search(Copyright).group() # globals and routines that should be in every program # (yes, you could import them, but there are problems in that approach too) debugging = True # set to False for production release def DebugPrint(*whatever): global debugging if debugging: sys.stderr.write("%s\n" % repr(whatever)) def test(*args): "check if lowercase functions actually work as programs" print "this is a test. it is only a test. passed arguments follow..." DebugPrint(args) def GetString(*args): """helper routine for template program, extracts string argument depending on whether a routine was called directly from the command line (testing mode) or from elsewhere in the program, the argument may be a list rather than the expected string.""" while len(args) > 0 and (type(args) is types.ListType or \ type(args) is types.TupleType): args = args[0] return args # other globals, specific to this program try: from _winreg import * except: pass # it only matters on Windows anyway, and routines will trap error jclicense = """because of the ingenious (???) way this template code looks for what routine to execute, you always need to create a string variable, like this one, with the same name as the script (minus the .py extension, if any). As stated elsewhere, this cannot also be the name of a function within the program.""" def enforce(*args): Copyright # just make sure it's in the nametable before import try: import pwd sys.path.append(os.path.join(pwd.getpwuid(os.geteuid())[5], 'lib', 'python')) from com.jcomeau import gpl except: sys.stderr.write(""" This software is free and is licensed under the terms of the GNU Public License. Some or all of the files which explain this appear to be missing from your installation. Please contact the author of the software to correct this. """) raise if sys.platform == 'win32': windows_enforce(sys.argv[0].split(os.sep)[-1]) def windows_register(*args): program = GetString(args) try: software = OpenKey(HKEY_LOCAL_MACHINE, 'SOFTWARE') jcomeau = CreateKey(software, 'jcomeau.com') CreateKey(jcomeau, program).Close() jcomeau.Close() software.Close() except: raise Exception, 'Failed to register %s' % program def windows_deregister(*args): program = GetString(args) try: software = OpenKey(HKEY_LOCAL_MACHINE, 'SOFTWARE') jcomeau = OpenKey(software, 'jcomeau.com') DeleteKey(jcomeau, program) try: EnumKey(jcomeau, 0) except: jcomeau.Close() DeleteKey(software, 'jcomeau.com') try: jcomeau.Close() except: pass software.Close() except: raise Exception, 'Failed to deregister %s' % program def windows_enforce(program): try: software = OpenKey(HKEY_LOCAL_MACHINE, 'SOFTWARE') jcomeau = OpenKey(software, 'jcomeau.com') OpenKey(jcomeau, program).Close() jcomeau.Close() software.Close() except: sys.stderr.write(""" You are not authorized to use this program under Windows. The author is a proponent of Open Source operating systems, and having you pay for Windows software helps make Linux, FreeBSD, and other free OS's more attractive. It also takes more work to have programs install correctly under Windows. And the author needs to eat. Yes, it's possible to defeat this requirement with little effort, but don't. It's wrong, and if people find out you did it, it's possible you will be punished. If you believe you are seeing this message in error, contact the author to have it fixed: jc@jcomeau.com. Thank you. """) sys.exit(1) def main(): """main routine, only used for command-line testing let's say this program is called 'template.py' don't, by the way, name the program with the name of an included function if you're using this system... now if the program is invoked as './template.py', it will simply output a usage message. if invoked as './template.py MyFunction 1 2 3' we will attempt to call MyFunction(1, 2, 3) and show whatever is found if invoked as './template.py myfunction 1 2 3' we attempt to call myfunction(1, 2, 3) as a program and let it output whatever it decides likewise if you symlink like so: 'ln -s template.py myfunction' then invoke as './myfunction 1 2 3'""" program = sys.argv[0].split(os.sep)[-1] function = program.split('.')[0] # in case of .py extension try: if eval("type(%s)" % function) == types.FunctionType: if re.compile('^[a-z0-9]+$').match(function) != None: eval("%s(sys.argv[1:])" % function) else: try: print repr(eval("%s(sys.argv[1:])" % function)) except: sys.stderr.write("Error occurred testing routine %s(%s)\n" % ( function, repr(sys.argv[1:]))) raise else: raise NameError, '%s not a function' % function except NameError, instance: # first make sure this wasn't some other type of name error; if it was, barf #DebugPrint(instance.args) try: message = instance.args[0] except: message = 'unknown NameError' if message != '%s not a function' % function: raise NameError, message # called name didn't match anything defined if len(sys.argv) > 1: # hopefully the next arg is the function name we want sys.argv.pop(0) main() else: # called name didn't match any routine, so output usage message sys.stderr.write("""Usage: %s [OPTIONS] INPUT[...] or for more detailed help, read source or: pydoc %s """ % (self, self.split('.')[0])) if __name__ == '__main__': # if this program was imported by another, the above test will fail, # and this following code won't be used... main() else: # default action on import enforce()