libmobi
C library for handling MOBI format ebook documents
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Data Structures | Macros | Typedefs | Enumerations | Functions
mobi.h File Reference

Libmobi main header file. More...

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>

Go to the source code of this file.

Data Structures

struct  MOBIFileMeta
 Metadata of file types. More...
 
struct  MOBIPdbHeader
 Header of palmdoc database file. More...
 
struct  MOBIPdbRecord
 Metadata and data of a record. All records form a linked list. More...
 
struct  MOBIExthHeader
 Metadata and data of a EXTH record. All records form a linked list. More...
 
struct  MOBIExthMeta
 EXTH tag metadata. More...
 
struct  MOBIRecord0Header
 Header of the Record 0 meta-record. More...
 
struct  MOBIMobiHeader
 MOBI header which follows Record 0 header. More...
 
struct  MOBIData
 Main structure holding all metadata and unparsed records data. More...
 
struct  MOBIFdst
 Parsed FDST record. More...
 
struct  MOBIIndexTag
 Parsed tag for an index entry. More...
 
struct  MOBIIndexEntry
 Parsed INDX index entry. More...
 
struct  MOBIIndx
 Parsed INDX record. More...
 
struct  MOBIPart
 Reconstructed source file. More...
 
struct  MOBIRawml
 Main structure containing reconstructed source parts and indices. More...
 

Macros

#define MOBI_EXPORT   __attribute__((__visibility__("default")))
 Visibility attributes for symbol export.
 
#define MOBI_NOTSET   UINT32_MAX
 Usually 32-bit values in mobi records with value 0xffffffff mean "value not set".
 

Typedefs

typedef struct MOBIPdbRecord MOBIPdbRecord
 Metadata and data of a record. All records form a linked list.
 
typedef struct MOBIExthHeader MOBIExthHeader
 Metadata and data of a EXTH record. All records form a linked list.
 
typedef struct MOBIData MOBIData
 Main structure holding all metadata and unparsed records data. More...
 
typedef struct MOBIPart MOBIPart
 Reconstructed source file. More...
 

Enumerations

enum  MOBI_RET {
  MOBI_SUCCESS = 0, MOBI_ERROR = 1, MOBI_PARAM_ERR = 2, MOBI_DATA_CORRUPT = 3,
  MOBI_FILE_NOT_FOUND = 4, MOBI_FILE_ENCRYPTED = 5, MOBI_FILE_UNSUPPORTED = 6, MOBI_MALLOC_FAILED = 7,
  MOBI_INIT_FAILED = 8, MOBI_BUFFER_END = 9, MOBI_XML_ERR = 10, MOBI_DRM_PIDINV = 11,
  MOBI_DRM_KEYNOTFOUND = 12, MOBI_DRM_UNSUPPORTED = 13, MOBI_WRITE_FAILED = 14
}
 Error codes returned by functions. More...
 
enum  MOBIExthType { EXTH_NUMERIC = 0, EXTH_STRING = 1, EXTH_BINARY = 2 }
 EXTH record types.
 
enum  MOBIExthTag {
  EXTH_DRMSERVER = 1, EXTH_DRMCOMMERCE = 2, EXTH_DRMEBOOKBASE = 3, EXTH_TITLE = 99,
  EXTH_AUTHOR = 100, EXTH_PUBLISHER = 101, EXTH_IMPRINT = 102, EXTH_DESCRIPTION = 103,
  EXTH_ISBN = 104, EXTH_SUBJECT = 105, EXTH_PUBLISHINGDATE = 106, EXTH_REVIEW = 107,
  EXTH_CONTRIBUTOR = 108, EXTH_RIGHTS = 109, EXTH_SUBJECTCODE = 110, EXTH_TYPE = 111,
  EXTH_SOURCE = 112, EXTH_ASIN = 113, EXTH_VERSION = 114, EXTH_SAMPLE = 115,
  EXTH_STARTREADING = 116, EXTH_ADULT = 117, EXTH_PRICE = 118, EXTH_CURRENCY = 119,
  EXTH_KF8BOUNDARY = 121, EXTH_FIXEDLAYOUT = 122, EXTH_BOOKTYPE = 123, EXTH_ORIENTATIONLOCK = 124,
  EXTH_COUNTRESOURCES = 125, EXTH_ORIGRESOLUTION = 126, EXTH_ZEROGUTTER = 127, EXTH_ZEROMARGIN = 128,
  EXTH_KF8COVERURI = 129, EXTH_RESCOFFSET = 131, EXTH_REGIONMAGNI = 132, EXTH_DICTNAME = 200,
  EXTH_COVEROFFSET = 201, EXTH_THUMBOFFSET = 202, EXTH_HASFAKECOVER = 203, EXTH_CREATORSOFT = 204,
  EXTH_CREATORMAJOR = 205, EXTH_CREATORMINOR = 206, EXTH_CREATORBUILD = 207, EXTH_WATERMARK = 208,
  EXTH_TAMPERKEYS = 209, EXTH_FONTSIGNATURE = 300, EXTH_CLIPPINGLIMIT = 401, EXTH_PUBLISHERLIMIT = 402,
  EXTH_UNK403 = 403, EXTH_TTSDISABLE = 404, EXTH_UNK405 = 405, EXTH_RENTAL = 406,
  EXTH_UNK407 = 407, EXTH_UNK450 = 450, EXTH_UNK451 = 451, EXTH_UNK452 = 452,
  EXTH_UNK453 = 453, EXTH_DOCTYPE = 501, EXTH_LASTUPDATE = 502, EXTH_UPDATEDTITLE = 503,
  EXTH_ASIN504 = 504, EXTH_TITLEFILEAS = 508, EXTH_CREATORFILEAS = 517, EXTH_PUBLISHERFILEAS = 522,
  EXTH_LANGUAGE = 524, EXTH_ALIGNMENT = 525, EXTH_CREATORSTRING = 526, EXTH_PAGEDIR = 527,
  EXTH_OVERRIDEFONTS = 528, EXTH_SORCEDESC = 529, EXTH_DICTLANGIN = 531, EXTH_DICTLANGOUT = 532,
  EXTH_INPUTSOURCE = 534, EXTH_CREATORBUILDREV = 535
}
 EXTH record tags. More...
 
enum  MOBIFiletype {
  T_UNKNOWN, T_HTML, T_CSS, T_SVG,
  T_OPF, T_NCX, T_JPG, T_GIF,
  T_PNG, T_BMP, T_OTF, T_TTF,
  T_MP3, T_MPG, T_PDF, T_FONT,
  T_AUDIO, T_VIDEO, T_BREAK
}
 Types of files stored in database records. More...
 
enum  MOBIEncoding { MOBI_CP1252 = 1252, MOBI_UTF8 = 65001, MOBI_UTF16 = 65002 }
 

Functions

MOBI_EXPORT const char * mobi_version (void)
 Get libmobi version. More...
 
MOBI_EXPORT MOBI_RET mobi_load_file (MOBIData *m, FILE *file)
 Read MOBI document from file into MOBIData structure. More...
 
MOBI_EXPORT MOBI_RET mobi_load_filename (MOBIData *m, const char *path)
 Read MOBI document from a path into MOBIData structure. More...
 
MOBI_EXPORT MOBIDatamobi_init (void)
 Initializer for MOBIData structure. More...
 
MOBI_EXPORT void mobi_free (MOBIData *m)
 Free MOBIData structure and all its children. More...
 
MOBI_EXPORT MOBI_RET mobi_parse_kf7 (MOBIData *m)
 Loader will parse KF7 part of hybrid file. More...
 
MOBI_EXPORT MOBI_RET mobi_parse_kf8 (MOBIData *m)
 Loader will parse KF8 part of hybrid file. More...
 
MOBI_EXPORT MOBI_RET mobi_parse_rawml (MOBIRawml *rawml, const MOBIData *m)
 Parse raw records into html flow parts, markup parts, resources and indices. More...
 
MOBI_EXPORT MOBI_RET mobi_parse_rawml_opt (MOBIRawml *rawml, const MOBIData *m, bool parse_toc, bool parse_dict, bool reconstruct)
 Parse raw records into html flow parts, markup parts, resources and indices. Individual stages of the parsing may be turned on/off. More...
 
MOBI_EXPORT MOBI_RET mobi_get_rawml (const MOBIData *m, char *text, size_t *len)
 Decompress text to a text buffer. More...
 
MOBI_EXPORT MOBI_RET mobi_dump_rawml (const MOBIData *m, FILE *file)
 Decompress text record to an open file descriptor. More...
 
MOBI_EXPORT MOBI_RET mobi_decode_font_resource (unsigned char **decoded_font, size_t *decoded_size, MOBIPart *part)
 Deobfuscator and decompressor for font resources. More...
 
MOBI_EXPORT MOBI_RET mobi_decode_audio_resource (unsigned char **decoded_resource, size_t *decoded_size, MOBIPart *part)
 Decode audio resource. More...
 
MOBI_EXPORT MOBI_RET mobi_decode_video_resource (unsigned char **decoded_resource, size_t *decoded_size, MOBIPart *part)
 Decode video resource. More...
 
MOBI_EXPORT MOBI_RET mobi_get_embedded_source (unsigned char **data, size_t *size, const MOBIData *m)
 Get embedded source archive. More...
 
MOBI_EXPORT MOBI_RET mobi_get_embedded_log (unsigned char **data, size_t *size, const MOBIData *m)
 Get embedded conversion log. More...
 
MOBI_EXPORT MOBIPdbRecordmobi_get_record_by_uid (const MOBIData *m, const size_t uid)
 Get palm database record with given unique id. More...
 
MOBI_EXPORT MOBIPdbRecordmobi_get_record_by_seqnumber (const MOBIData *m, const size_t uid)
 Get palm database record with given sequential number (first record has number 0) More...
 
MOBI_EXPORT MOBIPartmobi_get_flow_by_uid (const MOBIRawml *rawml, const size_t uid)
 Get rawml->flow MOBIPart part by uid. More...
 
MOBI_EXPORT MOBIPartmobi_get_flow_by_fid (const MOBIRawml *rawml, const char *fid)
 Find flow part by flow id (fid) from kindle:flow:fid link. Flow fid is base32 encoded part uid. More...
 
MOBI_EXPORT MOBIPartmobi_get_resource_by_uid (const MOBIRawml *rawml, const size_t uid)
 Get MOBIPart resource record with given unique id. More...
 
MOBI_EXPORT MOBIPartmobi_get_resource_by_fid (const MOBIRawml *rawml, const char *fid)
 Find resource by flow id (fid) from kindle:embed:fid link. Flow fid is base32 encoded part uid. More...
 
MOBI_EXPORT MOBIPartmobi_get_part_by_uid (const MOBIRawml *rawml, const size_t uid)
 Get rawml->markup MOBIPart part by uid. More...
 
MOBI_EXPORT MOBI_RET mobi_get_fullname (const MOBIData *m, char *fullname, const size_t len)
 Get ebook full name stored in Record 0 at offset given in MOBI header. More...
 
MOBI_EXPORT size_t mobi_get_first_resource_record (const MOBIData *m)
 Get sequential number of first resource record (image/font etc) More...
 
MOBI_EXPORT size_t mobi_get_text_maxsize (const MOBIData *m)
 Get maximal size of all uncompressed text records. More...
 
MOBI_EXPORT uint16_t mobi_get_textrecord_maxsize (const MOBIData *m)
 Get maximal size of uncompressed text record. More...
 
MOBI_EXPORT size_t mobi_get_kf8offset (const MOBIData *m)
 Get offset of KF8 Boundary for KF7/KF8 hybrid file cached in MOBIData structure. More...
 
MOBI_EXPORT size_t mobi_get_kf8boundary_seqnumber (const MOBIData *m)
 Get sequential number of KF8 Boundary record for KF7/KF8 hybrid file. More...
 
MOBI_EXPORT size_t mobi_get_record_extrasize (const MOBIPdbRecord *record, const uint16_t flags)
 Calculate the size of extra bytes at the end of text record. More...
 
MOBI_EXPORT size_t mobi_get_record_mb_extrasize (const MOBIPdbRecord *record, const uint16_t flags)
 Calculate the size of extra multibyte section at the end of text record. More...
 
MOBI_EXPORT size_t mobi_get_fileversion (const MOBIData *m)
 Get mobi file version. More...
 
MOBI_EXPORT size_t mobi_get_fdst_record_number (const MOBIData *m)
 Get sequential number of FDST record. More...
 
MOBI_EXPORT MOBIExthHeadermobi_get_exthrecord_by_tag (const MOBIData *m, const MOBIExthTag tag)
 Get EXTH record with given MOBIExthTag tag. More...
 
MOBI_EXPORT MOBIExthHeadermobi_next_exthrecord_by_tag (const MOBIData *m, const MOBIExthTag tag, MOBIExthHeader **start)
 Get EXTH record with given MOBIExthTag tag. Start list search at given record. More...
 
MOBI_EXPORT MOBI_RET mobi_delete_exthrecord_by_tag (MOBIData *m, const MOBIExthTag tag)
 Delete all EXTH records with given MOBIExthTag tag. More...
 
MOBI_EXPORT MOBI_RET mobi_add_exthrecord (MOBIData *m, const MOBIExthTag tag, const uint32_t size, const void *value)
 Add new EXTH record with given tag and value. More...
 
MOBI_EXPORT MOBIExthMeta mobi_get_exthtagmeta_by_tag (const MOBIExthTag tag)
 Get MOBIExthMeta tag structure by MOBIExthTag tag id. More...
 
MOBI_EXPORT MOBIFileMeta mobi_get_filemeta_by_type (const MOBIFiletype type)
 Get MOBIFileMeta tag structure by MOBIFiletype type. More...
 
MOBI_EXPORT uint32_t mobi_decode_exthvalue (const unsigned char *data, const size_t size)
 Decode big-endian value stored in EXTH record. More...
 
MOBI_EXPORT char * mobi_decode_exthstring (const MOBIData *m, const unsigned char *data, const size_t size)
 Decode string stored in EXTH record. More...
 
MOBI_EXPORT struct tm * mobi_pdbtime_to_time (const long pdb_time)
 Convert time values from palmdoc header to time tm struct. More...
 
MOBI_EXPORT const char * mobi_get_locale_string (const uint32_t locale)
 Get pointer to locale tag for a given Mobipocket locale number. More...
 
MOBI_EXPORT size_t mobi_get_locale_number (const char *locale_string)
 Get Mobipocket locale number for a given string tag. More...
 
MOBI_EXPORT bool mobi_exists_mobiheader (const MOBIData *m)
 Check if MOBI header is loaded / present in the loaded file. More...
 
MOBI_EXPORT bool mobi_exists_fdst (const MOBIData *m)
 Check if FDST record is present in the loaded file. More...
 
MOBI_EXPORT bool mobi_exists_skel_indx (const MOBIData *m)
 Check if skeleton INDX is present in the loaded file. More...
 
MOBI_EXPORT bool mobi_exists_frag_indx (const MOBIData *m)
 Check if fragments INDX is present in the loaded file. More...
 
MOBI_EXPORT bool mobi_exists_guide_indx (const MOBIData *m)
 Check if guide INDX is present in the loaded file. More...
 
MOBI_EXPORT bool mobi_exists_ncx (const MOBIData *m)
 Check if ncx INDX is present in the loaded file. More...
 
MOBI_EXPORT bool mobi_exists_orth (const MOBIData *m)
 Check if orth INDX is present in the loaded file. More...
 
MOBI_EXPORT bool mobi_exists_infl (const MOBIData *m)
 Check if infl INDX is present in the loaded file. More...
 
MOBI_EXPORT bool mobi_is_hybrid (const MOBIData *m)
 Check if loaded MOBI data is KF7/KF8 hybrid file. More...
 
MOBI_EXPORT bool mobi_is_encrypted (const MOBIData *m)
 Check if loaded document is encrypted. More...
 
MOBI_EXPORT bool mobi_is_mobipocket (const MOBIData *m)
 Check if loaded document is MOBI/BOOK Mobipocket format. More...
 
MOBI_EXPORT bool mobi_is_dictionary (const MOBIData *m)
 Check if loaded document is dictionary. More...
 
MOBI_EXPORT bool mobi_is_kf8 (const MOBIData *m)
 Is file version 8 or above. More...
 
MOBI_EXPORT bool mobi_is_rawml_kf8 (const MOBIRawml *rawml)
 Is file version 8 or above. More...
 
MOBI_EXPORT MOBIRawmlmobi_init_rawml (const MOBIData *m)
 Initialize and return MOBIRawml structure. More...
 
MOBI_EXPORT void mobi_free_rawml (MOBIRawml *rawml)
 Free MOBIRawml structure allocated by mobi_init_rawml() More...
 
MOBI_EXPORT char * mobi_meta_get_title (const MOBIData *m)
 Get document title metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_author (const MOBIData *m)
 Get document author metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_publisher (const MOBIData *m)
 Get document publisher metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_imprint (const MOBIData *m)
 Get document imprint metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_description (const MOBIData *m)
 Get document description metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_isbn (const MOBIData *m)
 Get document ISBN metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_subject (const MOBIData *m)
 Get document subject metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_publishdate (const MOBIData *m)
 Get document publishing date metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_review (const MOBIData *m)
 Get document review metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_contributor (const MOBIData *m)
 Get document contributor metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_copyright (const MOBIData *m)
 Get document copyright metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_asin (const MOBIData *m)
 Get document ASIN metadata. More...
 
MOBI_EXPORT char * mobi_meta_get_language (const MOBIData *m)
 Get document language code metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_title (MOBIData *m, const char *title)
 Set document title metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_title (MOBIData *m, const char *title)
 Add document title metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_title (MOBIData *m)
 Delete all title metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_author (MOBIData *m, const char *author)
 Set document author metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_author (MOBIData *m, const char *author)
 Add document author metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_author (MOBIData *m)
 Delete all author metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_publisher (MOBIData *m, const char *publisher)
 Set document publisher metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_publisher (MOBIData *m, const char *publisher)
 Add document publisher metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_publisher (MOBIData *m)
 Delete all publisher metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_imprint (MOBIData *m, const char *imprint)
 Set document imprint metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_imprint (MOBIData *m, const char *imprint)
 Add document imprint metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_imprint (MOBIData *m)
 Delete all imprint metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_description (MOBIData *m, const char *description)
 Set document description metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_description (MOBIData *m, const char *description)
 Add document description metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_description (MOBIData *m)
 Delete all description metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_isbn (MOBIData *m, const char *isbn)
 Set document isbn metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_isbn (MOBIData *m, const char *isbn)
 Add document isbn metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_isbn (MOBIData *m)
 Delete all isbn metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_subject (MOBIData *m, const char *subject)
 Set document subject metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_subject (MOBIData *m, const char *subject)
 Add document subject metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_subject (MOBIData *m)
 Delete all subject metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_publishdate (MOBIData *m, const char *publishdate)
 Set document publishdate metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_publishdate (MOBIData *m, const char *publishdate)
 Add document publishdate metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_publishdate (MOBIData *m)
 Delete all publishdate metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_review (MOBIData *m, const char *review)
 Set document review metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_review (MOBIData *m, const char *review)
 Add document review metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_review (MOBIData *m)
 Delete all review metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_contributor (MOBIData *m, const char *contributor)
 Set document contributor metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_contributor (MOBIData *m, const char *contributor)
 Add document contributor metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_contributor (MOBIData *m)
 Delete all contributor metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_copyright (MOBIData *m, const char *copyright)
 Set document copyright metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_copyright (MOBIData *m, const char *copyright)
 Add document copyright metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_copyright (MOBIData *m)
 Delete all copyright metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_asin (MOBIData *m, const char *asin)
 Set document asin metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_asin (MOBIData *m, const char *asin)
 Add document asin metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_asin (MOBIData *m)
 Delete all asin metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_set_language (MOBIData *m, const char *language)
 Set document language code metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_add_language (MOBIData *m, const char *language)
 Add document language code metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_meta_delete_language (MOBIData *m)
 Delete all language code metadata. More...
 
MOBI_EXPORT MOBI_RET mobi_drm_setkey (MOBIData *m, const char *pid)
 Store PID for encryption in MOBIData stucture. More...
 
MOBI_EXPORT MOBI_RET mobi_drm_setkey_serial (MOBIData *m, const char *serial)
 Store PID for encryption in MOBIData stucture. PID will be calculated from device serial number. More...
 
MOBI_EXPORT MOBI_RET mobi_drm_delkey (MOBIData *m)
 Remove PID stored for encryption from MOBIData structure. More...
 
MOBI_EXPORT MOBI_RET mobi_drm_decrypt (MOBIData *m)
 Decrypt document. More...
 
MOBI_EXPORT MOBI_RET mobi_write_file (FILE *file, MOBIData *m)
 Write mobi document to file. More...
 

Detailed Description

Libmobi main header file.

This file is installed with the library. Include it in your project with "#include <mobi.h>". See example of usage in mobitool.c.

Copyright (c) 2014 Bartek Fabiszewski http://www.fabiszewski.net

This file is part of libmobi. Licensed under LGPL, either version 3, or any later. See http://www.gnu.org/licenses/