LibLicense Documentation

0.5

A library for managing license metadata, in particular Creative Commons (CC) licensing information.

The idea of this library started out on the IRC channel, in a discussion on how to best help boost the community of software developers working with things related to CC - mostly the metadata format.

Basically, the idea is to write a portable C library that manages metadata for CC licenses, and a bunch of other licenses of interest to the community.

The library will produce licensing information based on the specifications of calling libraries and programs. In addition to generating text for specific licenses, it will also allow an application to enumerate which licenses are currently available and provide descriptive text for each license, and for license features. It should also provide an easy way to specify "verify at" URLs.

The benefit of this library is that applications linking to it can correctly offer licensing choices, and these choices can be transparently updated through package managers as license versions are updated. Human readable descriptions will also be internationalized, preferably using the same .po files used by the CC web site. Hence liblicense will take advantage of package updating and i18n systems to allow applications to always provide current and correct licensing choices and license text.

Part of the project is also to provide wrappers for the library for other languages, and to help external developers add metadata support to their projects. A good start will probably be to wrap the library for Python, and use it for ccpublisher.

We will also integrate a module system so that libraries can be used to embed and extract metadata in/from common formats.

As liblicense itself deals only with text strings, we can also make GUI libraries to provide dialogs which present these strings to the user in desktop or web applications. This layering ensures that such dialogs present consistent licensing choices.

Getting Started

Before you can call the library, it is mandatory to call the ll_init function. This is required to initialize internal databases and indexes.

Once you are done with the library, it is important to call the ll_stop function. This ensures that library resources are free()ed, but more importantly it ensures that caches that need to be have been flushed.

Discovering Available Licenses

To obtain a list of available licenses, you use the ll_get_licenses function. This returns a list of license URIs. This is the most important thing to understand about liblicense: it uses URIs to name everything, including license references.

For example, the Sampling Plus license URI looks like this: http://creativecommons.org/licenses/sampling+/1.0/

The license -a command uses code very similar to the following to list all of the available licenses:

   #include <liblicense.h>

   int
   main (int argc, char **argv)
   {
     ll_uri_t *licenses;
     int i;

     licenses = ll_get_licenses (NULL);
     i = 0;
     while (licenses[i] != NULL)
       {
         printf ("%s - %s\n", ll_get_first(ll_get_attribute(licenses[i], LL_NAME, false)), licenses[i]);
         i++;
       }
     ll_free_list (licenses);
     ll_stop ();
     return 0;
   }

The LL_NAME, attribute used to obtain a human-friendly license name. You can not pass a human-friendly name to any of the functions which expect a license URI, they simply will not work. You will have to use ll_get_licenses and walk the list to translate a human-friendly name into a license URI.

There is some logic behind all of this: the human-fiendly names are internationalized, and will be appropriately translated for the current locale. This means the human-fiendly names are not constant from one country to the next, but the license URIs are the same the world over.

Getting a License from a File

There is one thing you will want to do over and over again: read the license of a file. Once you have the license URI, you can query the license for the various rights you have. First things first: reading the license.

   #include <liblicense.h>
   #include <stdio.h>

   int
   main (int argc, char **argv)
   {
     ll_uri_t uri;

     ll_init ();
     uri = ll_read (argv[1], LL_LICENSE);
     if (uri == NULL)
       printf ("No license found\n");
     else
       printf ("%s\n", uri);
     ll_stop ();
     return 0;
   }

Some file formats are capable of holding a license within their other application data. For example, PNG files have optional text comment blocks, and the license data could be stored in them. For formats which cannot carry license data, is is also possible to a have a companion ".xmp" license file. The ll_read function checks for both possibilities.

Getting the Attributes of a License

Having read the license of a file, you want to know what conditions it imposes. There are several attributes liblicense exposes for this purpose. We have already seen the LL_NAME attribute. The others to use are LL_VERSION, ll_get_jurisdiction, LL_PERMITS, LL_REQUIRES, and LL_PROHIBITS.

   void
   print_license_info (ll_uri_t uri)
   {
     char **attrs, **attr;
     char *string;
     ll_version_t version;
     ll_juris_t juris;
     int i;

     printf ("License URI: %s\n", uri);

     string = ll_get_first(ll_get_attribute(uri, LL_NAME, false));
     printf ("Name: %s\n", string);
     free (string);

     version = ll_get_version (uri);
     printf ("Version: ");
     if (version)
       {
         for (i = 1; i <= version[0]; ++i)
           {
             if (i != 1)
               printf (".");
             printf ("%d", version[i]);
           }
         printf ("\n");
         free (version);
       }

     juris = ll_get_first(ll_get_attribute(uri, LL_JURISDICTION, false));
     if (juris)
       {
         string = ll_jurisdiction_name (juris);
         printf ("Jurisdiction: %s (%s)\n", string, juris);
         free (string);
         free (juris);
       }

     printf ("Rights:\n");

     attrs = ll_get_attribute(uri, LL_PERMITS, false);
     if (*attrs)
       {
         printf ("   Permits:\n");
         for (attr = attrs; *attr; ++attr)
           {
             printf ("      %s\n", *attr);
           }
       }
     ll_free_list (attrs);

     attrs = ll_get_attribute(uri, LL_REQUIRES, false);
     if (*attrs)
       {
         printf ("   Requires:\n");
         for (attr = attrs; *attr; ++attr)
           {
             printf ("      %s\n", *attr);
           }
       }
     ll_free_list (attrs);

     attrs = ll_get_attribute(uri, LL_PROHIBITS, false);
     if (*attrs)
       {
         printf ("   Prohibits:\n");
         for (attr = attrs; *attr; ++attr)
           {
             printf ("      %s\n", *attr);
           }
       }
     ll_free_list (attrs);
   }

When you actually compile and run this code, you will see that once again there are URIs for each of the rights, rather than simple strings.

The above code is a shortened version of the ll_license_print_info function, which you may prefer to use for consistency.

   #include <liblicense.h>
   #include <stdio.h>

   int
   main (int argc, char **argv)
   {
     ll_uri_t uri;

     ll_init ();
     uri = ll_read (argv[1], LL_LICENSE);
     if (uri == 0)
       printf ("No license found\n");
     else
       ll_license_print_info (uri);
     ll_stop ();
     return 0;

And, as you can see, the amount of code you need to write is much smaller, as well.

Examining other properties of a file

Despite its name, liblicense supports reading and writing other properties to a file. For example, you may want to store a link to a "web statement" that has more information on the file.

We have already seen the LL_LICENSE property you can pass to have ll_read(). The other supported properties are:

To use them, just pass them to ll_read() like you did with LL_LICENSE. Note that ll_write() also accepts these arguments in a similar way.

Discovering Supported Formats

The easiest way to see a list of supported formats is to use the -m option of the license(1) command which is part of the liblicense package. This program uses the liblicense API to obtain this information as follows:

   #include <liblicense.h>

   int
   main (int argc, char **argv)
   {
     ll_init ();
     ll_print_module_info ();
     ll_stop ();
     return 0;
   }

The results are printed on the standard output. (This section needs to be expanded for folks who need pick lists for GUIs._


Generated on Mon May 4 16:03:19 2009 for LibLicense by  doxygen 1.5.6