1 /*
2  * ****************************************************************************
3  * Copyright (c) 2013-2019, PyInstaller Development Team.
4  * Distributed under the terms of the GNU General Public License with exception
5  * for distributing bootloader.
6  *
7  * The full license is in the file COPYING.txt, distributed with this software.
8  * ****************************************************************************
9  */
10 
11 /*
12  * Declarations related to an PyInstaller archive.
13  */
14 
15 #ifndef PYI_ARCHIVE_H
16 #define PYI_ARCHIVE_H
17 
18 /* Types of CArchive items. */
19 #define ARCHIVE_ITEM_BINARY           'b'  /* binary */
20 #define ARCHIVE_ITEM_DEPENDENCY       'd'  /* runtime option */
21 #define ARCHIVE_ITEM_PYZ              'z'  /* zlib (pyz) - frozen Python code */
22 #define ARCHIVE_ITEM_ZIPFILE          'Z'  /* zlib (pyz) - frozen Python code */
23 #define ARCHIVE_ITEM_PYPACKAGE        'M'  /* Python package (__init__.py) */
24 #define ARCHIVE_ITEM_PYMODULE         'm'  /* Python module */
25 #define ARCHIVE_ITEM_PYSOURCE         's'  /* Python script (v3) */
26 #define ARCHIVE_ITEM_DATA             'x'  /* data */
27 #define ARCHIVE_ITEM_RUNTIME_OPTION   'o'  /* runtime option */
28 
29 /* TOC entry for a CArchive */
30 typedef struct _toc {
31     int  structlen;  /*len of this one - including full len of name */
32     int  pos;        /* pos rel to start of concatenation */
33     int  len;        /* len of the data (compressed) */
34     int  ulen;       /* len of data (uncompressed) */
35     char cflag;      /* is it compressed (really a byte) */
36     char typcd;      /* type code -'b' binary, 'z' zlib, 'm' module,
37                       * 's' script (v3),'x' data, 'o' runtime option  */
38     char name[1];    /* the name to save it as */
39     /* starting in v5, we stretch this out to a mult of 16 */
40 } TOC;
41 
42 /* The CArchive Cookie, from end of the archive. */
43 typedef struct _cookie {
44     char magic[8];      /* 'MEI\014\013\012\013\016' */
45     int  len;           /* len of entire package */
46     int  TOC;           /* pos (rel to start) of TableOfContents */
47     int  TOClen;        /* length of TableOfContents */
48     int  pyvers;        /* new in v4 */
49     char pylibname[64]; /* Filename of Python dynamic library e.g. python2.7.dll. */
50 } COOKIE;
51 
52 typedef struct _archive_status {
53     FILE * fp;
54     int    pkgstart;
55     TOC *  tocbuff;
56     TOC *  tocend;
57     COOKIE cookie;
58     /*
59      * On Windows:
60      *    These strings are UTF-8 encoded (via pyi_win32_utils_to_utf8). On Python 2,
61      *    they are re-encoded to ANSI with ShortFileNames when passed to Python. On
62      *    Python 3, they are decoded back to wchar_t.
63      *
64      * On Linux/OS X:
65      *    These strings are system-provided. On Python 2, they are passed as-is to Python.
66      *    On Python 3, they are decoded to wchar_t using Py_DecodeLocale
67      *    (formerly called _Py_char2wchar) first.
68      */
69     char archivename[PATH_MAX];
70     char homepath[PATH_MAX];
71     char temppath[PATH_MAX];
72     /*
73      * Main path could be homepath or temppath. It will be temppath
74      * if temppath is available. Sometimes we do not need to know if temppath
75      * or homepath should be used. We only need to know the path. This variable
76      * is used for example to set sys.path, sys.prefix, and sys._MEIPASS.
77      */
78     char mainpath[PATH_MAX];
79     /*
80      * Flag if temporary directory is available. This usually means running
81      * executable in onefile mode. Bootloader has to behave differently
82      * in this mode.
83      */
84     bool has_temp_directory;
85     /*
86      * Flag if Python library was loaded. This indicates if it is safe
87      * to call function PI_Py_Finalize(). If Python dll is missing
88      * calling this function would cause segmentation fault.
89      */
90     bool is_pylib_loaded;
91     /*
92      * Cached command-line arguments.
93      */
94     int    argc;      /* Count of command-line arguments. */
95     char **argv;      /*
96                        * On Windows, UTF-8 encoded form of __wargv.
97                        * On OS X/Linux, as received in main()
98                        */
99 } ARCHIVE_STATUS;
100 
101 TOC *pyi_arch_increment_toc_ptr(const ARCHIVE_STATUS *status, const TOC* ptoc);
102 
103 unsigned char *pyi_arch_extract(ARCHIVE_STATUS *status, TOC *ptoc);
104 int pyi_arch_extract2fs(ARCHIVE_STATUS *status, TOC *ptoc);
105 
106 /**
107  * Helpers for embedders
108  */
109 int pyi_arch_get_pyversion(ARCHIVE_STATUS *status);
110 extern int pyvers;
111 
112 /**
113  * The gory detail level
114  */
115 int pyi_arch_set_paths(ARCHIVE_STATUS *status, char const * archivePath,
116                        char const * archiveName);
117 int pyi_arch_open(ARCHIVE_STATUS *status);
118 
119 /*
120  * Memory allocation wrappers.
121  */
122 void pyi_arch_status_free_memory(ARCHIVE_STATUS *status);
123 
124 /*
125  * Setup the paths and open the archive
126  *
127  * @param archivePath  The path (with trailing backslash) to the archive.
128  *
129  * @param archiveName  The file name of the archive, without a path.
130  *
131  * @param workpath     The path (with trailing backslash) to where
132  *                     the binaries were extracted. If they have not
133  *                     benn extracted yet, this is NULL. If they have,
134  *                     this will either be archivePath, or a temp dir
135  *                     where the user has write permissions.
136  *
137  * @return 0 on success, non-zero otherwise.
138  */
139 int pyi_arch_setup(ARCHIVE_STATUS *status, char const * archivePath,
140                    char const * archiveName);
141 
142 TOC *getFirstTocEntry(ARCHIVE_STATUS *status);
143 TOC *getNextTocEntry(ARCHIVE_STATUS *status, TOC *entry);
144 
145 char * pyi_arch_get_option(const ARCHIVE_STATUS * status, char * optname);
146 
147 #endif  /* PYI_ARCHIVE_H */
148