tags:

views:

172

answers:

2

I am working on an open-source project, and part of it is licensed under a permissive license written by the original developer. The license is very short and not very detailed. Moreover, it doesn't appear to be compatible with the license the rest of the project uses.

I would like to ask the original developer to relicense the code under a different, open-source license. The problem is, I don't know what they need to do in order to achieve this. For example, I know that GPL usage guide states that each file needs to have a certain "header", referencing the license. Presumably other licenses (say, BSD) are "activated" similarly.

The source code is already in an SCM. Do I need to ask the person to modify every single file by himself, or can I somehow make it less work for him?

(In case you wonder why I want to avoid asking the person to commit the changes - it's because there is actually quite a bit of work. The project is Windows-only, and the SCM, Mercurial on BitBucket, requires SSH. Getting this to work on Windows by someone with no prior experience - even if they are a good developer - is anything but trivial.)

+5  A: 

Legally, all you need is the written permission of all original authors to publish a project under a different, non-compatible license (obviously, you don't need a permission if the license is compatible, or, in the trivial case) the same.

To protect the project with the new license, someone must replace all the license texts in all files. This can be done by anyone with the necessary permission (so it can be you or him or someone else).

Note: A project can be shared under as many licenses as necessary. So if you need to, you can create two clones where one is distributed in license A and a second copy which is distributed under license B. Use a tool that can search'n'replace chunks of text and only accept contributions when the authors allow you to share them under both licenses.

Aaron Digulla
As an aside, while you can publish code under one license in a project with a compatible license, you *can't* necessarily just relicense the code in question. e.g., if a GPL project includes individual files that are BSD, the obligations of the GPL do not apply to those files, and it isn't possible to simply relicense them as GPL without the original author's approval.
camccann
@camccann: You're mixing up two issues: 1. There is no rule that a project must have only one license. 2. If you want to share a project under more than one license, you need the approval of all the authors.
Aaron Digulla
No, I agree on that. I just wanted to clarify that "using code with a compatible license" is not the same thing as "relicensing that code". I could include BSD code in a larger GPL project without special permission, but I couldn't just change the actual license text on the BSD code to the GPL without the author's permission, any more than I could remove the copyright notice and claim the code as my own.
camccann
A: 

"The source code is already in an SCM. Do I need to ask the person to modify every single file by himself, or can I somehow make it less work for him?"

I actually had this same problem on a old project. I eventually broke down and just wrote a little tool to replace the licenses automatically. It took a file containing the license and injected the text into all the .cs files (it was a c# project) it found in a given directory and all of its subdirs after stripping them of their old one (it just looked for a beginning comment...it was quick and dirty).

Here it is, in c#. Distributed under MIT/X11 :

/*
  Copyright (c) 2009 Benjamin J. Setel

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
 */

using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System;


namespace Tools
{
    class LicenseInjector
    {
        public static void Main()
        {
            Console.WriteLine("Please enter the full root folder path (i.e. /home/usr/code/): ");
            string folder = Console.ReadLine();

            Console.WriteLine("Please enter full path to license data: ");
            string LicensePath = Console.ReadLine();

            FileStream ReadFile = new FileStream(LicensePath, FileMode.Open, FileAccess.Read);
            StreamReader sr = new StreamReader(ReadFile);
            string license = sr.ReadToEnd();
            sr.Close();
            ReadFile.Close();

            Recursion.RecursivePrepend(folder, license);

        }//Main
    }//LicenseInjector

    public static class Recursion
    {
        public static void RecursivePrepend(string folder, string license)
        {
            string [] Subdirs = Directory.GetDirectories(folder);
            if(Subdirs.Length != 0)
            {
                foreach(string s in Subdirs)
                    RecursivePrepend(s, license);
            }

            string[] files = PatternFind.DirPatternFinder(folder, ".cs");  
            foreach(string s in files)
                Prepend.Prepender(s, license);       

        }//RecursivePrepend()
    }//Recursion

    public static class PatternFind
    {
        public static string[] DirPatternFinder(string ToLook, string Pattern)
        {
            Regex r = new Regex(Pattern);
            string[] files = Directory.GetFiles(ToLook);
            List<string> results = new List<string>();

            for(int i = 0; i < files.Length; ++i)
            {
                    Match m = r.Match(files[i]);
                    if(m.Success)
                        results.Add(files[i]);
            } 
            return results.ToArray();
        }//DirPatternFinder()

        public static string PatternFinder(string Pattern1, string Pattern2)
        {
            Regex r = new Regex(Pattern1);
            Match m = r.Match(Pattern2);
            return m.ToString();
        }//PatternFinder()
    }//PatternFind
    public static class Prepend
    {
        public static void Prepender(string path, string ToPut)
        {
            FileStream ReadFile = new FileStream(path, FileMode.Open, FileAccess.Read);
            StreamReader sr = new StreamReader(ReadFile);
            string s = sr.ReadToEnd();
            sr.Close();
            ReadFile.Close();


            bool HasLicense = false;
            if(s.Substring(0, 2) == "/*")
                HasLicense = true;

            if(HasLicense) //If the file already has the license, we have to strip it out before adding it back in
                           // so that the file does not wind up with more than one copy.
            {
               int i = 1;
               string c = "(";
               while(c != "*/" && i < s.Length)
               {
                    c = s.Substring(i, 2);
                    ++i;
               }
               if(String.Compare("\n\n", s.Substring(i+1, 2)) == 0) //If there's already a newline after the license
               {
                    s = s.Remove(0, i+3);               
                }               
               else
               {             
                    s = s.Remove(0, i+2);
               }
            }


            FileStream WriteFile = new FileStream(path, FileMode.Open, FileAccess.Write);
            StreamWriter FileWriter = new StreamWriter(WriteFile);
            FileWriter.Write(ToPut);
            FileWriter.Write("\n");
            FileWriter.Write(s);
            FileWriter.Close();
            WriteFile.Close();
            return;            
        }//Prepender()
    }//Prepend
}//Tools
mothis