├── LICENSE.md ├── README.md ├── core ├── chl.h └── src │ ├── cgi.c │ ├── cgi.h │ ├── chl.h │ ├── deffuncs.c │ ├── deffuncs.h │ ├── error.c │ ├── error.h │ ├── fastcgi.c │ ├── fastcgi.h │ ├── fcgi_stdio.h │ ├── fcgiapp.h │ ├── http.c │ ├── http.h │ ├── inline.c │ ├── inline.h │ ├── std.c │ ├── std.h │ ├── view.c │ └── view.h ├── findplugindeps ├── makefile ├── pluginhandler └── plugins ├── fastcgi ├── fcgi.h ├── libs │ └── .gitignore ├── makefile └── src │ ├── fastcgi.h │ ├── fcgi_config.h │ ├── fcgi_config_x86.h │ ├── fcgi_stdio.c │ ├── fcgi_stdio.h │ ├── fcgiapp.c │ ├── fcgiapp.h │ ├── fcgimisc.h │ ├── fcgio.cpp │ ├── fcgio.h │ ├── fcgios.h │ └── os_unix.c └── mysql ├── libs └── .gitignore ├── libscompile ├── makefile ├── mysql.h └── src ├── HEADERS ├── chlmysql.c ├── chlmysql.h ├── my_alloc.h ├── my_list.h ├── mysql.h ├── mysql_com.h ├── mysql_time.h ├── mysql_version.h └── typelib.h /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CHL 2 | C Hypertext Library - A library for writing web applications in C 3 | 4 | ```c 5 | #include 6 | 7 | int main() { 8 | chl_set_default_headers(); 9 | chl_print_headers(); 10 | 11 | printf("Hello world"); 12 | 13 | return 0; 14 | } 15 | ``` 16 | (*Simple Hello World in CHL*) 17 | 18 | [See examples](https://github.com/it4e/CHL/wiki/Examples)
19 | [Tutorial](https://github.com/it4e/CHL/wiki/Tutorial), 20 | [Setup](https://github.com/it4e/CHL/wiki/Setup), 21 | [API](https://github.com/it4e/CHL/wiki), 22 | [Contribute](https://github.com/it4e/CHL/wiki/Contribute)
23 | [FastCGI](https://github.com/it4e/CHL/wiki/FastCGI) 24 | 25 | ## What is CHL? 26 | 27 | CHL, short for *C Hypertext Library*, is a library used to write web applications of all sorts in the C programming language. CHL provides you with a lot of useful features: 28 | 29 | > 30 | - *FastCGI implementation* 31 | - *MySQL library* 32 | - *Parsing and fetching HTTP data, such as POST and GET.* 33 | - *Creating and deleting HTTP headers.* 34 | - *A dedicated API for creating and deleting cookies.* 35 | - *The ability to execute CHL functions within HTML files* 36 | 37 | and a lot more... 38 | 39 | ## Why CHL? 40 | 41 | What makes CHL uniqe is the support for executing functions inside HTML files, much like PHP using the ** syntax, though *CHL* uses the *<{ }>* syntax. 42 | 43 | > Example 44 | 45 | ```html 46 | 47 | <{ import("header.vw"); }> 48 | 49 | ``` 50 | 51 | ## How does it work? 52 | 53 | Web applications written in C must somehow be executed by the Web server since C is a compiled language. To make this possible CHL is based on CGI (Common Gateway Interface), which in short means that the server executes your program and passes it data through environment variables. CHL does all the parsing and handling of CGI in the background, and provides you with some easy to use functions instead. CHL also provides an interface for FastCGI. 54 | 55 | ## API 56 | 57 | The *Application Programming Interface* is written with *Github Wikis*: [API](https://github.com/it4e/CHL/wiki). 58 | 59 | ## Setup 60 | 61 | For a proper guide on how to install and configure CHL on your system, read the following document: https://github.com/it4e/CHL/wiki/Setup. 62 | 63 | As of now, CHL is only officially available on Linux, but I am planning to port it to other operating systems as well if the interest is big enough. Otherwise you could of course make a port of it yourself, see [contribute](https://github.com/it4e/CHL/wiki/Contribute). 64 | 65 | ## Tutorial 66 | 67 | To read an in depth tutorial on the structure of *CHL web applications*, and a walk through on how to get started and how to use the *CHL API* properly see https://github.com/it4e/CHL/wiki/Tutorial. 68 | 69 | The tutorial is divided into various sections. The first section is a quick introduction to let you know what *CHL* is all about and what it can do for you. We will then dig deeper and deeper into the CHL API. 70 | 71 | Before you start reading this tutorial, make sure you have CHL installed and that everything is properly set up. [Setting up CHL](https://github.com/it4e/CHL/wiki/Setup). 72 | 73 | 74 | ## Contribute 75 | 76 | There are several ways you can contribute to CHL. Take a look at the [*issues page*](https://github.com/it4e/CHL/issues) for an overview of what you can contribute to. If you have any ideas of your own for new features to implement, feel free to contribute with a pull request. 77 | 78 | For a detailed guide on contribution to CHL, see [contribute](https://github.com/it4e/CHL/wiki/Contribute). 79 | 80 | ## Examples 81 | 82 | See [examples](https://github.com/it4e/CHL/wiki/Examples), for a page with detailed examples of CHL in use. 83 | -------------------------------------------------------------------------------- /core/chl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the standard header file for CHL. 3 | * Contains all of the available functions and properties part of the CHL API 4 | */ 5 | #ifndef CHL_H_ 6 | #define CHL_H_ 7 | 8 | // 9 | 10 | #include 11 | #include 12 | 13 | // Only used for macro chl_error_append 14 | void error_append(char, char *); 15 | 16 | /* 17 | * Function for outputting CHL errors 18 | */ 19 | void chl_print_errors(); 20 | 21 | // Dynamically allocated variable for error string 22 | extern char * _alloce_; 23 | 24 | // Macro to dynamically allocate an error string and pass it to error_append 25 | #define chl_error_append(id, ...) snprintf((_alloce_ = malloc(100)), 100, __VA_ARGS__), error_append(id, _alloce_); 26 | 27 | // 28 | 29 | /* 30 | * Function for acquiring HTTP POST data. 31 | * [name]: a string containing the name of the POST variable 32 | * 33 | * Return: 0 if not defined, or POST variable value 34 | */ 35 | char * chl_post(char * name); 36 | 37 | /* 38 | * Function for acquiring HTTP POST data as integer value. 39 | * [name]: a string containing the name of the POST variable 40 | * 41 | * Return: 0 if not defined, -1 if conversion to int failed, or POST variable value 42 | */ 43 | int chl_posti(char * name); 44 | 45 | /* 46 | * Function for acquiring HTTP POST data as float value. 47 | * [name]: a string containing the name of the POST variable 48 | * 49 | * Return: 0 if not defined, -1 if conversion to float failed, or POST variable value 50 | */ 51 | float chl_postf(char * name); 52 | 53 | /* 54 | * Function for acquiring GET data. 55 | * [name]: a string containing the name of the GET variable 56 | * 57 | * Return: 0 if not defined, or GET variable value 58 | */ 59 | char * chl_get(char * name); 60 | 61 | /* 62 | * Function for acquiring GET data as integer value. 63 | * [name]: a string containing the name of the GET variable 64 | * 65 | * Return: 0 if not defined, -1 if conversion to int failed, or GET variable value 66 | */ 67 | int chl_geti(char * name); 68 | 69 | /* 70 | * Function for acquiring GET data as float value. 71 | * [name]: a string containing the name of the GET variable 72 | * 73 | * Return: 0 if not defined, -1 if conversion to float failed, or GET variable value 74 | */ 75 | float chl_getf(char * name); 76 | 77 | // 78 | 79 | /* 80 | * Function for defining HTTP headers 81 | * [name]: a string containing the name of the HTTP header, [value]: which value to assign 82 | */ 83 | void chl_set_header(char * name, char * value); 84 | 85 | /* 86 | * Function for acquiring a self-set header 87 | * [name]: a string containing the name of the HTTP header 88 | * 89 | * Return: 0 if not defined, or header value 90 | */ 91 | char * chl_get_header(char * name); 92 | 93 | /* 94 | * Function for outputting headers 95 | */ 96 | void chl_print_headers(); 97 | 98 | /* 99 | * Function for setting default headers 100 | */ 101 | void chl_set_default_headers(); 102 | 103 | /* 104 | * Function for acquiring HTTP cookies data 105 | * [name]: a string containing the name of the HTTP cookie 106 | * 107 | * Return: 0 if not defined, or cookie value 108 | */ 109 | char * chl_cookies(char * name); 110 | 111 | /* 112 | * Function for creating HTTP cookies 113 | * [name]: a string containing the name of the HTTP cookie, [value]: which value to assign, [expires]: lifetime of cookie in format: Wdy, DD-Mon-YYYY HH:MM:SS GMT 114 | */ 115 | void chl_set_cookie(char * name, char * value, char * expires); 116 | 117 | /* 118 | * Function for deleting HTTP cookies 119 | * [name]: a string containing the name of the HTTP cookie 120 | */ 121 | void chl_delete_cookie(char * name); 122 | 123 | 124 | 125 | // 126 | 127 | /* 128 | * Function for opening a CHL view file 129 | * Also outputs headers 130 | * [path]: path to file 131 | */ 132 | void chl_view(char * path); 133 | 134 | /* 135 | * Function for acquiring contents of files 136 | * [path]: path to file 137 | */ 138 | void chl_import(char * path); 139 | 140 | 141 | 142 | 143 | // 144 | 145 | 146 | /* 147 | * Function for appending CHL function so it can be executed through inline CHL code 148 | * [name]: which function name to set, [function]: pointer to a function returning void and taking a char pointer as argument 149 | */ 150 | void chl_func_append(char * name, void (* function)(char *)); 151 | 152 | /* 153 | * Function for executing CHL functions 154 | * [name]: name of function, [args]: arguments passed to function 155 | * 156 | * Return: 0 if function not found, or >0 if found 157 | */ 158 | char chl_func(char * name, char * args); 159 | 160 | /* 161 | * Function for acquiring next argument of function 162 | * [args]: the char pointer argument to CHL function 163 | * 164 | * Return: 0 if no arguments left, or argument data 165 | */ 166 | char * chl_next_arg(char * args); 167 | 168 | /* 169 | * Function for acquiring next argument of function as integer value 170 | * [args]: the char pointer argument to CHL function 171 | * 172 | * Return: 0 if no arguments left, -1 if conversion to int failed, or argument data 173 | */ 174 | int chl_next_argi(char * args); 175 | 176 | /* 177 | * Function for acquiring next argument of function as float value 178 | * [args]: the char pointer argument to CHL function 179 | * 180 | * Return: 0 if no arguments left, -1 if conversion to float failed, or argument data 181 | */ 182 | float chl_next_argf(char * args); 183 | 184 | /* 185 | * Function for acquiring all arguments of a function 186 | * [arguments]: the address of a char ** variable. Will contain all arguments. [args]: the char pointer argument to CHL function 187 | */ 188 | char chl_get_args(char *(** arguments), char * args); 189 | 190 | // 191 | 192 | /* 193 | * Function for calling init methods of other source files to work with FastCGI 194 | */ 195 | void chl_fcgi_init(); 196 | 197 | /* 198 | * Function for accepting next client using FastCGI 199 | * Should be called in a loop by caller 200 | * 201 | * Return: 1 if pending client, 0 if an error accoured 202 | */ 203 | char chl_fcgi_next(); 204 | 205 | #endif /* CHL_H_ */ 206 | -------------------------------------------------------------------------------- /core/src/cgi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This source file's purpose is to work as an interface between the server and CHL. 3 | * Contains all the code for interpreting and manipulating CGI environment variables. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "cgi.h" 13 | #include "std.h" 14 | 15 | #define GET_DATA_ENV "QUERY_STRING" // GET data environment variable 16 | #define METHOD_POST 1 17 | #define METHOD_GET 0 18 | #define METHOD_POST_NREAD 2000 // POST data bytes per interation limit 19 | 20 | // A struct to hold CGI [method] data 21 | typedef struct { 22 | char * name; 23 | char * value; 24 | } CGI_METHOD_DATA; 25 | 26 | static CGI_METHOD_DATA * POST = NULL; // Struct array for CGI POST data, dynamically allocated 27 | static CGI_METHOD_DATA * GET = NULL; // Struct array for CGI GET data, dynamically allocated 28 | static unsigned char post_size = 0, get_size = 0; // Size of [method] structs 29 | 30 | // Buffer for [method] data, dynamically allocated 31 | static char * raw_data_post = NULL, * raw_data_get = NULL; 32 | 33 | // Whether [method] has been successfully manipulated or not 34 | static char post_used = 0, get_used = 0; 35 | 36 | // Function for reading environment variables from server 37 | char * get_env(char * var_name) { 38 | char * val; 39 | 40 | if((val = getenv(var_name)) != NULL) 41 | return val; 42 | 43 | val = "\0"; 44 | return val; 45 | } 46 | 47 | // Function to interpret data sent with the POST method 48 | void method_post_init() { 49 | if(post_used) // Check if the POST data has already been interpreted 50 | return; 51 | 52 | // Allocate memory for POST data 53 | raw_data_post = std_malloc(METHOD_POST_NREAD * sizeof(char)); // POST data 54 | 55 | //Append temporary blank variable to POST array to prevent NULL error, overwritten 56 | method_append_var(" ", " ", METHOD_POST); 57 | 58 | // Assign raw_data_post its value 59 | method_post_read_input(); 60 | 61 | // Split data into variables, url-decode 62 | format_data(raw_data_post, METHOD_POST); 63 | 64 | post_used = 1; // Set that POST data is done 65 | } 66 | 67 | // Function to interpret data sent with the GET method 68 | void method_get_init() { 69 | if(get_used) // Check if the GET data has already been interpreted 70 | return; 71 | 72 | // Append temporary blank variable to GET array to prevent NULL error, overwritten 73 | method_append_var(" ", " ", METHOD_GET); 74 | 75 | // Assign [raw_data_get] its value 76 | raw_data_get = get_env(GET_DATA_ENV); 77 | 78 | // Split data into variables, url-decode 79 | format_data(raw_data_get, METHOD_GET); 80 | 81 | get_used = 1; // Set that GET data is done 82 | } 83 | 84 | // Function for interpreting and splitting [method] data 85 | void format_data(char * data, const char method) { 86 | char * last_var; // Pointer to last occurrence of '&', or start of string [data] 87 | char * var_name, * var_value; // Pointer to variable in [data] 88 | 89 | last_var = data; 90 | var_name = data; 91 | 92 | // Loop through [data] and interpret the data 93 | while(*data != '\0') { 94 | // If variable with '=' character 95 | if(*data == '=') { 96 | // Set end of variable name 97 | *data++ = '\0'; 98 | 99 | var_name = last_var; 100 | var_value = data; 101 | 102 | // Loop to next variable, next occurrence of '&' 103 | while((*data != '&') && (*data != '\0')) 104 | data++; 105 | 106 | // Set end of variable value 107 | (*data == '\0') ? 0 : (*data++ = '\0'); 108 | 109 | last_var = data; 110 | 111 | // Decode HTTP data 112 | http_form_decode(var_name); 113 | http_form_decode(var_value); 114 | 115 | // Append variable to method struct 116 | method_append_var(var_name, var_value, method); 117 | } 118 | 119 | // If variable without value (without '=' character) 120 | else if(*data == '&') { 121 | *data = '\0'; 122 | 123 | // Set name, and set value to null 124 | var_value = data; 125 | var_name = last_var; 126 | 127 | last_var = ++data; 128 | 129 | // Append variable to [method] struct 130 | method_append_var(var_name, var_value, method); 131 | } 132 | 133 | // Go on if just a letter 134 | else 135 | data++; 136 | } 137 | 138 | // A variable only defined with a variable name, and without '=' 139 | if(var_name == last_var) { 140 | var_value = data; 141 | method_append_var(var_name, var_value, method); 142 | } 143 | } 144 | 145 | // Decode HTTP FORM data 146 | void http_form_decode(char * str) { 147 | char * decoded; // The final decoded string 148 | decoded = str; 149 | 150 | // If string is empty 151 | if(*str == '\0') 152 | return; 153 | 154 | // Loop through string and interpret characters 155 | while(*str != '\0') { 156 | if(*str == '+') { 157 | *decoded++ = ' '; 158 | str++; 159 | } 160 | 161 | else if((*str == '%') && (isxdigit(str[1]) && isxdigit(str[2]))) { 162 | { 163 | if(str[1] >= 'a') 164 | str[1] -= ('a' - 'A'); 165 | else if(str[1] >= 'A') 166 | str[1] -= ('A' - 10); 167 | else 168 | str[1] -= '0'; 169 | } 170 | 171 | { 172 | if(str[2] >= 'a') 173 | str[2] -= ('a' - 'A'); 174 | else if(str[2] >= 'A') 175 | str[2] -= ('A' - 10); 176 | else 177 | str[2] -= '0'; 178 | } 179 | 180 | *decoded++ = (16 * str[1]) + str[2]; 181 | str += 3; 182 | } 183 | 184 | else 185 | *decoded++ = *str++; 186 | } 187 | 188 | *decoded++ = '\0'; 189 | } 190 | 191 | // Append a variable to [method] array 192 | void method_append_var(char * name, char * value, const char method) { 193 | // Prevent char overflow, a greater number than 512 194 | if((post_size >= 510) || (get_size >= 510)) 195 | return; 196 | 197 | switch(method) { 198 | case METHOD_POST: 199 | // Allocate memory for new variable 200 | POST = std_realloc(POST, ++post_size * sizeof(CGI_METHOD_DATA)); 201 | 202 | // Set variable properties 203 | POST[post_size - 1].name = name; 204 | POST[post_size - 1].value = value; 205 | 206 | break; 207 | 208 | case METHOD_GET: 209 | // Allocate memory for new variable 210 | GET = std_realloc(GET, ++get_size * sizeof(CGI_METHOD_DATA)); 211 | 212 | // Set variable properties 213 | GET[get_size - 1].name = name; 214 | GET[get_size - 1].value = value; 215 | 216 | break; 217 | } 218 | } 219 | 220 | // Returns variable [name]'s value in POST data array 221 | char * chl_post(char * name) { 222 | // Check if POST data array has been initialized 223 | if(! post_used) 224 | method_post_init(); 225 | 226 | int i, x; 227 | 228 | // Loop through every index in POST data array until [name] is found 229 | for(i = 0; (i < post_size) && (x = strcmp(POST[i].name, name)); i++); 230 | 231 | // Found a matching value for [name] 232 | if(!x) 233 | return POST[i].value; 234 | 235 | // Did not find a match 236 | return 0; 237 | } 238 | 239 | // Returns variable [name]'s value in POST data array as integer 240 | int chl_posti(char * name) { 241 | char * val, * err; 242 | long int ret; 243 | 244 | // Check if POST index exists 245 | if(! (val = chl_post(name))) 246 | return -1; 247 | 248 | // Convert to int 249 | ret = strtol(val, &err, 10); 250 | 251 | // Return -1 if conversion could not be done, or an error occurred 252 | if((val == err) || (ret == LONG_MIN) || (ret == LONG_MAX)) 253 | return -1; 254 | 255 | // Return integer 256 | return (int) ret; 257 | } 258 | 259 | // Returns variable [name]'s value in POST data array as float 260 | float chl_postf(char * name) { 261 | char * val, * err; 262 | float ret; 263 | 264 | // Check if POST index exists 265 | if(! (val = chl_post(name))) 266 | return -1; 267 | 268 | // Convert to float 269 | ret = strtof(val, &err); 270 | 271 | // Return -1 if conversion could not be done, or an error occurred 272 | if((val == err) || (ret == HUGE_VALF)) 273 | return -1; 274 | 275 | // Return float 276 | return ret; 277 | } 278 | 279 | // Returns variable [name]'s value in GET data array 280 | char * chl_get(char * name) { 281 | // Check if GET data array has been initialized 282 | if(! get_used) 283 | method_get_init(); 284 | 285 | int i, x; 286 | 287 | // Loop through every index in GET data array until [name] is found 288 | for(i = 0; (i < get_size) && (x = strcmp(GET[i].name, name)); i++); 289 | 290 | // Found a matching value for [name] 291 | if(!x) 292 | return GET[i].value; 293 | 294 | // Did not find a match 295 | return 0; 296 | } 297 | 298 | // Returns variable [name]'s value in GET data array as integer 299 | int chl_geti(char * name) { 300 | char * val, * err; 301 | long int ret; 302 | 303 | // Check if GET index exists 304 | if(! (val = chl_get(name))) 305 | return -1; 306 | 307 | // Convert to int 308 | ret = strtol(val, &err, 10); 309 | 310 | // Return -1 if conversion could not be done, or an error occurred 311 | if((val == err) || (ret == LONG_MIN) || (ret == LONG_MAX)) 312 | return -1; 313 | 314 | // Return integer 315 | return (int) ret; 316 | } 317 | 318 | // Returns variable [name]'s value in GET data array as float 319 | float chl_getf(char * name) { 320 | char * val, * err; 321 | float ret; 322 | 323 | // Check if POST index exists 324 | if(! (val = chl_get(name))) 325 | return -1; 326 | 327 | // Convert to float 328 | ret = strtof(val, &err); 329 | 330 | // Return -1 if conversion could not be done, or an error occurred 331 | if((val == err) || (ret == HUGE_VALF)) 332 | return -1; 333 | 334 | // Return float 335 | return ret; 336 | } 337 | 338 | // Read POST data from stdin 339 | void method_post_read_input() { 340 | int ntotal = 0; // Total bytes read 341 | int nread = 0; // Bytes read in one iteration 342 | int iteration = 1; // Number of iterations 343 | 344 | // Read data from stdin [METHOD_POST_NREAD] bytes at time, allocate more memory if needed 345 | while((nread = fread(raw_data_post + ntotal, sizeof(char), METHOD_POST_NREAD, stdin)) == METHOD_POST_NREAD) { 346 | // Limit to CGI_POST_LIM bytes 347 | if((++iteration * METHOD_POST_NREAD) >= CGI_POST_LIM) 348 | return; 349 | 350 | // Allocate more memory for POST data 351 | raw_data_post = std_realloc(raw_data_post, iteration * METHOD_POST_NREAD); 352 | ntotal += nread; 353 | } 354 | 355 | // Null terminate data 356 | raw_data_post[ntotal + nread] = '\0'; 357 | } 358 | 359 | // Initialize and free objects, called by chl_fcgi_init 360 | void _cgi_init() { 361 | post_size = 0; 362 | get_size = 0; 363 | post_used = 0; 364 | get_used = 0; 365 | 366 | free(POST); 367 | free(GET); 368 | free(raw_data_post); 369 | 370 | POST = NULL; 371 | GET = NULL; 372 | raw_data_post = NULL; 373 | } 374 | -------------------------------------------------------------------------------- /core/src/cgi.h: -------------------------------------------------------------------------------- 1 | #ifndef CGI_H_ 2 | #define CGI_H_ 3 | 4 | #define CGI_POST_LIM 100000 // CGI POST data limit 5 | #define CGI_GET_LIM 1000 // Not used, see environment variable limit 6 | 7 | // Whether to compile as FastCGI 8 | #ifdef _F_CHL_ 9 | #include "fcgi_stdio.h" 10 | #endif 11 | 12 | char * get_env(char *); 13 | void method_post_init(); 14 | void method_get_init(); 15 | void format_data(char *, const char); 16 | void http_form_decode(char *); 17 | void method_append_var(char *, char *, const char); 18 | char * chl_post(char *); 19 | int chl_posti(char *); 20 | float chl_postf(char *); 21 | char * chl_get(char *); 22 | int chl_geti(char *); 23 | float chl_getf(char *); 24 | void method_post_read_input(); 25 | void _cgi_init(); 26 | 27 | #endif /* CGI_H_ */ 28 | -------------------------------------------------------------------------------- /core/src/chl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the standard header file for CHL. 3 | * Contains all of the available functions and properties part of the CHL API 4 | */ 5 | #ifndef CHL_H_ 6 | #define CHL_H_ 7 | 8 | // 9 | 10 | #include 11 | #include 12 | 13 | // Only used for macro chl_error_append 14 | void error_append(char, char *); 15 | 16 | /* 17 | * Function for outputting CHL errors 18 | */ 19 | void chl_print_errors(); 20 | 21 | // Dynamically allocated variable for error string 22 | extern char * _alloce_; 23 | 24 | // Macro to dynamically allocate an error string and pass it to error_append 25 | #define chl_error_append(id, ...) snprintf((_alloce_ = std_malloc(100)), 100, __VA_ARGS__), error_append(id, _alloce_); 26 | 27 | // 28 | 29 | /* 30 | * Function for acquiring HTTP POST data. 31 | * [name]: a string containing the name of the POST variable 32 | * 33 | * Return: 0 if not defined, or POST variable value 34 | */ 35 | char * chl_post(char * name); 36 | 37 | /* 38 | * Function for acquiring HTTP POST data as integer value. 39 | * [name]: a string containing the name of the POST variable 40 | * 41 | * Return: 0 if not defined, -1 if conversion to int failed, or POST variable value 42 | */ 43 | int chl_posti(char * name); 44 | 45 | /* 46 | * Function for acquiring HTTP POST data as float value. 47 | * [name]: a string containing the name of the POST variable 48 | * 49 | * Return: 0 if not defined, -1 if conversion to float failed, or POST variable value 50 | */ 51 | float chl_postf(char * name); 52 | 53 | /* 54 | * Function for acquiring GET data. 55 | * [name]: a string containing the name of the GET variable 56 | * 57 | * Return: 0 if not defined, or GET variable value 58 | */ 59 | char * chl_get(char * name); 60 | 61 | /* 62 | * Function for acquiring GET data as integer value. 63 | * [name]: a string containing the name of the GET variable 64 | * 65 | * Return: 0 if not defined, -1 if conversion to int failed, or GET variable value 66 | */ 67 | int chl_geti(char * name); 68 | 69 | /* 70 | * Function for acquiring GET data as float value. 71 | * [name]: a string containing the name of the GET variable 72 | * 73 | * Return: 0 if not defined, -1 if conversion to float failed, or GET variable value 74 | */ 75 | float chl_getf(char * name); 76 | 77 | // 78 | 79 | /* 80 | * Function for defining HTTP headers 81 | * [name]: a string containing the name of the HTTP header, [value]: which value to assign 82 | */ 83 | void chl_set_header(char * name, char * value); 84 | 85 | /* 86 | * Function for acquiring a self-set header 87 | * [name]: a string containing the name of the HTTP header 88 | * 89 | * Return: 0 if not defined, or header value 90 | */ 91 | char * chl_get_header(char * name); 92 | 93 | /* 94 | * Function for outputting headers 95 | */ 96 | void chl_print_headers(); 97 | 98 | /* 99 | * Function for setting default headers 100 | */ 101 | void chl_set_default_headers(); 102 | 103 | /* 104 | * Function for acquiring HTTP cookies data 105 | * [name]: a string containing the name of the HTTP cookie 106 | * 107 | * Return: 0 if not defined, or cookie value 108 | */ 109 | char * chl_cookies(char * name); 110 | 111 | /* 112 | * Function for creating HTTP cookies 113 | * [name]: a string containing the name of the HTTP cookie, [value]: which value to assign, [expires]: lifetime of cookie in format: Wdy, DD-Mon-YYYY HH:MM:SS GMT 114 | */ 115 | void chl_set_cookie(char * name, char * value, char * expires); 116 | 117 | /* 118 | * Function for deleting HTTP cookies 119 | * [name]: a string containing the name of the HTTP cookie 120 | */ 121 | void chl_delete_cookie(char * name); 122 | 123 | 124 | 125 | // 126 | 127 | /* 128 | * Function for opening a CHL view file 129 | * Also outputs headers 130 | * [path]: path to file 131 | */ 132 | void chl_view(char * path); 133 | 134 | /* 135 | * Function for acquiring contents of files 136 | * [path]: path to file 137 | */ 138 | void chl_import(char * path); 139 | 140 | 141 | 142 | 143 | // 144 | 145 | 146 | /* 147 | * Function for appending CHL function so it can be executed through inline CHL code 148 | * [name]: which function name to set, [function]: pointer to a function returning void and taking a char pointer as argument 149 | */ 150 | void chl_func_append(char * name, void (* function)(char *)); 151 | 152 | /* 153 | * Function for executing CHL functions 154 | * [name]: name of function, [args]: arguments passed to function 155 | * 156 | * Return: 0 if function not found, or >0 if found 157 | */ 158 | char chl_func(char * name, char * args); 159 | 160 | /* 161 | * Function for acquiring next argument of function 162 | * [args]: the char pointer argument to CHL function 163 | * 164 | * Return: 0 if no arguments left, or argument data 165 | */ 166 | char * chl_next_arg(char * args); 167 | 168 | /* 169 | * Function for acquiring next argument of function as integer value 170 | * [args]: the char pointer argument to CHL function 171 | * 172 | * Return: 0 if no arguments left, -1 if conversion to int failed, or argument data 173 | */ 174 | int chl_next_argi(char * args); 175 | 176 | /* 177 | * Function for acquiring next argument of function as float value 178 | * [args]: the char pointer argument to CHL function 179 | * 180 | * Return: 0 if no arguments left, -1 if conversion to float failed, or argument data 181 | */ 182 | float chl_next_argf(char * args); 183 | 184 | /* 185 | * Function for acquiring all arguments of a function 186 | * [arguments]: the address of a char ** variable. Will contain all arguments. [args]: the char pointer argument to CHL function 187 | */ 188 | char chl_get_args(char *(** arguments), char * args); 189 | 190 | // 191 | 192 | /* 193 | * Function for calling init methods of other source files to work with FastCGI 194 | */ 195 | void chl_fcgi_init(); 196 | 197 | /* 198 | * Function for accepting next client using FastCGI 199 | * Should be called in a loop by caller 200 | * 201 | * Return: 1 if pending client, 0 if an error accoured 202 | */ 203 | char chl_fcgi_next(); 204 | 205 | #endif /* CHL_H_ */ 206 | -------------------------------------------------------------------------------- /core/src/deffuncs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This source file's purpose is to define the default inline functions for CHL 3 | */ 4 | 5 | #include "inline.h" 6 | #include "view.h" 7 | #include "deffuncs.h" 8 | 9 | // Whether default functions have been initialized or not 10 | char def_funcs = 0; 11 | 12 | // Default inline function for importing files 13 | void _def_import(char * args) { 14 | char * file; 15 | 16 | // Import file if argument file name is defined 17 | if((file = chl_next_arg(args))) 18 | chl_import(file); 19 | } 20 | 21 | // Default inline print function 22 | void _def_print(char * args) { 23 | char * arg; 24 | 25 | // Attain first argument 26 | if(! (arg = chl_next_arg(args))) 27 | return; 28 | 29 | // Output first argument 30 | fputs(arg, stdout); 31 | 32 | // Loop through rest of arguments and output data 33 | while((arg = chl_next_arg(NULL))) 34 | fputs(arg, stdout); 35 | } 36 | 37 | // Append default functions to [FUNCS] array in "inline.c" 38 | void append_default_funcs() { 39 | // Add default inline import function 40 | chl_func_append(DEF_FUNC_IMPORT, _def_import); 41 | // Add default inline print function 42 | chl_func_append(DEF_FUNC_PRINT, _def_print); 43 | 44 | def_funcs = 1; 45 | } 46 | -------------------------------------------------------------------------------- /core/src/deffuncs.h: -------------------------------------------------------------------------------- 1 | #ifndef DEFFUNCS_H_ 2 | #define DEFFUNCS_H_ 3 | 4 | #define DEF_FUNC_IMPORT "import" // Name of default function for inline import of files 5 | #define DEF_FUNC_PRINT "print" // Name of default function for inline print 6 | 7 | // Whether to compile as FastCGI 8 | #ifdef _F_CHL_ 9 | #include "fcgi_stdio.h" 10 | #endif 11 | 12 | extern char def_funcs; 13 | void _def_import(char *); 14 | void _def_print(char *); 15 | void append_default_funcs(); 16 | 17 | #endif /* DEFFUNCS_H_ */ 18 | -------------------------------------------------------------------------------- /core/src/error.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This source file's purpose is to provide an interface for error handling 3 | * header imported by other source files 4 | */ 5 | 6 | #include 7 | #include 8 | #include "error.h" 9 | #include "std.h" 10 | 11 | // Struct for holding error data 12 | typedef struct { 13 | unsigned char id; 14 | char * value; 15 | } ERROR; 16 | 17 | // Struct array to hold errors of type [ERROR], dynamically allocated 18 | static ERROR * ERRORS = NULL; 19 | 20 | // Size of [ERRORS] 21 | static unsigned char errors_size = 0; 22 | 23 | // Dynamically allocated variable for error string 24 | char * _alloce_ = NULL; 25 | 26 | // Append error [ERROR] to [ERRORS] array, see macro chl_error_append 27 | void error_append(char id, char * value) { 28 | // Prevent char overflow, a greater number than 512 29 | if(errors_size >= 510) 30 | return; 31 | 32 | // Allocate memory for new error variable 33 | ERRORS = std_realloc(ERRORS, ++errors_size * sizeof(ERROR)); 34 | 35 | // Set variable properties 36 | ERRORS[errors_size - 1].id = id; 37 | ERRORS[errors_size - 1].value = value; 38 | } 39 | 40 | // Output errors in [ERRORS] struct array 41 | void chl_print_errors() { 42 | int i; 43 | 44 | // Loop through [ERRORS] array and output errors 45 | printf(""); 46 | 47 | for(i = 0; i < errors_size; i++) 48 | printf("Error %d: %s.
", ERRORS[i].id, ERRORS[i].value); 49 | 50 | printf("
"); 51 | 52 | fflush(stdout); 53 | } 54 | 55 | // Initialize and free objects, called by chl_fcgi_init 56 | void _error_init() { 57 | errors_size = 0; 58 | 59 | free(ERRORS); 60 | free(_alloce_); 61 | 62 | ERRORS = NULL; 63 | _alloce_ = NULL; 64 | } 65 | -------------------------------------------------------------------------------- /core/src/error.h: -------------------------------------------------------------------------------- 1 | #ifndef ERROR_H_ 2 | #define ERROR_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Whether to compile as FastCGI 8 | #ifdef _F_CHL_ 9 | #include "fcgi_stdio.h" 10 | #endif 11 | 12 | 13 | #define CHL_E_FILENF 0 // Error: file not found 14 | #define CHL_E_FILEINT 1 // Error: opening of file interrupted by signal 15 | #define CHL_E_FILESIZE 2 // Error: file too large 16 | #define CHL_E_NOTERMIN 3 // Error: no inline code terminator 17 | #define CHL_E_NOTERMFUNC 4 // Error: no function code terminator 18 | #define CHL_E_UNEXV 5 // Error: no clear end of variable name 19 | #define CHL_E_UNKFUNC 6 // Error: unknown function 20 | #define CHL_E_MYSQL 7 // Error: MySQL error 21 | 22 | void error_append(char, char *); 23 | void chl_print_errors(); 24 | void _error_init(); 25 | 26 | // Dynamically allocated variable for error string 27 | extern char * _alloce_; 28 | 29 | // Macro to dynamically allocate an error string and pass it to error_append 30 | #define chl_error_append(id, ...) snprintf((_alloce_ = malloc(100)), 100, __VA_ARGS__), error_append(id, _alloce_); 31 | 32 | #endif /* ERROR_H_ */ 33 | -------------------------------------------------------------------------------- /core/src/fastcgi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This source file's purpose is to call functions to initialize and free data 3 | * inside other source files, and to provide support for FastCGI 4 | * 5 | * Put source init functions inside chl_fcgi_init 6 | */ 7 | 8 | #include "cgi.h" 9 | #include "error.h" 10 | #include "http.h" 11 | #include "inline.h" 12 | #include "fastcgi.h" 13 | #include "fcgi_stdio.h" 14 | 15 | // Call the init function of source files 16 | void chl_fcgi_init() { 17 | _cgi_init(); 18 | _error_init(); 19 | _http_init(); 20 | _inline_init(); 21 | } 22 | 23 | // Accept next client using FastCGI, caller should run in a loop 24 | char chl_fcgi_next() { 25 | chl_fcgi_init(); 26 | 27 | if(FCGI_Accept() >= 0) 28 | return 1; 29 | 30 | return 0; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /core/src/fastcgi.h: -------------------------------------------------------------------------------- 1 | #ifndef FASTCGI_H_ 2 | #define FASTCGI_H_ 3 | 4 | void chl_fcgi_init(); 5 | char chl_fcgi_next(); 6 | 7 | #endif /* FASTCGI_H_ */ 8 | -------------------------------------------------------------------------------- /core/src/fcgi_stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef _FCGI_STDIO 2 | #define _FCGI_STDIO 1 3 | 4 | #include 5 | #include 6 | #include "fcgiapp.h" 7 | 8 | #if defined (c_plusplus) || defined (__cplusplus) 9 | extern "C" { 10 | #endif 11 | 12 | #ifndef DLLAPI 13 | #ifdef _WIN32 14 | #define DLLAPI __declspec(dllimport) 15 | #else 16 | #define DLLAPI 17 | #endif 18 | #endif 19 | 20 | /* 21 | * Wrapper type for FILE 22 | */ 23 | 24 | typedef struct { 25 | FILE *stdio_stream; 26 | FCGX_Stream *fcgx_stream; 27 | } FCGI_FILE; 28 | 29 | /* 30 | * The four new functions and two new macros 31 | */ 32 | 33 | DLLAPI int FCGI_Accept(void); 34 | DLLAPI void FCGI_Finish(void); 35 | DLLAPI int FCGI_StartFilterData(void); 36 | DLLAPI void FCGI_SetExitStatus(int status); 37 | 38 | #define FCGI_ToFILE(fcgi_file) (fcgi_file->stdio_stream) 39 | #define FCGI_ToFcgiStream(fcgi_file) (fcgi_file->fcgx_stream) 40 | 41 | /* 42 | * Wrapper stdin, stdout, and stderr variables, set up by FCGI_Accept() 43 | */ 44 | 45 | DLLAPI extern FCGI_FILE _fcgi_sF[]; 46 | #define FCGI_stdin (&_fcgi_sF[0]) 47 | #define FCGI_stdout (&_fcgi_sF[1]) 48 | #define FCGI_stderr (&_fcgi_sF[2]) 49 | 50 | /* 51 | * Wrapper function prototypes, grouped according to sections 52 | * of Harbison & Steele, "C: A Reference Manual," fourth edition, 53 | * Prentice-Hall, 1995. 54 | */ 55 | 56 | DLLAPI void FCGI_perror(const char *str); 57 | 58 | DLLAPI FCGI_FILE *FCGI_fopen(const char *path, const char *mode); 59 | DLLAPI int FCGI_fclose(FCGI_FILE *fp); 60 | DLLAPI int FCGI_fflush(FCGI_FILE *fp); 61 | DLLAPI FCGI_FILE *FCGI_freopen(const char *path, const char *mode, FCGI_FILE *fp); 62 | 63 | DLLAPI int FCGI_setvbuf(FCGI_FILE *fp, char *buf, int bufmode, size_t size); 64 | DLLAPI void FCGI_setbuf(FCGI_FILE *fp, char *buf); 65 | 66 | DLLAPI int FCGI_fseek(FCGI_FILE *fp, long offset, int whence); 67 | DLLAPI int FCGI_ftell(FCGI_FILE *fp); 68 | DLLAPI void FCGI_rewind(FCGI_FILE *fp); 69 | #ifdef HAVE_FPOS 70 | DLLAPI int FCGI_fgetpos(FCGI_FILE *fp, fpos_t *pos); 71 | DLLAPI int FCGI_fsetpos(FCGI_FILE *fp, const fpos_t *pos); 72 | #endif 73 | DLLAPI int FCGI_fgetc(FCGI_FILE *fp); 74 | DLLAPI int FCGI_getchar(void); 75 | DLLAPI int FCGI_ungetc(int c, FCGI_FILE *fp); 76 | 77 | DLLAPI char *FCGI_fgets(char *str, int size, FCGI_FILE *fp); 78 | DLLAPI char *FCGI_gets(char *str); 79 | 80 | /* 81 | * Not yet implemented 82 | * 83 | * int FCGI_fscanf(FCGI_FILE *fp, const char *format, ...); 84 | * int FCGI_scanf(const char *format, ...); 85 | * 86 | */ 87 | 88 | DLLAPI int FCGI_fputc(int c, FCGI_FILE *fp); 89 | DLLAPI int FCGI_putchar(int c); 90 | 91 | DLLAPI int FCGI_fputs(const char *str, FCGI_FILE *fp); 92 | DLLAPI int FCGI_puts(const char *str); 93 | 94 | DLLAPI int FCGI_fprintf(FCGI_FILE *fp, const char *format, ...); 95 | DLLAPI int FCGI_printf(const char *format, ...); 96 | 97 | DLLAPI int FCGI_vfprintf(FCGI_FILE *fp, const char *format, va_list ap); 98 | DLLAPI int FCGI_vprintf(const char *format, va_list ap); 99 | 100 | DLLAPI size_t FCGI_fread(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp); 101 | DLLAPI size_t FCGI_fwrite(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp); 102 | 103 | DLLAPI int FCGI_feof(FCGI_FILE *fp); 104 | DLLAPI int FCGI_ferror(FCGI_FILE *fp); 105 | DLLAPI void FCGI_clearerr(FCGI_FILE *fp); 106 | 107 | DLLAPI FCGI_FILE *FCGI_tmpfile(void); 108 | 109 | DLLAPI int FCGI_fileno(FCGI_FILE *fp); 110 | DLLAPI FCGI_FILE *FCGI_fdopen(int fd, const char *mode); 111 | DLLAPI FCGI_FILE *FCGI_popen(const char *cmd, const char *type); 112 | DLLAPI int FCGI_pclose(FCGI_FILE *); 113 | 114 | /* 115 | * The remaining definitions are for application programs, 116 | * not for fcgi_stdio.c 117 | */ 118 | 119 | #ifndef NO_FCGI_DEFINES 120 | 121 | /* 122 | * Replace standard types, variables, and functions with FastCGI wrappers. 123 | * Use undef in case a macro is already defined. 124 | */ 125 | 126 | #undef FILE 127 | #define FILE FCGI_FILE 128 | 129 | #undef stdin 130 | #define stdin FCGI_stdin 131 | #undef stdout 132 | #define stdout FCGI_stdout 133 | #undef stderr 134 | #define stderr FCGI_stderr 135 | 136 | #undef perror 137 | #define perror FCGI_perror 138 | 139 | #undef fopen 140 | #define fopen FCGI_fopen 141 | #undef fclose 142 | #define fclose FCGI_fclose 143 | #undef fflush 144 | #define fflush FCGI_fflush 145 | #undef freopen 146 | #define freopen FCGI_freopen 147 | 148 | #undef setvbuf 149 | #define setvbuf FCGI_setvbuf 150 | #undef setbuf 151 | #define setbuf FCGI_setbuf 152 | 153 | #undef fseek 154 | #define fseek FCGI_fseek 155 | #undef ftell 156 | #define ftell FCGI_ftell 157 | #undef rewind 158 | #define rewind FCGI_rewind 159 | #undef fgetpos 160 | #define fgetpos FCGI_fgetpos 161 | #undef fsetpos 162 | #define fsetpos FCGI_fsetpos 163 | 164 | #undef fgetc 165 | #define fgetc FCGI_fgetc 166 | #undef getc 167 | #define getc FCGI_fgetc 168 | #undef getchar 169 | #define getchar FCGI_getchar 170 | #undef ungetc 171 | #define ungetc FCGI_ungetc 172 | 173 | #undef fgets 174 | #define fgets FCGI_fgets 175 | #undef gets 176 | #define gets FCGI_gets 177 | 178 | #undef fputc 179 | #define fputc FCGI_fputc 180 | #undef putc 181 | #define putc FCGI_fputc 182 | #undef putchar 183 | #define putchar FCGI_putchar 184 | 185 | #undef fputs 186 | #define fputs FCGI_fputs 187 | #undef puts 188 | #define puts FCGI_puts 189 | 190 | #undef fprintf 191 | #define fprintf FCGI_fprintf 192 | #undef printf 193 | #define printf FCGI_printf 194 | 195 | #undef vfprintf 196 | #define vfprintf FCGI_vfprintf 197 | #undef vprintf 198 | #define vprintf FCGI_vprintf 199 | 200 | #undef fread 201 | #define fread FCGI_fread 202 | #undef fwrite 203 | #define fwrite FCGI_fwrite 204 | 205 | #undef feof 206 | #define feof FCGI_feof 207 | #undef ferror 208 | #define ferror FCGI_ferror 209 | #undef clearerr 210 | #define clearerr FCGI_clearerr 211 | 212 | #undef tmpfile 213 | #define tmpfile FCGI_tmpfile 214 | 215 | #undef fileno 216 | #define fileno FCGI_fileno 217 | #undef fdopen 218 | #define fdopen FCGI_fdopen 219 | #undef popen 220 | #define popen FCGI_popen 221 | #undef pclose 222 | #define pclose FCGI_pclose 223 | 224 | #endif /* NO_FCGI_DEFINES */ 225 | 226 | #if defined (__cplusplus) || defined (c_plusplus) 227 | } /* terminate extern "C" { */ 228 | #endif 229 | 230 | #endif /* _FCGI_STDIO */ 231 | 232 | -------------------------------------------------------------------------------- /core/src/fcgiapp.h: -------------------------------------------------------------------------------- 1 | #ifndef _FCGIAPP_H 2 | #define _FCGIAPP_H 3 | 4 | /* Hack to see if we are building TCL - TCL needs varargs not stdarg */ 5 | #ifndef TCL_LIBRARY 6 | #include 7 | #else 8 | #include 9 | #endif 10 | 11 | #ifndef DLLAPI 12 | #ifdef _WIN32 13 | #define DLLAPI __declspec(dllimport) 14 | #else 15 | #define DLLAPI 16 | #endif 17 | #endif 18 | 19 | #if defined (c_plusplus) || defined (__cplusplus) 20 | extern "C" { 21 | #endif 22 | 23 | /* 24 | * Error codes. Assigned to avoid conflict with EOF and errno(2). 25 | */ 26 | #define FCGX_UNSUPPORTED_VERSION -2 27 | #define FCGX_PROTOCOL_ERROR -3 28 | #define FCGX_PARAMS_ERROR -4 29 | #define FCGX_CALL_SEQ_ERROR -5 30 | 31 | /* 32 | * This structure defines the state of a FastCGI stream. 33 | * Streams are modeled after the FILE type defined in stdio.h. 34 | * (We wouldn't need our own if platform vendors provided a 35 | * standard way to subclass theirs.) 36 | * The state of a stream is private and should only be accessed 37 | * by the procedures defined below. 38 | */ 39 | typedef struct FCGX_Stream { 40 | unsigned char *rdNext; /* reader: first valid byte 41 | * writer: equals stop */ 42 | unsigned char *wrNext; /* writer: first free byte 43 | * reader: equals stop */ 44 | unsigned char *stop; /* reader: last valid byte + 1 45 | * writer: last free byte + 1 */ 46 | unsigned char *stopUnget; /* reader: first byte of current buffer 47 | * fragment, for ungetc 48 | * writer: undefined */ 49 | int isReader; 50 | int isClosed; 51 | int wasFCloseCalled; 52 | int FCGI_errno; /* error status */ 53 | void (*fillBuffProc) (struct FCGX_Stream *stream); 54 | void (*emptyBuffProc) (struct FCGX_Stream *stream, int doClose); 55 | void *data; 56 | } FCGX_Stream; 57 | 58 | /* 59 | * An environment (as defined by environ(7)): A NULL-terminated array 60 | * of strings, each string having the form name=value. 61 | */ 62 | typedef char **FCGX_ParamArray; 63 | 64 | /* 65 | * FCGX_Request Flags 66 | * 67 | * Setting FCGI_FAIL_ACCEPT_ON_INTR prevents FCGX_Accept() from 68 | * restarting upon being interrupted. 69 | */ 70 | #define FCGI_FAIL_ACCEPT_ON_INTR 1 71 | 72 | /* 73 | * FCGX_Request -- State associated with a request. 74 | * 75 | * Its exposed for API simplicity, I expect parts of it to change! 76 | */ 77 | typedef struct FCGX_Request { 78 | int requestId; /* valid if isBeginProcessed */ 79 | int role; 80 | FCGX_Stream *in; 81 | FCGX_Stream *out; 82 | FCGX_Stream *err; 83 | char **envp; 84 | 85 | /* Don't use anything below here */ 86 | 87 | struct Params *paramsPtr; 88 | int ipcFd; /* < 0 means no connection */ 89 | int isBeginProcessed; /* FCGI_BEGIN_REQUEST seen */ 90 | int keepConnection; /* don't close ipcFd at end of request */ 91 | int appStatus; 92 | int nWriters; /* number of open writers (0..2) */ 93 | int flags; 94 | int listen_sock; 95 | } FCGX_Request; 96 | 97 | 98 | /* 99 | *====================================================================== 100 | * Control 101 | *====================================================================== 102 | */ 103 | 104 | /* 105 | *---------------------------------------------------------------------- 106 | * 107 | * FCGX_IsCGI -- 108 | * 109 | * Returns TRUE iff this process appears to be a CGI process 110 | * rather than a FastCGI process. 111 | * 112 | *---------------------------------------------------------------------- 113 | */ 114 | DLLAPI int FCGX_IsCGI(void); 115 | 116 | /* 117 | *---------------------------------------------------------------------- 118 | * 119 | * FCGX_Init -- 120 | * 121 | * Initialize the FCGX library. Call in multi-threaded apps 122 | * before calling FCGX_Accept_r(). 123 | * 124 | * Returns 0 upon success. 125 | * 126 | *---------------------------------------------------------------------- 127 | */ 128 | DLLAPI int FCGX_Init(void); 129 | 130 | /* 131 | *---------------------------------------------------------------------- 132 | * 133 | * FCGX_OpenSocket -- 134 | * 135 | * Create a FastCGI listen socket. 136 | * 137 | * path is the Unix domain socket (named pipe for WinNT), or a colon 138 | * followed by a port number. e.g. "/tmp/fastcgi/mysocket", ":5000" 139 | * 140 | * backlog is the listen queue depth used in the listen() call. 141 | * 142 | * Returns the socket's file descriptor or -1 on error. 143 | * 144 | *---------------------------------------------------------------------- 145 | */ 146 | DLLAPI int FCGX_OpenSocket(const char *path, int backlog); 147 | 148 | /* 149 | *---------------------------------------------------------------------- 150 | * 151 | * FCGX_InitRequest -- 152 | * 153 | * Initialize a FCGX_Request for use with FCGX_Accept_r(). 154 | * 155 | * sock is a file descriptor returned by FCGX_OpenSocket() or 0 (default). 156 | * The only supported flag at this time is FCGI_FAIL_ON_INTR. 157 | * 158 | * Returns 0 upon success. 159 | *---------------------------------------------------------------------- 160 | */ 161 | DLLAPI int FCGX_InitRequest(FCGX_Request *request, int sock, int flags); 162 | 163 | /* 164 | *---------------------------------------------------------------------- 165 | * 166 | * FCGX_Accept_r -- 167 | * 168 | * Accept a new request (multi-thread safe). Be sure to call 169 | * FCGX_Init() first. 170 | * 171 | * Results: 172 | * 0 for successful call, -1 for error. 173 | * 174 | * Side effects: 175 | * 176 | * Finishes the request accepted by (and frees any 177 | * storage allocated by) the previous call to FCGX_Accept. 178 | * Creates input, output, and error streams and 179 | * assigns them to *in, *out, and *err respectively. 180 | * Creates a parameters data structure to be accessed 181 | * via getenv(3) (if assigned to environ) or by FCGX_GetParam 182 | * and assigns it to *envp. 183 | * 184 | * DO NOT retain pointers to the envp array or any strings 185 | * contained in it (e.g. to the result of calling FCGX_GetParam), 186 | * since these will be freed by the next call to FCGX_Finish 187 | * or FCGX_Accept. 188 | * 189 | * DON'T use the FCGX_Request, its structure WILL change. 190 | * 191 | *---------------------------------------------------------------------- 192 | */ 193 | DLLAPI int FCGX_Accept_r(FCGX_Request *request); 194 | 195 | /* 196 | *---------------------------------------------------------------------- 197 | * 198 | * FCGX_Finish_r -- 199 | * 200 | * Finish the request (multi-thread safe). 201 | * 202 | * Side effects: 203 | * 204 | * Finishes the request accepted by (and frees any 205 | * storage allocated by) the previous call to FCGX_Accept. 206 | * 207 | * DO NOT retain pointers to the envp array or any strings 208 | * contained in it (e.g. to the result of calling FCGX_GetParam), 209 | * since these will be freed by the next call to FCGX_Finish 210 | * or FCGX_Accept. 211 | * 212 | *---------------------------------------------------------------------- 213 | */ 214 | DLLAPI void FCGX_Finish_r(FCGX_Request *request); 215 | 216 | /* 217 | *---------------------------------------------------------------------- 218 | * 219 | * FCGX_Free -- 220 | * 221 | * Free the memory and, if close is true, 222 | * IPC FD associated with the request (multi-thread safe). 223 | * 224 | *---------------------------------------------------------------------- 225 | */ 226 | DLLAPI void FCGX_Free(FCGX_Request * request, int close); 227 | 228 | /* 229 | *---------------------------------------------------------------------- 230 | * 231 | * FCGX_Accept -- 232 | * 233 | * Accept a new request (NOT multi-thread safe). 234 | * 235 | * Results: 236 | * 0 for successful call, -1 for error. 237 | * 238 | * Side effects: 239 | * 240 | * Finishes the request accepted by (and frees any 241 | * storage allocated by) the previous call to FCGX_Accept. 242 | * Creates input, output, and error streams and 243 | * assigns them to *in, *out, and *err respectively. 244 | * Creates a parameters data structure to be accessed 245 | * via getenv(3) (if assigned to environ) or by FCGX_GetParam 246 | * and assigns it to *envp. 247 | * 248 | * DO NOT retain pointers to the envp array or any strings 249 | * contained in it (e.g. to the result of calling FCGX_GetParam), 250 | * since these will be freed by the next call to FCGX_Finish 251 | * or FCGX_Accept. 252 | * 253 | *---------------------------------------------------------------------- 254 | */ 255 | DLLAPI int FCGX_Accept( 256 | FCGX_Stream **in, 257 | FCGX_Stream **out, 258 | FCGX_Stream **err, 259 | FCGX_ParamArray *envp); 260 | 261 | /* 262 | *---------------------------------------------------------------------- 263 | * 264 | * FCGX_Finish -- 265 | * 266 | * Finish the current request (NOT multi-thread safe). 267 | * 268 | * Side effects: 269 | * 270 | * Finishes the request accepted by (and frees any 271 | * storage allocated by) the previous call to FCGX_Accept. 272 | * 273 | * DO NOT retain pointers to the envp array or any strings 274 | * contained in it (e.g. to the result of calling FCGX_GetParam), 275 | * since these will be freed by the next call to FCGX_Finish 276 | * or FCGX_Accept. 277 | * 278 | *---------------------------------------------------------------------- 279 | */ 280 | DLLAPI void FCGX_Finish(void); 281 | 282 | /* 283 | *---------------------------------------------------------------------- 284 | * 285 | * FCGX_StartFilterData -- 286 | * 287 | * stream is an input stream for a FCGI_FILTER request. 288 | * stream is positioned at EOF on FCGI_STDIN. 289 | * Repositions stream to the start of FCGI_DATA. 290 | * If the preconditions are not met (e.g. FCGI_STDIN has not 291 | * been read to EOF) sets the stream error code to 292 | * FCGX_CALL_SEQ_ERROR. 293 | * 294 | * Results: 295 | * 0 for a normal return, < 0 for error 296 | * 297 | *---------------------------------------------------------------------- 298 | */ 299 | DLLAPI int FCGX_StartFilterData(FCGX_Stream *stream); 300 | 301 | /* 302 | *---------------------------------------------------------------------- 303 | * 304 | * FCGX_SetExitStatus -- 305 | * 306 | * Sets the exit status for stream's request. The exit status 307 | * is the status code the request would have exited with, had 308 | * the request been run as a CGI program. You can call 309 | * SetExitStatus several times during a request; the last call 310 | * before the request ends determines the value. 311 | * 312 | *---------------------------------------------------------------------- 313 | */ 314 | DLLAPI void FCGX_SetExitStatus(int status, FCGX_Stream *stream); 315 | 316 | /* 317 | *====================================================================== 318 | * Parameters 319 | *====================================================================== 320 | */ 321 | 322 | /* 323 | *---------------------------------------------------------------------- 324 | * 325 | * FCGX_GetParam -- obtain value of FCGI parameter in environment 326 | * 327 | * 328 | * Results: 329 | * Value bound to name, NULL if name not present in the 330 | * environment envp. Caller must not mutate the result 331 | * or retain it past the end of this request. 332 | * 333 | *---------------------------------------------------------------------- 334 | */ 335 | DLLAPI char *FCGX_GetParam(const char *name, FCGX_ParamArray envp); 336 | 337 | /* 338 | *====================================================================== 339 | * Readers 340 | *====================================================================== 341 | */ 342 | 343 | /* 344 | *---------------------------------------------------------------------- 345 | * 346 | * FCGX_GetChar -- 347 | * 348 | * Reads a byte from the input stream and returns it. 349 | * 350 | * Results: 351 | * The byte, or EOF (-1) if the end of input has been reached. 352 | * 353 | *---------------------------------------------------------------------- 354 | */ 355 | DLLAPI int FCGX_GetChar(FCGX_Stream *stream); 356 | 357 | /* 358 | *---------------------------------------------------------------------- 359 | * 360 | * FCGX_UnGetChar -- 361 | * 362 | * Pushes back the character c onto the input stream. One 363 | * character of pushback is guaranteed once a character 364 | * has been read. No pushback is possible for EOF. 365 | * 366 | * Results: 367 | * Returns c if the pushback succeeded, EOF if not. 368 | * 369 | *---------------------------------------------------------------------- 370 | */ 371 | DLLAPI int FCGX_UnGetChar(int c, FCGX_Stream *stream); 372 | 373 | /* 374 | *---------------------------------------------------------------------- 375 | * 376 | * FCGX_GetStr -- 377 | * 378 | * Reads up to n consecutive bytes from the input stream 379 | * into the character array str. Performs no interpretation 380 | * of the input bytes. 381 | * 382 | * Results: 383 | * Number of bytes read. If result is smaller than n, 384 | * the end of input has been reached. 385 | * 386 | *---------------------------------------------------------------------- 387 | */ 388 | DLLAPI int FCGX_GetStr(char *str, int n, FCGX_Stream *stream); 389 | 390 | /* 391 | *---------------------------------------------------------------------- 392 | * 393 | * FCGX_GetLine -- 394 | * 395 | * Reads up to n-1 consecutive bytes from the input stream 396 | * into the character array str. Stops before n-1 bytes 397 | * have been read if '\n' or EOF is read. The terminating '\n' 398 | * is copied to str. After copying the last byte into str, 399 | * stores a '\0' terminator. 400 | * 401 | * Results: 402 | * NULL if EOF is the first thing read from the input stream, 403 | * str otherwise. 404 | * 405 | *---------------------------------------------------------------------- 406 | */ 407 | DLLAPI char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream); 408 | 409 | /* 410 | *---------------------------------------------------------------------- 411 | * 412 | * FCGX_HasSeenEOF -- 413 | * 414 | * Returns EOF if end-of-file has been detected while reading 415 | * from stream; otherwise returns 0. 416 | * 417 | * Note that FCGX_HasSeenEOF(s) may return 0, yet an immediately 418 | * following FCGX_GetChar(s) may return EOF. This function, like 419 | * the standard C stdio function feof, does not provide the 420 | * ability to peek ahead. 421 | * 422 | * Results: 423 | * EOF if end-of-file has been detected, 0 if not. 424 | * 425 | *---------------------------------------------------------------------- 426 | */ 427 | 428 | DLLAPI int FCGX_HasSeenEOF(FCGX_Stream *stream); 429 | 430 | /* 431 | *====================================================================== 432 | * Writers 433 | *====================================================================== 434 | */ 435 | 436 | /* 437 | *---------------------------------------------------------------------- 438 | * 439 | * FCGX_PutChar -- 440 | * 441 | * Writes a byte to the output stream. 442 | * 443 | * Results: 444 | * The byte, or EOF (-1) if an error occurred. 445 | * 446 | *---------------------------------------------------------------------- 447 | */ 448 | DLLAPI int FCGX_PutChar(int c, FCGX_Stream *stream); 449 | 450 | /* 451 | *---------------------------------------------------------------------- 452 | * 453 | * FCGX_PutStr -- 454 | * 455 | * Writes n consecutive bytes from the character array str 456 | * into the output stream. Performs no interpretation 457 | * of the output bytes. 458 | * 459 | * Results: 460 | * Number of bytes written (n) for normal return, 461 | * EOF (-1) if an error occurred. 462 | * 463 | *---------------------------------------------------------------------- 464 | */ 465 | DLLAPI int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream); 466 | 467 | /* 468 | *---------------------------------------------------------------------- 469 | * 470 | * FCGX_PutS -- 471 | * 472 | * Writes a null-terminated character string to the output stream. 473 | * 474 | * Results: 475 | * number of bytes written for normal return, 476 | * EOF (-1) if an error occurred. 477 | * 478 | *---------------------------------------------------------------------- 479 | */ 480 | DLLAPI int FCGX_PutS(const char *str, FCGX_Stream *stream); 481 | 482 | /* 483 | *---------------------------------------------------------------------- 484 | * 485 | * FCGX_FPrintF, FCGX_VFPrintF -- 486 | * 487 | * Performs printf-style output formatting and writes the results 488 | * to the output stream. 489 | * 490 | * Results: 491 | * number of bytes written for normal return, 492 | * EOF (-1) if an error occurred. 493 | * 494 | *---------------------------------------------------------------------- 495 | */ 496 | DLLAPI int FCGX_FPrintF(FCGX_Stream *stream, const char *format, ...); 497 | 498 | DLLAPI int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg); 499 | 500 | /* 501 | *---------------------------------------------------------------------- 502 | * 503 | * FCGX_FFlush -- 504 | * 505 | * Flushes any buffered output. 506 | * 507 | * Server-push is a legitimate application of FCGX_FFlush. 508 | * Otherwise, FCGX_FFlush is not very useful, since FCGX_Accept 509 | * does it implicitly. Calling FCGX_FFlush in non-push applications 510 | * results in extra writes and therefore reduces performance. 511 | * 512 | * Results: 513 | * EOF (-1) if an error occurred. 514 | * 515 | *---------------------------------------------------------------------- 516 | */ 517 | DLLAPI int FCGX_FFlush(FCGX_Stream *stream); 518 | 519 | /* 520 | *====================================================================== 521 | * Both Readers and Writers 522 | *====================================================================== 523 | */ 524 | 525 | /* 526 | *---------------------------------------------------------------------- 527 | * 528 | * FCGX_FClose -- 529 | * 530 | * Closes the stream. For writers, flushes any buffered 531 | * output. 532 | * 533 | * Close is not a very useful operation since FCGX_Accept 534 | * does it implicitly. Closing the out stream before the 535 | * err stream results in an extra write if there's nothing 536 | * in the err stream, and therefore reduces performance. 537 | * 538 | * Results: 539 | * EOF (-1) if an error occurred. 540 | * 541 | *---------------------------------------------------------------------- 542 | */ 543 | DLLAPI int FCGX_FClose(FCGX_Stream *stream); 544 | 545 | /* 546 | *---------------------------------------------------------------------- 547 | * 548 | * FCGX_GetError -- 549 | * 550 | * Return the stream error code. 0 means no error, > 0 551 | * is an errno(2) error, < 0 is an FastCGI error. 552 | * 553 | *---------------------------------------------------------------------- 554 | */ 555 | DLLAPI int FCGX_GetError(FCGX_Stream *stream); 556 | 557 | /* 558 | *---------------------------------------------------------------------- 559 | * 560 | * FCGX_ClearError -- 561 | * 562 | * Clear the stream error code and end-of-file indication. 563 | * 564 | *---------------------------------------------------------------------- 565 | */ 566 | DLLAPI void FCGX_ClearError(FCGX_Stream *stream); 567 | 568 | /* 569 | *---------------------------------------------------------------------- 570 | * 571 | * FCGX_CreateWriter -- 572 | * 573 | * Create a FCGX_Stream (used by cgi-fcgi). This shouldn't 574 | * be needed by a FastCGI applictaion. 575 | * 576 | *---------------------------------------------------------------------- 577 | */ 578 | DLLAPI FCGX_Stream *FCGX_CreateWriter( 579 | int socket, 580 | int requestId, 581 | int bufflen, 582 | int streamType); 583 | 584 | /* 585 | *---------------------------------------------------------------------- 586 | * 587 | * FCGX_FreeStream -- 588 | * 589 | * Free a FCGX_Stream (used by cgi-fcgi). This shouldn't 590 | * be needed by a FastCGI applictaion. 591 | * 592 | *---------------------------------------------------------------------- 593 | */ 594 | DLLAPI void FCGX_FreeStream(FCGX_Stream **stream); 595 | 596 | /* ---------------------------------------------------------------------- 597 | * 598 | * Prevent the lib from accepting any new requests. Signal handler safe. 599 | * 600 | * ---------------------------------------------------------------------- 601 | */ 602 | DLLAPI void FCGX_ShutdownPending(void); 603 | 604 | #if defined (__cplusplus) || defined (c_plusplus) 605 | } /* terminate extern "C" { */ 606 | #endif 607 | 608 | #endif /* _FCGIAPP_H */ 609 | -------------------------------------------------------------------------------- /core/src/http.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This source file's purpose is to provide functions for reading and manipulating 3 | * HTTP headers and data, cookies 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "http.h" 10 | #include "std.h" 11 | 12 | // Implemented from cgi.c 13 | extern char * get_env(char *); 14 | 15 | #define HEADER_X_POW_BY "CHL" // Default x-powered-by header 16 | #define HEADER_CON_TYPE "text/html" // Default content-type header 17 | #define COOKIES_DATA_ENV "HTTP_COOKIE" // Cookies environment variable 18 | 19 | // A struct to hold HTTP variables (headers, cookies) 20 | typedef struct { 21 | char * name; 22 | char * value; 23 | } HTTP_VAR; 24 | 25 | static HTTP_VAR * HEADERS = NULL; // Struct array for HTTP header variables, dynamically allocated 26 | static HTTP_VAR * COOKIES = NULL; // Struct array for HTTP cookies, dynamically allocated 27 | 28 | static unsigned char headers_size = 0; // The amount of headers in [HEADERS] 29 | static unsigned char cookies_size = 0; // The amount of cookies in [COOKIES] 30 | 31 | static char headers_used = 0; // Whether headers have been printed 32 | static char cookies_used = 0; // Whether cookies have been parsed or not 33 | 34 | static char * raw_data_cookies = NULL; // Buffer for cookies data, dynamically allocated 35 | 36 | // Add header element to [HEADERS] array 37 | void chl_set_header(char * name, char * value) { 38 | char * value_pt; // Points to last value if header already set 39 | 40 | // Has header already been set 41 | if((value_pt = chl_get_header(name)) != NULL) { 42 | value_pt = value; 43 | return; 44 | } 45 | 46 | // Allocate memory for new header 47 | HEADERS = std_realloc(HEADERS, ++headers_size * sizeof(HTTP_VAR)); 48 | 49 | // Set header properties 50 | HEADERS[headers_size - 1].name = name; 51 | HEADERS[headers_size - 1].value = value; 52 | } 53 | 54 | // Returns [name]'s value in [HEADERS] array 55 | char * chl_get_header(char * name) { 56 | // Check if [HEADERS] array is initialized to prevent error 57 | if(! headers_size) 58 | return 0; 59 | 60 | int i, x; 61 | 62 | // Loop through every index in [HEADERS] array until [name] is found 63 | for(i = 0; (i < headers_size) && (x = strcmp(HEADERS[i].name, name)); i++); 64 | 65 | // Found a matching value for [name] 66 | if(!x) 67 | return HEADERS[i].value; 68 | 69 | // Did not find a match 70 | return 0; 71 | } 72 | 73 | // Output headers in [HEADERS] 74 | void chl_print_headers() { 75 | // Prevent multiple outputs of headers 76 | if(headers_used) 77 | return; 78 | 79 | int i; 80 | 81 | // Loop through [HEADERS] array and output name and value 82 | for(i = 0; i < headers_size; i++) 83 | printf("%s: %s\n", HEADERS[i].name, HEADERS[i].value); 84 | 85 | // Terminate headers, \n\n 86 | puts(""); 87 | 88 | headers_used = 1; 89 | } 90 | 91 | // Set default HTTP headers 92 | void chl_set_default_headers() { 93 | // Allocate memory for new headers 94 | HEADERS = std_realloc(HEADERS, (++headers_size + 1) * sizeof(HTTP_VAR)); 95 | 96 | // Set default content-type header properties 97 | HEADERS[headers_size - 1].name = "Content-Type"; 98 | HEADERS[headers_size - 1].value = HEADER_CON_TYPE; 99 | 100 | // Set default x-powered-by header properties 101 | HEADERS[headers_size].name = "X-Powered-By"; 102 | HEADERS[headers_size++].value = HEADER_X_POW_BY; 103 | } 104 | 105 | // Initialize [COOKIES] array and cookies data 106 | void http_cookies_init() { 107 | // Prevent function from being called multiple times 108 | if(cookies_used) 109 | return; 110 | 111 | // Assign [raw_data_cookies] its value 112 | raw_data_cookies = get_env(COOKIES_DATA_ENV); 113 | 114 | // Append temporary blank variable to [COOKIES] array to prevent NULL error, overwritten 115 | cookies_append_var(" ", " "); 116 | 117 | // Split data into variables 118 | format_cookies_data(); 119 | 120 | cookies_used = 1; 121 | } 122 | 123 | // Format cookies data and split into variables in [COOKIES] array 124 | void format_cookies_data() { 125 | char * data = raw_data_cookies; // Cookies data pointer 126 | char * var_name, * var_value; // Pointer to variable in [data] 127 | char * last_var; // Last occurrence of ';', or start of string [data] 128 | 129 | last_var = data; 130 | var_name = data; 131 | 132 | // Loop through data and split into variables 133 | while(*data != '\0') { 134 | // If new variable 135 | if((*data == ':') || (*data == '=')) { 136 | // Set end of variable name 137 | *data++ = '\0'; 138 | 139 | // Skip first spaces 140 | while(*data == ' ') 141 | data++; 142 | 143 | var_name = last_var; 144 | var_value = data; 145 | 146 | // Loop to next variable, next occurrence of ';' 147 | while((*data != ';') && (*data != '\0')) 148 | data++; 149 | 150 | // Set end of variable value 151 | if(*data != '\0') { 152 | *data = '\0'; 153 | last_var = (data++ + 2); 154 | } 155 | 156 | // Append variable to [COOKIES] array 157 | cookies_append_var(var_name, var_value); 158 | } 159 | 160 | // Continue if just letter 161 | else 162 | data++; 163 | } 164 | } 165 | 166 | // Append cookie variable to [COOKIES] array 167 | void cookies_append_var(char * name, char * value) { 168 | // Prevent char overflow, a greater number than 512 169 | if(cookies_size >= 510) 170 | return; 171 | 172 | // Allocate memory for new variable 173 | COOKIES = std_realloc(COOKIES, ++cookies_size * sizeof(HTTP_VAR)); 174 | 175 | // Set variable properties 176 | COOKIES[cookies_size - 1].name = name; 177 | COOKIES[cookies_size - 1].value = value; 178 | } 179 | 180 | // Returns variable [name]'s value in [COOKIES] data array 181 | char * chl_cookies(char * name) { 182 | // Check if [COOKIES] array has been initialized 183 | if(! cookies_used) 184 | http_cookies_init(); 185 | 186 | int i, x; 187 | 188 | // Loop through every index in [HEADERS] array until [name] is found 189 | for(i = 0; (i < cookies_size) && (x = strcmp(COOKIES[i].name, name)); i++); 190 | 191 | // Found a matching value for [name] 192 | if(!x) 193 | return COOKIES[i].value; 194 | 195 | // Did not find a match 196 | return 0; 197 | } 198 | 199 | // Set and output cookie 200 | void chl_set_cookie(char * name, char * value, char * expires) { 201 | // If headers have not been printed 202 | if(! headers_used) { 203 | // Session cookie 204 | if(expires == NULL) 205 | printf("Set-Cookie: %s=%s;\n", name, value); 206 | else 207 | printf("Set-Cookie: %s=%s; expires=%s\n", name, value, expires); 208 | } 209 | } 210 | 211 | // Delete cookie 212 | void chl_delete_cookie(char * name) { 213 | // If headers have not been printed 214 | if(! headers_used) 215 | printf("Set-Cookie: %s=; expires=Thu, 01 Jan 1970 00:00:00 GMT\n", name); 216 | 217 | } 218 | 219 | // Initialize and free objects, called by chl_fcgi_init 220 | void _http_init() { 221 | headers_size = 0; 222 | headers_used = 0; 223 | cookies_used = 0; 224 | 225 | for(int i = 0; i < cookies_size; i++) { 226 | free(HEADERS[i].name); 227 | free(HEADERS[i].value); 228 | } 229 | 230 | cookies_size = 0; 231 | 232 | free(HEADERS); 233 | free(COOKIES); 234 | 235 | HEADERS = NULL; 236 | COOKIES = NULL; 237 | raw_data_cookies = NULL; 238 | 239 | } 240 | -------------------------------------------------------------------------------- /core/src/http.h: -------------------------------------------------------------------------------- 1 | #ifndef HTTP_H_ 2 | #define HTTP_H_ 3 | 4 | // Whether to compile as FastCGI 5 | #ifdef _F_CHL_ 6 | #include "fcgi_stdio.h" 7 | #endif 8 | 9 | void chl_set_header(char *, char *); 10 | char * chl_get_header(char *); 11 | void chl_print_headers(); 12 | void chl_set_default_headers(); 13 | void http_cookies_init(); 14 | void format_cookies_data(); 15 | void cookies_append_var(char *, char *); 16 | char * chl_cookies(char *); 17 | void chl_set_cookie(char *, char *, char *); 18 | void chl_delete_cookie(char *); 19 | void _http_init(); 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /core/src/inline.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This source file's purpose is to handle everything that has to do with inline code 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "inline.h" 12 | #include "error.h" 13 | #include "deffuncs.h" 14 | #include "std.h" 15 | 16 | // Struct for CHL inline functions 17 | typedef struct { 18 | char * name; 19 | void (* function)(char *); 20 | } FUNC; 21 | 22 | // Struct array for CHL inline functions, dynamically allocated 23 | static FUNC * FUNCS = NULL; 24 | 25 | // Size of [FUNCS] struct array 26 | static unsigned char funcs_size = 0; 27 | 28 | // Parse inline code and handle inline functions and such 29 | char parse_inline(char ** buff, char * path, int * line_nr) { 30 | char * var_name; // Variable name 31 | char * var_args; // Variable arguments 32 | 33 | // Loop through every byte until end of inline code is found '}>', or null terminator 34 | while(**buff != '\0') { 35 | // New line, increment [line_nr] 36 | if(**buff == '\n') { 37 | (*line_nr)++; 38 | goto next_byte; 39 | } 40 | 41 | // If space, skip 42 | else if(isspace(**buff)) 43 | goto next_byte; 44 | 45 | // First letter of inline terminator 46 | else if(**buff == '}') { 47 | // Found whole terminator 48 | if(*(*buff + 1) == '>') { 49 | *buff += 2; // Move outside inline code 50 | return 1; 51 | } 52 | 53 | // Did not find whole terminator 54 | else 55 | break; 56 | } 57 | 58 | // Is start of function 59 | else { 60 | // Set start of variable name 61 | var_name = *buff; 62 | 63 | // Loop until end of variable name and start of arguments 64 | while((**buff != '(') && (**buff != '\0')) 65 | (*buff)++; 66 | 67 | // If proper function name 68 | if(**buff == '(') { 69 | **buff = '\0'; // Set end of variable name 70 | var_args = ++(*buff); // Set start of variable arguments 71 | 72 | // Loop until end of variable arguments 73 | while((**buff != ')') && (**buff != '\0')) 74 | (*buff)++; 75 | 76 | // Found function terminator ');' 77 | if((**buff == ')') && (*(*buff + 1) == ';')) { 78 | *((*buff)++) = '\0'; // Set end of variable arguments 79 | 80 | // Execute function [var_name], check if not existing 81 | if(! chl_func(var_name, var_args)) { 82 | // Unknown function error 83 | chl_error_append(CHL_E_UNKFUNC, "in file '%s' on line %d, unknown function '%s'", path, *line_nr, var_name); 84 | return 0; 85 | } 86 | } 87 | 88 | // Found null terminator, no ending ');' for function 89 | else { 90 | // Set error no ending terminator, only comes here if no terminator 91 | chl_error_append(CHL_E_NOTERMFUNC, "in file '%s' on line %d, missing terminator ');' for function '%s'", path, *line_nr, var_name); 92 | return 0; 93 | } 94 | } 95 | 96 | // Found null terminator, no clear end of variable name 97 | else { 98 | chl_error_append(CHL_E_UNEXV, "in file '%s' on line %d, unexpected end of function", path, *line_nr); 99 | return 0; 100 | } 101 | } 102 | 103 | // Next byte 104 | next_byte: 105 | (*buff)++; 106 | } 107 | 108 | // Set error no ending terminator, only comes here if no terminator 109 | chl_error_append(CHL_E_NOTERMIN, "in file '%s' on line %d, missing terminator '}>'", path, *line_nr); 110 | 111 | return 0; 112 | } 113 | 114 | // Append function to [FUNCS] struct array 115 | void chl_func_append(char * name, void (* function)(char *)) { 116 | // Prevent char overflow, a greater number than 512 117 | if(funcs_size >= 510) 118 | return; 119 | 120 | // Allocate memory for new function 121 | FUNCS = std_realloc(FUNCS, ++funcs_size * sizeof(FUNC)); 122 | 123 | // Set variable properties 124 | FUNCS[funcs_size - 1].name = name; 125 | FUNCS[funcs_size - 1].function = function; 126 | } 127 | 128 | // Execute function [name], return 0 if not found 129 | char chl_func(char * name, char * args) { 130 | // Check whether default functions have been initialized 131 | if(! def_funcs) 132 | append_default_funcs(); 133 | 134 | int i, x; 135 | 136 | // Loop through every index in [HEADERS] array until [name] is found 137 | for(i = 0; (i < funcs_size) && (x = strcmp(FUNCS[i].name, name)); i++); 138 | 139 | // Found a matching value for [name] 140 | if(!x) { 141 | // Execute function 142 | (*(FUNCS[i].function))(args); 143 | return 1; 144 | } 145 | 146 | // Did not find a match 147 | return 0; 148 | } 149 | 150 | // Returns next argument in [args], 0 if no arguments left 151 | char * chl_next_arg(char * args) { 152 | static char * pt; // Pointer to current byte in [args] 153 | char * arg; // Pointer to next arg in [args] 154 | char delim; // String delimiter 155 | 156 | // If args attain a new value 157 | if(args != NULL) 158 | pt = args; 159 | 160 | // Loop until start of argument delimiter is found (" | ') 161 | while(((*pt != '"') && (*pt != '\'')) && (*pt != '\0')) 162 | pt++; 163 | 164 | // Set delimiter 165 | delim = *pt; 166 | 167 | // Found end of arguments 168 | if(*pt == '\0') 169 | return 0; 170 | 171 | // Set start of argument 172 | arg = ++pt; 173 | 174 | // Loop until end of argument delimiter is found 175 | while((*pt != delim) && (*pt != '\0')) 176 | pt++; 177 | 178 | // No ending delimiter 179 | if(*pt == '\0') 180 | return 0; 181 | 182 | // Set end of argument 183 | *(pt++) = '\0'; 184 | 185 | return arg; 186 | } 187 | 188 | // Fetches next argument in [args] and converts it to integer, returns -1 on error or if end argument 189 | int chl_next_argi(char * args) { 190 | char * arg, * err; 191 | long int ret; 192 | 193 | // Check if last argument 194 | if(! (arg = chl_next_arg(args))) 195 | return -1; 196 | 197 | // Convert to int 198 | ret = strtol(arg, &err, 10); 199 | 200 | // Return -1 if conversion could not be done, or an error occurred 201 | if((arg == err) || (ret == LONG_MIN) || (ret == LONG_MAX)) 202 | return -1; 203 | 204 | // Return integer 205 | return (int) ret; 206 | } 207 | 208 | // Fetches next argument in [args] and converts it to float, returns -1 on error or 0 if end argument 209 | float chl_next_argf(char * args) { 210 | char * arg, * err; 211 | float ret; 212 | 213 | // Check if last argument 214 | if(! (arg = chl_next_arg(args))) 215 | return -1; 216 | 217 | // Convert to float 218 | ret = strtof(arg, &err); 219 | 220 | // Return -1 if conversion could not be done, or an error occurred 221 | if((arg == err) || (ret == HUGE_VALF)) 222 | return -1; 223 | 224 | // Return float 225 | return ret; 226 | } 227 | 228 | // Allocates memory for [dst] and sets arguments, return number of arguments 229 | char chl_get_args(char *(** dst), char * args) { 230 | char argsn = 0; // Number of arguments 231 | char * arg; // Pointer to argument 232 | 233 | // If no arguments 234 | if(! (arg = chl_next_arg(args))) 235 | return 0; 236 | 237 | // Allocate memory for argument pointer 238 | *dst = std_malloc(++argsn * sizeof(char *)); 239 | **dst = arg; 240 | 241 | // While there are still arguments left 242 | while((arg = chl_next_arg(NULL))) { 243 | // Allocate memory for argument pointer 244 | *dst = std_realloc(*dst, ++argsn * sizeof(char *)); 245 | *(*dst + (argsn - 1)) = arg; 246 | } 247 | 248 | // Return number of arguments 249 | return argsn; 250 | } 251 | 252 | // Initialize and free objects, called by chl_fcgi_init 253 | void _inline_init() { 254 | funcs_size = 0; 255 | def_funcs = 0; 256 | 257 | free(FUNCS); 258 | FUNCS = NULL; 259 | } 260 | -------------------------------------------------------------------------------- /core/src/inline.h: -------------------------------------------------------------------------------- 1 | #ifndef INLINE_H_ 2 | #define INLINE_H_ 3 | 4 | // Whether to compile as FastCGI 5 | #ifdef _F_CHL_ 6 | #include "fcgi_stdio.h" 7 | #endif 8 | 9 | char parse_inline(char **, char *, int *); 10 | void chl_func_append(char *, void (*)(char *)); 11 | char chl_func(char *, char *); 12 | char * chl_next_arg(char *); 13 | int chl_next_argi(char *); 14 | float chl_next_argf(char *); 15 | char chl_get_args(char *(**), char *); 16 | void _inline_init(); 17 | 18 | #endif /* INLINE_H_ */ 19 | -------------------------------------------------------------------------------- /core/src/std.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This source file's purpose is to provide important shared functions for 3 | * other source files. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #define SLEEP_INTERVAL_TIME 1000 10 | #define SLEEP_INTERVAL_MULTI_LIM 10 11 | 12 | // malloc with proper error handling 13 | void * std_malloc(size_t size) { 14 | void * mem; 15 | char inter_multi = 1; 16 | 17 | while((mem = malloc(size)) == NULL) { 18 | if(inter_multi > SLEEP_INTERVAL_MULTI_LIM) 19 | exit(-1); 20 | 21 | sleep(SLEEP_INTERVAL_TIME * inter_multi++); 22 | } 23 | 24 | return mem; 25 | } 26 | 27 | // realloc with proper error handling 28 | void * std_realloc(void * ptr, size_t newsize) { 29 | void * mem; 30 | char inter_multi = 1; 31 | 32 | while((mem = realloc(ptr, newsize)) == NULL) { 33 | if(inter_multi > SLEEP_INTERVAL_MULTI_LIM) 34 | exit(-1); 35 | 36 | sleep(SLEEP_INTERVAL_TIME * inter_multi++); 37 | } 38 | 39 | return mem; 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /core/src/std.h: -------------------------------------------------------------------------------- 1 | #ifndef STD_H_ 2 | #define STD_H_ 3 | 4 | void * std_malloc(size_t); 5 | void * std_realloc(void *, size_t); 6 | 7 | #endif /* STD_H_ */ 8 | -------------------------------------------------------------------------------- /core/src/view.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This source file's purpose is to provide functions for opening views and 3 | * handling inline C functions 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "error.h" 10 | #include "http.h" 11 | #include "view.h" 12 | #include "inline.h" 13 | #include "std.h" 14 | 15 | #define BUFF_BLOCK_SIZE 2000 // Size per allocation for [buffer] 16 | 17 | // Open and interpret view [view_path] 18 | void chl_view(char * view_path) { 19 | FILE * fd; // File stream to [view_path] 20 | char * buff_st = NULL, * buff = NULL; // Buffer to contain file data, dynamically allocated 21 | 22 | // Output headers 23 | chl_set_default_headers(); 24 | chl_print_headers(); 25 | 26 | // Open file [view_path] for reading 27 | if(! file_read_open(view_path, &fd)) 28 | goto print_error; 29 | 30 | // Read data from file 31 | if((buff_st = file_read_data(&buff, view_path, fd)) == NULL) 32 | goto print_error; 33 | 34 | // Parse and interpret view 35 | parse_view(&buff, view_path); 36 | 37 | // Print errors if any 38 | print_error: 39 | chl_print_errors(); 40 | 41 | free(buff_st); 42 | 43 | if(fd != NULL) 44 | fclose(fd); 45 | } 46 | 47 | 48 | // Open file [path] for reading 49 | char file_read_open(char * path, FILE ** fd) { 50 | // Open file for reading 51 | if((*fd = fopen(path, "r")) != NULL) 52 | return 1; // Return success 53 | 54 | // Failed to open file, set appropriate error 55 | switch(errno) { 56 | // Could not find file 57 | case EACCES: 58 | case ENOENT: 59 | case ENOSPC: 60 | case ENOTDIR: 61 | // Append error 62 | chl_error_append(CHL_E_FILENF, "could not find file '%s'", path); 63 | 64 | break; 65 | 66 | // Opening of file interrupted by signal 67 | case EINTR: 68 | chl_error_append(CHL_E_FILEINT, "a signal was caught when trying to open file: '%s'", path); 69 | 70 | break; 71 | } 72 | 73 | return 0; // Return failure 74 | } 75 | 76 | // Read data from file [fd], allocate more memory for [buff] if needed 77 | char * file_read_data(char ** buff, char * path, FILE * fd) { 78 | int iteration = 1; // Number of iterations 79 | int ntotal = 0; // Total bytes read 80 | int nread; // Bytes read in one iteration 81 | 82 | // Allocate memory for [buff] 83 | *buff = std_malloc(BUFF_BLOCK_SIZE * sizeof(char)); 84 | 85 | // Read data from stdin [BUFF_BLOCK_SIZE] bytes at time, allocate more memory if needed 86 | while((nread = fread(*buff + ntotal, sizeof(char), BUFF_BLOCK_SIZE, fd)) == BUFF_BLOCK_SIZE) { 87 | // Limit to [BUFF_BLOCK_SIZE] bytes 88 | if((++iteration * BUFF_BLOCK_SIZE) >= VIEW_SIZE_LIM) { 89 | // Error too big file 90 | chl_error_append(CHL_E_FILESIZE, "file '%s' size exceeded limit %d", path, VIEW_SIZE_LIM); 91 | return NULL; 92 | } 93 | 94 | // Allocate more memory for buff 95 | *buff = std_realloc(*buff, iteration * VIEW_SIZE_LIM); 96 | ntotal += nread; 97 | } 98 | 99 | // Null terminate data 100 | (*buff)[ntotal + nread] = '\0'; 101 | 102 | return *buff; 103 | } 104 | 105 | // Parse and interpret view file [buff] 106 | void parse_view(char ** buff, char * path) { 107 | int line_nr = 1; // Current line number 108 | char * output; // Pointer to end of last output index 109 | 110 | output = *buff; 111 | 112 | // Loop through [buff] and interpret data 113 | while(**buff != '\0') { 114 | // If new line 115 | if(**buff == '\n') 116 | line_nr++; 117 | 118 | // If start of inline code 119 | else if((**buff == '<') && (*(*buff + 1) == '{')) { 120 | **buff = '\0'; // End of string before output 121 | *buff += 2; // Jump to inline code start 122 | 123 | // Output everything before inline code 124 | fputs(output, stdout); 125 | 126 | 127 | // Parse inline code 128 | if(! parse_inline(buff, path, &line_nr)) 129 | return; 130 | 131 | output = *buff; 132 | } 133 | 134 | (*buff)++; 135 | } 136 | 137 | // Output last bytes 138 | fputs(output, stdout); 139 | } 140 | 141 | // Import file [file_path] contents 142 | void chl_import(char * file_path) { 143 | FILE * fd; // File stream to [view_path] 144 | char * buff_st = NULL, * buff = NULL; // Buffer to contain file data, dynamically allocated 145 | 146 | // Open file [view_path] for reading 147 | if(! file_read_open(file_path, &fd)) 148 | goto print_error; 149 | 150 | // Read data from file 151 | if((buff_st = file_read_data(&buff, file_path, fd)) == NULL) 152 | goto print_error; 153 | 154 | // Parse and interpret view 155 | parse_view(&buff, file_path); 156 | 157 | // Print errors if any 158 | print_error: 159 | chl_print_errors(); 160 | 161 | free(buff_st); 162 | 163 | if(fd != NULL) 164 | fclose(fd); 165 | } 166 | 167 | -------------------------------------------------------------------------------- /core/src/view.h: -------------------------------------------------------------------------------- 1 | #ifndef VIEW_H_ 2 | #define VIEW_H_ 3 | 4 | #include 5 | 6 | #define VIEW_SIZE_LIM 100000 // Maximum size of a view file 7 | 8 | // Whether to compile as FastCGI 9 | #ifdef _F_CHL_ 10 | #include "fcgi_stdio.h" 11 | #endif 12 | 13 | void chl_view(char *); 14 | char file_read_open(char *, FILE **); 15 | char * file_read_data(char **, char *, FILE *); 16 | void parse_view(char **, char *); 17 | void chl_import(char *); 18 | 19 | #endif /* VIEW_H_ */ 20 | -------------------------------------------------------------------------------- /findplugindeps: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # THE PUROPSE OF THIS FILE IS TO LOCATE AND COPY THE HEADER AND DEPENDENT 4 | # LIBRARIES OF THE PLUGINS TO THEIR PROPER LOCATIONS 5 | 6 | for dir in ${1}/*/; do 7 | # COPY PLUGIN DEPENDENT LIBRARIES 8 | cp ${dir}libs/* /usr/lib/chl/ 9 | 10 | # COPY PLUGIN HEADER FILES 11 | cp ${dir}*.h /usr/include/chl/ 12 | done 13 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # STANDARD MAKEFILE FOR CHL 2 | # https://github.com/it4e/CHL 3 | 4 | install: move_files 5 | 6 | # Put files in proper locations 7 | move_files: create_lib 8 | mv libchl.so /usr/lib/chl/ 9 | cp core/*.h /usr/include/chl 10 | # Move plugin dependent libraries and headers 11 | if [ "${PLUGINS}" != "FALSE" ]; then bash findplugindeps plugins; fi 12 | # Make CHL libs available 13 | ln -f -s /usr/lib/chl/* /usr/lib/ 14 | 15 | 16 | # Create library 17 | create_lib: create_path compile_core 18 | gcc -shared -o libchl.so cmp/*.o 19 | make clean 20 | 21 | # Handle compilation of core 22 | compile_core: compile_plugins 23 | if [ "${TYPE}" != "FCGI" ]; then gcc -std=c11 -c -Wall -Werror -fPIC core/src/*.c; mv *.o cmp; else gcc -std=c11 -c -D '_F_CHL_' -Wall -Werror -fPIC core/src/*.c; mv *.o cmp; fi # Check whether to compile as fcgi or cgi 24 | 25 | 26 | # Handle plugins compilation 27 | compile_plugins: 28 | # Check whether to compile plugins or not 29 | if [ "${PLUGINS}" != "FALSE" ]; then bash pluginhandler plugins; fi 30 | 31 | # Create path for compilation and library 32 | create_path: 33 | # Check whether library paths already exists 34 | if ! [ -d "/usr/lib/chl" ]; then mkdir /usr/lib/chl; fi 35 | if ! [ -d "/usr/include/chl" ]; then mkdir /usr/include/chl; fi 36 | # Check whether compilation folder already exists 37 | if ! [ -d "cmp" ]; then mkdir cmp; fi 38 | 39 | # Clean cmp 40 | clean: 41 | if [ -d "cmp" ]; then rm -r cmp; fi 42 | -------------------------------------------------------------------------------- /pluginhandler: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # THIS FILE HAS THE PURPOSE OF EXECUTING THE MAKEFILES OF THE PLUGINS, THUS 4 | # COMPILING ITS SOURCE CODE AND SUCH 5 | 6 | # Loop through ${1} subfolders and execute their makefiles 7 | for dir in ${1}/*/; do 8 | cd ${dir}; 9 | if [ -f "makefile" ]; then make; fi 10 | cd ../../ 11 | done 12 | -------------------------------------------------------------------------------- /plugins/fastcgi/fcgi.h: -------------------------------------------------------------------------------- 1 | #ifndef NO_FCGI_DEFINES 2 | 3 | #undef FILE 4 | #define FILE FCGI_FILE 5 | 6 | #undef stdin 7 | #define stdin FCGI_stdin 8 | #undef stdout 9 | #define stdout FCGI_stdout 10 | #undef stderr 11 | #define stderr FCGI_stderr 12 | 13 | #undef perror 14 | #define perror FCGI_perror 15 | 16 | #undef fopen 17 | #define fopen FCGI_fopen 18 | #undef fclose 19 | #define fclose FCGI_fclose 20 | #undef fflush 21 | #define fflush FCGI_fflush 22 | #undef freopen 23 | #define freopen FCGI_freopen 24 | 25 | #undef setvbuf 26 | #define setvbuf FCGI_setvbuf 27 | #undef setbuf 28 | #define setbuf FCGI_setbuf 29 | 30 | #undef fseek 31 | #define fseek FCGI_fseek 32 | #undef ftell 33 | #define ftell FCGI_ftell 34 | #undef rewind 35 | #define rewind FCGI_rewind 36 | #undef fgetpos 37 | #define fgetpos FCGI_fgetpos 38 | #undef fsetpos 39 | #define fsetpos FCGI_fsetpos 40 | 41 | #undef fgetc 42 | #define fgetc FCGI_fgetc 43 | #undef getc 44 | #define getc FCGI_fgetc 45 | #undef getchar 46 | #define getchar FCGI_getchar 47 | #undef ungetc 48 | #define ungetc FCGI_ungetc 49 | 50 | #undef fgets 51 | #define fgets FCGI_fgets 52 | #undef gets 53 | #define gets FCGI_gets 54 | 55 | #undef fputc 56 | #define fputc FCGI_fputc 57 | #undef putc 58 | #define putc FCGI_fputc 59 | #undef putchar 60 | #define putchar FCGI_putchar 61 | 62 | #undef fputs 63 | #define fputs FCGI_fputs 64 | #undef puts 65 | #define puts FCGI_puts 66 | 67 | #undef fprintf 68 | #define fprintf FCGI_fprintf 69 | #undef printf 70 | #define printf FCGI_printf 71 | 72 | #undef vfprintf 73 | #define vfprintf FCGI_vfprintf 74 | #undef vprintf 75 | #define vprintf FCGI_vprintf 76 | 77 | #undef fread 78 | #define fread FCGI_fread 79 | #undef fwrite 80 | #define fwrite FCGI_fwrite 81 | 82 | #undef feof 83 | #define feof FCGI_feof 84 | #undef ferror 85 | #define ferror FCGI_ferror 86 | #undef clearerr 87 | #define clearerr FCGI_clearerr 88 | 89 | #undef tmpfile 90 | #define tmpfile FCGI_tmpfile 91 | 92 | #undef fileno 93 | #define fileno FCGI_fileno 94 | #undef fdopen 95 | #define fdopen FCGI_fdopen 96 | #undef popen 97 | #define popen FCGI_popen 98 | #undef pclose 99 | #define pclose FCGI_pclose 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /plugins/fastcgi/libs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmylindh/CHL/a573099e8b75b253acd9b41cc45739b5536caf4d/plugins/fastcgi/libs/.gitignore -------------------------------------------------------------------------------- /plugins/fastcgi/makefile: -------------------------------------------------------------------------------- 1 | COMPILER = gcc 2 | all: compile 3 | 4 | # Compile source files 5 | compile: 6 | $(COMPILER) -c -w -Wall -Werror -fPIC src/*.c 7 | mv *.o ../../cmp 8 | 9 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fastcgi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fastcgi.h -- 3 | * 4 | * Defines for the FastCGI protocol. 5 | * 6 | * 7 | * Copyright (c) 1995-1996 Open Market, Inc. 8 | * 9 | * See the file "LICENSE.TERMS" for information on usage and redistribution 10 | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 11 | * 12 | * $Id: fastcgi.h,v 1.1.1.1 1997/09/16 15:36:32 stanleyg Exp $ 13 | */ 14 | 15 | #ifndef _FASTCGI_H 16 | #define _FASTCGI_H 17 | 18 | /* 19 | * Listening socket file number 20 | */ 21 | #define FCGI_LISTENSOCK_FILENO 0 22 | 23 | typedef struct { 24 | unsigned char version; 25 | unsigned char type; 26 | unsigned char requestIdB1; 27 | unsigned char requestIdB0; 28 | unsigned char contentLengthB1; 29 | unsigned char contentLengthB0; 30 | unsigned char paddingLength; 31 | unsigned char reserved; 32 | } FCGI_Header; 33 | 34 | #define FCGI_MAX_LENGTH 0xffff 35 | 36 | /* 37 | * Number of bytes in a FCGI_Header. Future versions of the protocol 38 | * will not reduce this number. 39 | */ 40 | #define FCGI_HEADER_LEN 8 41 | 42 | /* 43 | * Value for version component of FCGI_Header 44 | */ 45 | #define FCGI_VERSION_1 1 46 | 47 | /* 48 | * Values for type component of FCGI_Header 49 | */ 50 | #define FCGI_BEGIN_REQUEST 1 51 | #define FCGI_ABORT_REQUEST 2 52 | #define FCGI_END_REQUEST 3 53 | #define FCGI_PARAMS 4 54 | #define FCGI_STDIN 5 55 | #define FCGI_STDOUT 6 56 | #define FCGI_STDERR 7 57 | #define FCGI_DATA 8 58 | #define FCGI_GET_VALUES 9 59 | #define FCGI_GET_VALUES_RESULT 10 60 | #define FCGI_UNKNOWN_TYPE 11 61 | #define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE) 62 | 63 | /* 64 | * Value for requestId component of FCGI_Header 65 | */ 66 | #define FCGI_NULL_REQUEST_ID 0 67 | 68 | 69 | typedef struct { 70 | unsigned char roleB1; 71 | unsigned char roleB0; 72 | unsigned char flags; 73 | unsigned char reserved[5]; 74 | } FCGI_BeginRequestBody; 75 | 76 | typedef struct { 77 | FCGI_Header header; 78 | FCGI_BeginRequestBody body; 79 | } FCGI_BeginRequestRecord; 80 | 81 | /* 82 | * Mask for flags component of FCGI_BeginRequestBody 83 | */ 84 | #define FCGI_KEEP_CONN 1 85 | 86 | /* 87 | * Values for role component of FCGI_BeginRequestBody 88 | */ 89 | #define FCGI_RESPONDER 1 90 | #define FCGI_AUTHORIZER 2 91 | #define FCGI_FILTER 3 92 | 93 | 94 | typedef struct { 95 | unsigned char appStatusB3; 96 | unsigned char appStatusB2; 97 | unsigned char appStatusB1; 98 | unsigned char appStatusB0; 99 | unsigned char protocolStatus; 100 | unsigned char reserved[3]; 101 | } FCGI_EndRequestBody; 102 | 103 | typedef struct { 104 | FCGI_Header header; 105 | FCGI_EndRequestBody body; 106 | } FCGI_EndRequestRecord; 107 | 108 | /* 109 | * Values for protocolStatus component of FCGI_EndRequestBody 110 | */ 111 | #define FCGI_REQUEST_COMPLETE 0 112 | #define FCGI_CANT_MPX_CONN 1 113 | #define FCGI_OVERLOADED 2 114 | #define FCGI_UNKNOWN_ROLE 3 115 | 116 | 117 | /* 118 | * Variable names for FCGI_GET_VALUES / FCGI_GET_VALUES_RESULT records 119 | */ 120 | #define FCGI_MAX_CONNS "FCGI_MAX_CONNS" 121 | #define FCGI_MAX_REQS "FCGI_MAX_REQS" 122 | #define FCGI_MPXS_CONNS "FCGI_MPXS_CONNS" 123 | 124 | 125 | typedef struct { 126 | unsigned char type; 127 | unsigned char reserved[7]; 128 | } FCGI_UnknownTypeBody; 129 | 130 | typedef struct { 131 | FCGI_Header header; 132 | FCGI_UnknownTypeBody body; 133 | } FCGI_UnknownTypeRecord; 134 | 135 | #endif /* _FASTCGI_H */ 136 | 137 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fcgi_config.h: -------------------------------------------------------------------------------- 1 | /* fcgi_config.h. Generated automatically by configure. */ 2 | /* fcgi_config.h.in. Generated automatically from configure.in by autoheader. */ 3 | 4 | /* Define if you have the header file. */ 5 | #define HAVE_ARPA_INET_H 1 6 | 7 | /* Define if you have the header file. */ 8 | #define HAVE_DLFCN_H 1 9 | 10 | /* Define if there's a fileno() prototype in stdio.h */ 11 | #define HAVE_FILENO_PROTO 1 12 | 13 | /* Define if the fpos_t typedef is in stdio.h */ 14 | #define HAVE_FPOS 1 15 | 16 | /* Define if you have the header file. */ 17 | #define HAVE_INTTYPES_H 1 18 | 19 | /* Define if cin/cout/cerr has a streambuf assignment operator */ 20 | /* #undef HAVE_IOSTREAM_WITHASSIGN_STREAMBUF */ 21 | 22 | /* Define if you have the `nsl' library (-lnsl). */ 23 | #define HAVE_LIBNSL 1 24 | 25 | /* Define if you have the `socket' library (-lsocket). */ 26 | #define HAVE_LIBSOCKET 1 27 | 28 | /* Define if you have the header file. */ 29 | #define HAVE_LIMITS_H 1 30 | 31 | /* Define if you have the header file. */ 32 | #define HAVE_MEMORY_H 1 33 | 34 | /* Define if you have the header file. */ 35 | #define HAVE_NETDB_H 1 36 | 37 | /* Define if you have the header file. */ 38 | #define HAVE_NETINET_IN_H 1 39 | 40 | /* Define if you have POSIX threads libraries and header files. */ 41 | /* #undef HAVE_PTHREAD */ 42 | 43 | /* Define if sockaddr_un in sys/un.h contains a sun_len component */ 44 | /* #undef HAVE_SOCKADDR_UN_SUN_LEN */ 45 | 46 | /* Define if the socklen_t typedef is in sys/socket.h */ 47 | /* #undef HAVE_SOCKLEN */ 48 | 49 | /* Define if you have the header file. */ 50 | /* #undef HAVE_STDINT_H */ 51 | 52 | /* Define if you have the header file. */ 53 | #define HAVE_STDLIB_H 1 54 | 55 | /* Define if char_type is defined in the context of streambuf */ 56 | #define HAVE_STREAMBUF_CHAR_TYPE 1 57 | 58 | /* Define if you have the `strerror' function. */ 59 | #define HAVE_STRERROR 1 60 | 61 | /* Define if you have the header file. */ 62 | #define HAVE_STRINGS_H 1 63 | 64 | /* Define if you have the header file. */ 65 | #define HAVE_STRING_H 1 66 | 67 | /* Define if you have the header file. */ 68 | #define HAVE_SYS_PARAM_H 1 69 | 70 | /* Define if you have the header file. */ 71 | #define HAVE_SYS_SOCKET_H 1 72 | 73 | /* Define if you have the header file. */ 74 | #define HAVE_SYS_STAT_H 1 75 | 76 | /* Define if you have the header file. */ 77 | #define HAVE_SYS_TIME_H 1 78 | 79 | /* Define if you have the header file. */ 80 | #define HAVE_SYS_TYPES_H 1 81 | 82 | /* Define if you have the header file. */ 83 | #define HAVE_UNISTD_H 1 84 | 85 | /* Define if va_arg(arg, long double) crashes the compiler */ 86 | /* #undef HAVE_VA_ARG_LONG_DOUBLE_BUG */ 87 | 88 | /* Name of package */ 89 | #define PACKAGE "fcgi" 90 | 91 | /* Define to the necessary symbol if this constant uses a non-standard name on 92 | your system. */ 93 | /* #undef PTHREAD_CREATE_JOINABLE */ 94 | 95 | /* Define if you have the ANSI C header files. */ 96 | #define STDC_HEADERS 1 97 | 98 | /* Define if cross-process locking is required by accept() */ 99 | #define USE_LOCKING 1 100 | 101 | /* Version number of package */ 102 | #define VERSION "2.4.0" 103 | 104 | /* Define to empty if `const' does not conform to ANSI C. */ 105 | /* #undef const */ 106 | 107 | /* Define as `__inline' if that's what the C compiler calls it, or to nothing 108 | if it is not supported. */ 109 | /* #undef inline */ 110 | 111 | /* Define to `int' if does not define. */ 112 | /* #undef ssize_t */ 113 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fcgi_config_x86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copied to fcgi_config.h when building on WinNT without cygwin, 3 | * i.e. configure is not run. See fcgi_config.h.in for details. 4 | */ 5 | 6 | #define HAVE_FPOS 1 7 | #define HAVE_LIMITS_H 1 8 | #define HAVE_STREAMBUF_CHAR_TYPE 1 9 | #define HAVE_STRERROR 1 10 | #undef HAVE_ARPA_INET_H 11 | #undef HAVE_DLFCN_H 12 | #undef HAVE_FILENO_PROTO 13 | #undef HAVE_INTTYPES_H 14 | #undef HAVE_IOSTREAM_WITHASSIGN_STREAMBUF 15 | #undef HAVE_LIBNSL 16 | #undef HAVE_LIBSOCKET 17 | #undef HAVE_MEMORY_H 18 | #undef HAVE_NETDB_H 19 | #undef HAVE_NETINET_IN_H 20 | #undef HAVE_PTHREAD 21 | #undef HAVE_SOCKADDR_UN_SUN_LEN 22 | #undef HAVE_SOCKLEN 23 | #undef HAVE_STDINT_H 24 | #undef HAVE_STDLIB_H 25 | #undef HAVE_STRING_H 26 | #undef HAVE_STRINGS_H 27 | #undef HAVE_SYS_PARAM_H 28 | #undef HAVE_SYS_SOCKET_H 29 | #undef HAVE_SYS_STAT_H 30 | #undef HAVE_SYS_TIME_H 31 | #undef HAVE_SYS_TYPES_H 32 | #undef HAVE_UNISTD_H 33 | #undef HAVE_VA_ARG_LONG_DOUBLE_BUG 34 | #undef PTHREAD_CREATE_JOINABLE 35 | #undef STDC_HEADERS 36 | #undef USE_LOCKING 37 | #undef const 38 | #undef inline 39 | #undef ssize_t 40 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fcgi_stdio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * fcgi_stdio.c -- 3 | * 4 | * FastCGI-stdio compatibility package 5 | * 6 | * 7 | * Copyright (c) 1996 Open Market, Inc. 8 | * 9 | * See the file "LICENSE.TERMS" for information on usage and redistribution 10 | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 11 | * 12 | */ 13 | 14 | #ifndef lint 15 | static const char rcsid[] = "$Id: fcgi_stdio.c,v 1.14 2001/09/01 01:09:30 robs Exp $"; 16 | #endif /* not lint */ 17 | 18 | #include /* for errno */ 19 | #include /* for va_arg */ 20 | #include /* for malloc */ 21 | #include /* for strerror */ 22 | 23 | #include "fcgi_config.h" 24 | 25 | #ifdef HAVE_UNISTD_H 26 | #include 27 | #endif 28 | 29 | #ifdef _WIN32 30 | #define DLLAPI __declspec(dllexport) 31 | #endif 32 | 33 | #include "fcgiapp.h" 34 | #include "fcgios.h" 35 | #include "fcgimisc.h" 36 | 37 | #define NO_FCGI_DEFINES 38 | #include "fcgi_stdio.h" 39 | #undef NO_FCGI_DEFINES 40 | 41 | #ifndef _WIN32 42 | 43 | extern char **environ; 44 | 45 | #ifdef HAVE_FILENO_PROTO 46 | #include 47 | #else 48 | extern int fileno(FILE *stream); 49 | #endif 50 | 51 | extern FILE *fdopen(int fildes, const char *type); 52 | extern FILE *popen(const char *command, const char *type); 53 | extern int pclose(FILE *stream); 54 | 55 | #else /* _WIN32 */ 56 | 57 | #define popen _popen 58 | #define pclose _pclose 59 | 60 | #endif /* _WIN32 */ 61 | 62 | FCGI_FILE _fcgi_sF[3]; 63 | 64 | 65 | /* 66 | *---------------------------------------------------------------------- 67 | * 68 | * FCGI_Accept -- 69 | * 70 | * Accepts a new request from the HTTP server and creates 71 | * a conventional execution environment for the request. 72 | * 73 | * If the application was invoked as a FastCGI server, 74 | * the first call to FCGI_Accept indicates that the application 75 | * has completed its initialization and is ready to accept 76 | * a request. Subsequent calls to FCGI_Accept indicate that 77 | * the application has completed its processing of the 78 | * current request and is ready to accept a new request. 79 | * 80 | * If the application was invoked as a CGI program, the first 81 | * call to FCGI_Accept is essentially a no-op and the second 82 | * call returns EOF (-1). 83 | * 84 | * Results: 85 | * 0 for successful call, -1 for error (application should exit). 86 | * 87 | * Side effects: 88 | * If the application was invoked as a FastCGI server, 89 | * and this is not the first call to this procedure, 90 | * FCGI_Accept first performs the equivalent of FCGI_Finish. 91 | * 92 | * On every call, FCGI_Accept accepts the new request and 93 | * reads the FCGI_PARAMS stream into an environment array, 94 | * i.e. a NULL-terminated array of strings of the form 95 | * ``name=value''. It assigns a pointer to this array 96 | * to the global variable environ, used by the standard 97 | * library function getenv. It creates new FCGI_FILE *s 98 | * representing input from the HTTP server, output to the HTTP 99 | * server, and error output to the HTTP server, and assigns these 100 | * new files to stdin, stdout, and stderr respectively. 101 | * 102 | * DO NOT mutate or retain pointers to environ or any values 103 | * contained in it (e.g. to the result of calling getenv(3)), 104 | * since these are freed by the next call to FCGI_Finish or 105 | * FCGI_Accept. In particular do not use setenv(3) or putenv(3) 106 | * in conjunction with FCGI_Accept. 107 | * 108 | *---------------------------------------------------------------------- 109 | */ 110 | static int acceptCalled = FALSE; 111 | static int isCGI = FALSE; 112 | 113 | int FCGI_Accept(void) 114 | { 115 | if(!acceptCalled) { 116 | /* 117 | * First call to FCGI_Accept. Is application running 118 | * as FastCGI or as CGI? 119 | */ 120 | isCGI = FCGX_IsCGI(); 121 | acceptCalled = TRUE; 122 | atexit(&FCGI_Finish); 123 | } else if(isCGI) { 124 | /* 125 | * Not first call to FCGI_Accept and running as CGI means 126 | * application is done. 127 | */ 128 | return(EOF); 129 | } 130 | if(isCGI) { 131 | FCGI_stdin->stdio_stream = stdin; 132 | FCGI_stdin->fcgx_stream = NULL; 133 | FCGI_stdout->stdio_stream = stdout; 134 | FCGI_stdout->fcgx_stream = NULL; 135 | FCGI_stderr->stdio_stream = stderr; 136 | FCGI_stderr->fcgx_stream = NULL; 137 | } else { 138 | FCGX_Stream *in, *out, *error; 139 | FCGX_ParamArray envp; 140 | int acceptResult = FCGX_Accept(&in, &out, &error, &envp); 141 | if(acceptResult < 0) { 142 | return acceptResult; 143 | } 144 | FCGI_stdin->stdio_stream = NULL; 145 | FCGI_stdin->fcgx_stream = in; 146 | FCGI_stdout->stdio_stream = NULL; 147 | FCGI_stdout->fcgx_stream = out; 148 | FCGI_stderr->stdio_stream = NULL; 149 | FCGI_stderr->fcgx_stream = error; 150 | environ = envp; 151 | } 152 | return 0; 153 | } 154 | 155 | /* 156 | *---------------------------------------------------------------------- 157 | * 158 | * FCGI_Finish -- 159 | * 160 | * Finishes the current request from the HTTP server. 161 | * 162 | * Side effects: 163 | * 164 | * Flushes any buffered output to the HTTP server. Then frees 165 | * all storage allocated by the previous call, including all 166 | * storage reachable from the value of environ set by the previous 167 | * call to FCGI_Accept. 168 | * 169 | * DO NOT use stdin, stdout, stderr, or environ between calling 170 | * FCGI_Finish and calling FCGI_Accept. 171 | * 172 | * DO NOT mutate or retain pointers to environ or any values 173 | * contained in it (e.g. to the result of calling getenv(3)), 174 | * since these are freed by the next call to FCGI_Finish or 175 | * FCGI_Accept. In particular do not use setenv(3) or putenv(3) 176 | * in conjunction with FCGI_Accept. 177 | * 178 | *---------------------------------------------------------------------- 179 | */ 180 | void FCGI_Finish(void) 181 | { 182 | if(!acceptCalled || isCGI) { 183 | return; 184 | } 185 | FCGX_Finish(); 186 | FCGI_stdin->fcgx_stream = NULL; 187 | FCGI_stdout->fcgx_stream = NULL; 188 | FCGI_stderr->fcgx_stream = NULL; 189 | environ = NULL; 190 | } 191 | 192 | /* 193 | *---------------------------------------------------------------------- 194 | * 195 | * FCGI_StartFilterData -- 196 | * 197 | * 198 | * The current request is for the filter role, and stdin is 199 | * positioned at EOF of FCGI_STDIN. The call repositions 200 | * stdin to the start of FCGI_DATA. 201 | * If the preconditions are not met (e.g. FCGI_STDIN has not 202 | * been read to EOF), the call sets the stream error code to 203 | * FCGX_CALL_SEQ_ERROR. 204 | * 205 | * Results: 206 | * 0 for a normal return, < 0 for error 207 | * 208 | *---------------------------------------------------------------------- 209 | */ 210 | int FCGI_StartFilterData(void) 211 | { 212 | if(FCGI_stdin->stdio_stream) { 213 | return -1; 214 | } else { 215 | return FCGX_StartFilterData(FCGI_stdin->fcgx_stream); 216 | } 217 | } 218 | 219 | /* 220 | *---------------------------------------------------------------------- 221 | * 222 | * FCGI_SetExitStatus -- 223 | * 224 | * Sets the exit status for the current request. The exit status 225 | * is the status code the request would have exited with, had 226 | * the request been run as a CGI program. You can call 227 | * FCGI_SetExitStatus several times during a request; the last call 228 | * before the request ends (by calling FCGI_Accept) determines the 229 | * value. 230 | * 231 | *---------------------------------------------------------------------- 232 | */ 233 | void FCGI_SetExitStatus(int status) 234 | { 235 | if(FCGI_stdin->fcgx_stream) { 236 | FCGX_SetExitStatus(status, FCGI_stdin->fcgx_stream); 237 | } 238 | } 239 | 240 | /* 241 | *---------------------------------------------------------------------- 242 | * 243 | * FCGI_perror -- 244 | * 245 | * Wrapper for function defined in H&S Section 11.2 246 | * 247 | *---------------------------------------------------------------------- 248 | */ 249 | void FCGI_perror(const char *str) 250 | { 251 | FCGI_fputs(str, FCGI_stderr); 252 | FCGI_fputs(": ", FCGI_stderr); 253 | FCGI_fputs(strerror(OS_Errno), FCGI_stderr); 254 | return; 255 | } 256 | 257 | /* 258 | *---------------------------------------------------------------------- 259 | * 260 | * FCGI_OpenFromFILE -- 261 | * 262 | * Constructs a new FCGI_FILE * from the FILE *stream. 263 | * 264 | * Results: 265 | * NULL if stream == NULL or storage could not be allocated, 266 | * otherwise the new FCGI_FILE *. 267 | * 268 | *---------------------------------------------------------------------- 269 | */ 270 | static FCGI_FILE *FCGI_OpenFromFILE(FILE *stream) 271 | { 272 | FCGI_FILE *fp; 273 | 274 | if (stream == NULL) 275 | return NULL; 276 | 277 | fp = (FCGI_FILE *) malloc(sizeof(FCGI_FILE)); 278 | if (fp != NULL) 279 | { 280 | fp->stdio_stream = stream; 281 | fp->fcgx_stream = NULL; 282 | } 283 | 284 | return fp; 285 | } 286 | 287 | /* 288 | *---------------------------------------------------------------------- 289 | * 290 | * FCGI_fopen, FCGI_fclose, FCGI_fflush, FCGI_freopen -- 291 | * 292 | * Wrappers for functions defined in H&S Section 15.2 293 | * 294 | *---------------------------------------------------------------------- 295 | */ 296 | FCGI_FILE *FCGI_fopen(const char *path, const char *mode) 297 | { 298 | FILE * file = fopen(path, mode); 299 | FCGI_FILE * fcgi_file = FCGI_OpenFromFILE(file); 300 | 301 | if (file && !fcgi_file) 302 | fclose(file); 303 | 304 | return fcgi_file; 305 | } 306 | 307 | int FCGI_fclose(FCGI_FILE *fp) 308 | { 309 | int n = EOF; 310 | if(fp->stdio_stream) { 311 | n = fclose(fp->stdio_stream); 312 | fp->stdio_stream = NULL; 313 | } else if(fp->fcgx_stream) { 314 | n = FCGX_FClose(fp->fcgx_stream); 315 | fp->fcgx_stream = NULL; 316 | } 317 | if((fp != FCGI_stdin) && (fp != FCGI_stdout) && (fp != FCGI_stderr)) { 318 | free(fp); 319 | } 320 | return n; 321 | } 322 | 323 | int FCGI_fflush(FCGI_FILE *fp) 324 | { 325 | if(fp == NULL) 326 | return fflush(NULL); 327 | if(fp->stdio_stream) 328 | return fflush(fp->stdio_stream); 329 | else if(fp->fcgx_stream) 330 | return FCGX_FFlush(fp->fcgx_stream); 331 | return EOF; 332 | } 333 | 334 | FCGI_FILE *FCGI_freopen(const char *path, const char *mode, 335 | FCGI_FILE *fp) 336 | { 337 | if(fp->stdio_stream) { 338 | if(freopen(path, mode, fp->stdio_stream) == NULL) 339 | return NULL; 340 | else 341 | return fp; 342 | } else if(fp->fcgx_stream) { 343 | (void) FCGX_FClose(fp->fcgx_stream); 344 | fp->stdio_stream = fopen(path, mode); 345 | if(fp->stdio_stream == NULL) 346 | return NULL; 347 | else { 348 | fp->fcgx_stream = NULL; 349 | return fp; 350 | } 351 | } 352 | return NULL; 353 | } 354 | 355 | /* 356 | *---------------------------------------------------------------------- 357 | * 358 | * FCGI_setvbuf, FCGI_setbuf -- 359 | * 360 | * Wrappers for functions defined in H&S Section 15.3 361 | * 362 | *---------------------------------------------------------------------- 363 | */ 364 | int FCGI_setvbuf(FCGI_FILE *fp, char *buf, int bufmode, size_t size) 365 | { 366 | if(fp->stdio_stream) 367 | return setvbuf(fp->stdio_stream, buf, bufmode, size); 368 | else { 369 | return -1; 370 | } 371 | } 372 | 373 | void FCGI_setbuf(FCGI_FILE *fp, char *buf) 374 | { 375 | if(fp->stdio_stream) 376 | setbuf(fp->stdio_stream, buf); 377 | } 378 | 379 | /* 380 | *---------------------------------------------------------------------- 381 | * 382 | * FCGI_fseek, FCGI_ftell, FCGI_rewind, FCGI_fgetpos, FCGI_fsetpos -- 383 | * 384 | * Wrappers for functions defined in H&S Section 15.5 385 | * 386 | *---------------------------------------------------------------------- 387 | */ 388 | int FCGI_fseek(FCGI_FILE *fp, long offset, int whence) 389 | { 390 | if(fp->stdio_stream) 391 | return fseek(fp->stdio_stream, offset, whence); 392 | else { 393 | OS_SetErrno(ESPIPE); 394 | return -1; 395 | } 396 | } 397 | 398 | int FCGI_ftell(FCGI_FILE *fp) 399 | { 400 | if(fp->stdio_stream) 401 | return ftell(fp->stdio_stream); 402 | else { 403 | OS_SetErrno(ESPIPE); 404 | return -1; 405 | } 406 | } 407 | 408 | void FCGI_rewind(FCGI_FILE *fp) 409 | { 410 | if(fp->stdio_stream) 411 | rewind(fp->stdio_stream); 412 | else 413 | OS_SetErrno(ESPIPE); 414 | } 415 | 416 | #ifdef HAVE_FPOS 417 | int FCGI_fgetpos(FCGI_FILE *fp, fpos_t *pos) 418 | { 419 | if(fp->stdio_stream) 420 | return fgetpos(fp->stdio_stream, pos); 421 | else { 422 | OS_SetErrno(ESPIPE); 423 | return -1; 424 | } 425 | } 426 | 427 | int FCGI_fsetpos(FCGI_FILE *fp, const fpos_t *pos) 428 | { 429 | if(fp->stdio_stream) 430 | return fsetpos(fp->stdio_stream, pos); 431 | else { 432 | OS_SetErrno(ESPIPE); 433 | return -1; 434 | } 435 | } 436 | #endif 437 | 438 | /* 439 | *---------------------------------------------------------------------- 440 | * 441 | * FCGI_fgetc, FCGI_getchar, FCGI_ungetc -- 442 | * 443 | * Wrappers for functions defined in H&S Section 15.6 444 | * 445 | * XXX: getc and getchar are generally defined as macros 446 | * for performance reasons 447 | * 448 | *---------------------------------------------------------------------- 449 | */ 450 | int FCGI_fgetc(FCGI_FILE *fp) 451 | { 452 | if(fp->stdio_stream) 453 | return fgetc(fp->stdio_stream); 454 | else if(fp->fcgx_stream) 455 | return FCGX_GetChar(fp->fcgx_stream); 456 | return EOF; 457 | } 458 | 459 | int FCGI_getchar(void) 460 | { 461 | return FCGI_fgetc(FCGI_stdin); 462 | } 463 | 464 | int FCGI_ungetc(int c, FCGI_FILE *fp) 465 | { 466 | if(fp->stdio_stream) 467 | return ungetc(c, fp->stdio_stream); 468 | else if(fp->fcgx_stream) 469 | return FCGX_UnGetChar(c, fp->fcgx_stream); 470 | return EOF; 471 | } 472 | 473 | /* 474 | *---------------------------------------------------------------------- 475 | * 476 | * FCGI_fgets, FCGI_gets -- 477 | * 478 | * Wrappers for functions defined in H&S Section 15.7 479 | * 480 | *---------------------------------------------------------------------- 481 | */ 482 | char *FCGI_fgets(char *str, int size, FCGI_FILE *fp) 483 | { 484 | if(fp->stdio_stream) 485 | return fgets(str, size, fp->stdio_stream); 486 | else if(fp->fcgx_stream) 487 | return FCGX_GetLine(str, size, fp->fcgx_stream); 488 | return NULL; 489 | } 490 | 491 | /* 492 | * The gets() function reads characters from the standard input stream 493 | * into the array pointed to by str until a newline character is read 494 | * or an end-of-file condition is encountered. The newline character 495 | * is discarded and the string is terminated with a null character. 496 | */ 497 | char *FCGI_gets(char *str) 498 | { 499 | char *s; 500 | int c; 501 | 502 | for (s = str; ((c = FCGI_getchar()) != '\n');) { 503 | if(c == EOF) { 504 | if(s == str) 505 | return NULL; 506 | else 507 | break; 508 | } else 509 | *s++ = (char) c; 510 | } 511 | *s = 0; 512 | return str; 513 | } 514 | 515 | /* 516 | *---------------------------------------------------------------------- 517 | * 518 | * Wrappers for functions defined in H&S Section 15.8 519 | * 520 | * XXX: missing: fscanf, scanf 521 | * 522 | *---------------------------------------------------------------------- 523 | */ 524 | 525 | /* 526 | *---------------------------------------------------------------------- 527 | * 528 | * FCGI_fputc, FCGI_putchar -- 529 | * 530 | * Wrappers for functions defined in H&S Section 15.9 531 | * 532 | * XXX: putc and putchar are generally defined as macros 533 | * for performance reasons 534 | * 535 | *---------------------------------------------------------------------- 536 | */ 537 | int FCGI_fputc(int c, FCGI_FILE *fp) 538 | { 539 | if(fp->stdio_stream) 540 | return fputc(c, fp->stdio_stream); 541 | else if(fp->fcgx_stream) 542 | return FCGX_PutChar(c, fp->fcgx_stream); 543 | else return EOF; 544 | } 545 | 546 | int FCGI_putchar(int c) 547 | { 548 | return FCGI_fputc(c, FCGI_stdout); 549 | } 550 | 551 | /* 552 | *---------------------------------------------------------------------- 553 | * 554 | * FCGI_fputs, FCGI_puts 555 | * 556 | * Wrappers for functions defined in H&S Section 15.10 557 | * 558 | *---------------------------------------------------------------------- 559 | */ 560 | int FCGI_fputs(const char *str, FCGI_FILE *fp) 561 | { 562 | if(fp->stdio_stream) 563 | return fputs(str, fp->stdio_stream); 564 | else if(fp->fcgx_stream) 565 | return FCGX_PutS(str, fp->fcgx_stream); 566 | return EOF; 567 | } 568 | 569 | int FCGI_puts(const char *str) 570 | { 571 | int n; 572 | if(FCGI_stdout->stdio_stream) { 573 | n = fputs(str, FCGI_stdout->stdio_stream); 574 | if(n < 0) 575 | return n; 576 | else 577 | return fputc('\n', FCGI_stdout->stdio_stream); 578 | } else if(FCGI_stdout->fcgx_stream) { 579 | n = FCGX_PutS(str, FCGI_stdout->fcgx_stream); 580 | if(n < 0) 581 | return n; 582 | else 583 | return FCGX_PutChar('\n', FCGI_stdout->fcgx_stream); 584 | } 585 | return EOF; 586 | } 587 | 588 | /* 589 | *---------------------------------------------------------------------- 590 | * 591 | * FCGI_fprintf, FCGI_printf -- 592 | * 593 | * Wrappers for functions defined in H&S Section 15.11 594 | * 595 | *---------------------------------------------------------------------- 596 | */ 597 | int FCGI_fprintf(FCGI_FILE *fp, const char *format, ...) 598 | { 599 | va_list ap; 600 | int n = 0; 601 | va_start(ap, format); 602 | if(fp->stdio_stream) 603 | n = vfprintf(fp->stdio_stream, format, ap); 604 | else if(fp->fcgx_stream) 605 | n = FCGX_VFPrintF(fp->fcgx_stream, format, ap); 606 | va_end(ap); 607 | return n; 608 | } 609 | 610 | int FCGI_printf(const char *format, ...) 611 | { 612 | va_list ap; 613 | int n; 614 | va_start(ap, format); 615 | n = FCGI_vfprintf(FCGI_stdout, format, ap); 616 | va_end(ap); 617 | return n; 618 | } 619 | 620 | /* 621 | *---------------------------------------------------------------------- 622 | * 623 | * FCGI_vfprintf, FCGI_vprintf -- 624 | * 625 | * Wrappers for functions defined in H&S Section 15.12 626 | * 627 | *---------------------------------------------------------------------- 628 | */ 629 | int FCGI_vfprintf(FCGI_FILE *fp, const char *format, va_list ap) 630 | { 631 | if(fp->stdio_stream) 632 | return vfprintf(fp->stdio_stream, format, ap); 633 | else if(fp->fcgx_stream) 634 | return FCGX_VFPrintF(fp->fcgx_stream, format, ap); 635 | return EOF; 636 | } 637 | 638 | int FCGI_vprintf(const char *format, va_list ap) 639 | { 640 | if(FCGI_stdout->stdio_stream) 641 | return vfprintf(FCGI_stdout->stdio_stream, format, ap); 642 | else if(FCGI_stdout->fcgx_stream) 643 | return FCGX_VFPrintF(FCGI_stdout->fcgx_stream, format, ap); 644 | return EOF; 645 | } 646 | 647 | /* 648 | *---------------------------------------------------------------------- 649 | * 650 | * FCGI_fread, FCGI_fwrite -- 651 | * 652 | * Wrappers for functions defined in H&S Section 15.13 653 | * 654 | *---------------------------------------------------------------------- 655 | */ 656 | size_t FCGI_fread(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp) 657 | { 658 | int n; 659 | if(fp->stdio_stream) 660 | return fread(ptr, size, nmemb, fp->stdio_stream); 661 | else if(fp->fcgx_stream) { 662 | if((size * nmemb) == 0) { 663 | return 0; 664 | } 665 | n = FCGX_GetStr((char *) ptr, size * nmemb, fp->fcgx_stream); 666 | return (n/size); 667 | } 668 | return (size_t)EOF; 669 | } 670 | 671 | size_t FCGI_fwrite(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp) 672 | { 673 | int n; 674 | if(fp->stdio_stream) 675 | return fwrite(ptr, size, nmemb, fp->stdio_stream); 676 | else if(fp->fcgx_stream) { 677 | if((size * nmemb) == 0) { 678 | return 0; 679 | } 680 | n = FCGX_PutStr((char *) ptr, size * nmemb, fp->fcgx_stream); 681 | return (n/size); 682 | } 683 | return (size_t)EOF; 684 | } 685 | 686 | /* 687 | *---------------------------------------------------------------------- 688 | * 689 | * FCGI_feof, FCGI_ferror, FCGI_clearerr -- 690 | * 691 | * Wrappers for functions defined in H&S Section 15.14 692 | * 693 | *---------------------------------------------------------------------- 694 | */ 695 | int FCGI_feof(FCGI_FILE *fp) 696 | { 697 | if(fp->stdio_stream) { 698 | return feof(fp->stdio_stream); 699 | } else if (fp->fcgx_stream){ 700 | return FCGX_HasSeenEOF(fp->fcgx_stream); 701 | } 702 | return -1; 703 | 704 | } 705 | 706 | int FCGI_ferror(FCGI_FILE *fp) 707 | { 708 | if(fp->stdio_stream) { 709 | return ferror(fp->stdio_stream); 710 | } else if(fp->fcgx_stream) { 711 | return FCGX_GetError(fp->fcgx_stream); 712 | } 713 | return -1; 714 | } 715 | 716 | void FCGI_clearerr(FCGI_FILE *fp) 717 | { 718 | if(fp->stdio_stream) { 719 | clearerr(fp->stdio_stream); 720 | } else if(fp->fcgx_stream) { 721 | FCGX_ClearError(fp->fcgx_stream); 722 | } 723 | return; 724 | } 725 | 726 | /* 727 | *---------------------------------------------------------------------- 728 | * 729 | * FCGI_tmpfile -- 730 | * 731 | * Wrappers for function defined in H&S Section 15.16 732 | * 733 | *---------------------------------------------------------------------- 734 | */ 735 | FCGI_FILE *FCGI_tmpfile(void) 736 | { 737 | FILE * file = tmpfile(); 738 | FCGI_FILE * fcgi_file = FCGI_OpenFromFILE(file); 739 | 740 | if (file && !fcgi_file) 741 | fclose(file); 742 | 743 | return fcgi_file; 744 | } 745 | 746 | /* 747 | *---------------------------------------------------------------------- 748 | * 749 | * FCGI_fileno, FCGI_fdopen, FCGI_popen, FCGI_pclose -- 750 | * 751 | * Wrappers for POSIX, X/OPEN functions not in ISO C 752 | * 753 | *---------------------------------------------------------------------- 754 | */ 755 | int FCGI_fileno(FCGI_FILE *fp) 756 | { 757 | if(fp->stdio_stream) 758 | return fileno(fp->stdio_stream); 759 | else 760 | return -1; 761 | } 762 | 763 | FCGI_FILE *FCGI_fdopen(int fd, const char *mode) 764 | { 765 | FILE * file = fdopen(fd, mode); 766 | FCGI_FILE * fcgi_file = FCGI_OpenFromFILE(file); 767 | 768 | if (file && !fcgi_file) 769 | fclose(file); 770 | 771 | return fcgi_file; 772 | } 773 | 774 | FCGI_FILE *FCGI_popen(const char *cmd, const char *type) 775 | { 776 | FILE * file = popen(cmd, type); 777 | FCGI_FILE * fcgi_file = FCGI_OpenFromFILE(file); 778 | 779 | if (file && !fcgi_file) 780 | pclose(file); 781 | 782 | return fcgi_file; 783 | } 784 | 785 | int FCGI_pclose(FCGI_FILE *fp) 786 | { 787 | int n = EOF; 788 | if (fp->stdio_stream) { 789 | n = pclose(fp->stdio_stream); 790 | fp->stdio_stream = NULL; 791 | } else if(fp->fcgx_stream) { 792 | /* 793 | * The caller is deeply confused; don't free the storage. 794 | */ 795 | return EOF; 796 | } 797 | if((fp != FCGI_stdin) && (fp != FCGI_stdout) && (fp != FCGI_stderr)) { 798 | free(fp); 799 | } 800 | return n; 801 | } 802 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fcgi_stdio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fcgi_stdio.h -- 3 | * 4 | * FastCGI-stdio compatibility package 5 | * 6 | * 7 | * Copyright (c) 1996 Open Market, Inc. 8 | * 9 | * See the file "LICENSE.TERMS" for information on usage and redistribution 10 | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 11 | * 12 | * $Id: fcgi_stdio.h,v 1.5 2001/06/22 13:21:15 robs Exp $ 13 | */ 14 | 15 | #ifndef _FCGI_STDIO 16 | #define _FCGI_STDIO 1 17 | 18 | #include 19 | #include 20 | #include "fcgiapp.h" 21 | 22 | #if defined (c_plusplus) || defined (__cplusplus) 23 | extern "C" { 24 | #endif 25 | 26 | #ifndef DLLAPI 27 | #ifdef _WIN32 28 | #define DLLAPI __declspec(dllimport) 29 | #else 30 | #define DLLAPI 31 | #endif 32 | #endif 33 | 34 | /* 35 | * Wrapper type for FILE 36 | */ 37 | 38 | typedef struct { 39 | FILE *stdio_stream; 40 | FCGX_Stream *fcgx_stream; 41 | } FCGI_FILE; 42 | 43 | /* 44 | * The four new functions and two new macros 45 | */ 46 | 47 | DLLAPI int FCGI_Accept(void); 48 | DLLAPI void FCGI_Finish(void); 49 | DLLAPI int FCGI_StartFilterData(void); 50 | DLLAPI void FCGI_SetExitStatus(int status); 51 | 52 | #define FCGI_ToFILE(fcgi_file) (fcgi_file->stdio_stream) 53 | #define FCGI_ToFcgiStream(fcgi_file) (fcgi_file->fcgx_stream) 54 | 55 | /* 56 | * Wrapper stdin, stdout, and stderr variables, set up by FCGI_Accept() 57 | */ 58 | 59 | DLLAPI extern FCGI_FILE _fcgi_sF[]; 60 | #define FCGI_stdin (&_fcgi_sF[0]) 61 | #define FCGI_stdout (&_fcgi_sF[1]) 62 | #define FCGI_stderr (&_fcgi_sF[2]) 63 | 64 | /* 65 | * Wrapper function prototypes, grouped according to sections 66 | * of Harbison & Steele, "C: A Reference Manual," fourth edition, 67 | * Prentice-Hall, 1995. 68 | */ 69 | 70 | DLLAPI void FCGI_perror(const char *str); 71 | 72 | DLLAPI FCGI_FILE *FCGI_fopen(const char *path, const char *mode); 73 | DLLAPI int FCGI_fclose(FCGI_FILE *fp); 74 | DLLAPI int FCGI_fflush(FCGI_FILE *fp); 75 | DLLAPI FCGI_FILE *FCGI_freopen(const char *path, const char *mode, FCGI_FILE *fp); 76 | 77 | DLLAPI int FCGI_setvbuf(FCGI_FILE *fp, char *buf, int bufmode, size_t size); 78 | DLLAPI void FCGI_setbuf(FCGI_FILE *fp, char *buf); 79 | 80 | DLLAPI int FCGI_fseek(FCGI_FILE *fp, long offset, int whence); 81 | DLLAPI int FCGI_ftell(FCGI_FILE *fp); 82 | DLLAPI void FCGI_rewind(FCGI_FILE *fp); 83 | #ifdef HAVE_FPOS 84 | DLLAPI int FCGI_fgetpos(FCGI_FILE *fp, fpos_t *pos); 85 | DLLAPI int FCGI_fsetpos(FCGI_FILE *fp, const fpos_t *pos); 86 | #endif 87 | DLLAPI int FCGI_fgetc(FCGI_FILE *fp); 88 | DLLAPI int FCGI_getchar(void); 89 | DLLAPI int FCGI_ungetc(int c, FCGI_FILE *fp); 90 | 91 | DLLAPI char *FCGI_fgets(char *str, int size, FCGI_FILE *fp); 92 | DLLAPI char *FCGI_gets(char *str); 93 | 94 | /* 95 | * Not yet implemented 96 | * 97 | * int FCGI_fscanf(FCGI_FILE *fp, const char *format, ...); 98 | * int FCGI_scanf(const char *format, ...); 99 | * 100 | */ 101 | 102 | DLLAPI int FCGI_fputc(int c, FCGI_FILE *fp); 103 | DLLAPI int FCGI_putchar(int c); 104 | 105 | DLLAPI int FCGI_fputs(const char *str, FCGI_FILE *fp); 106 | DLLAPI int FCGI_puts(const char *str); 107 | 108 | DLLAPI int FCGI_fprintf(FCGI_FILE *fp, const char *format, ...); 109 | DLLAPI int FCGI_printf(const char *format, ...); 110 | 111 | DLLAPI int FCGI_vfprintf(FCGI_FILE *fp, const char *format, va_list ap); 112 | DLLAPI int FCGI_vprintf(const char *format, va_list ap); 113 | 114 | DLLAPI size_t FCGI_fread(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp); 115 | DLLAPI size_t FCGI_fwrite(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp); 116 | 117 | DLLAPI int FCGI_feof(FCGI_FILE *fp); 118 | DLLAPI int FCGI_ferror(FCGI_FILE *fp); 119 | DLLAPI void FCGI_clearerr(FCGI_FILE *fp); 120 | 121 | DLLAPI FCGI_FILE *FCGI_tmpfile(void); 122 | 123 | DLLAPI int FCGI_fileno(FCGI_FILE *fp); 124 | DLLAPI FCGI_FILE *FCGI_fdopen(int fd, const char *mode); 125 | DLLAPI FCGI_FILE *FCGI_popen(const char *cmd, const char *type); 126 | DLLAPI int FCGI_pclose(FCGI_FILE *); 127 | 128 | /* 129 | * The remaining definitions are for application programs, 130 | * not for fcgi_stdio.c 131 | */ 132 | 133 | #ifndef NO_FCGI_DEFINES 134 | 135 | /* 136 | * Replace standard types, variables, and functions with FastCGI wrappers. 137 | * Use undef in case a macro is already defined. 138 | */ 139 | 140 | #undef FILE 141 | #define FILE FCGI_FILE 142 | 143 | #undef stdin 144 | #define stdin FCGI_stdin 145 | #undef stdout 146 | #define stdout FCGI_stdout 147 | #undef stderr 148 | #define stderr FCGI_stderr 149 | 150 | #undef perror 151 | #define perror FCGI_perror 152 | 153 | #undef fopen 154 | #define fopen FCGI_fopen 155 | #undef fclose 156 | #define fclose FCGI_fclose 157 | #undef fflush 158 | #define fflush FCGI_fflush 159 | #undef freopen 160 | #define freopen FCGI_freopen 161 | 162 | #undef setvbuf 163 | #define setvbuf FCGI_setvbuf 164 | #undef setbuf 165 | #define setbuf FCGI_setbuf 166 | 167 | #undef fseek 168 | #define fseek FCGI_fseek 169 | #undef ftell 170 | #define ftell FCGI_ftell 171 | #undef rewind 172 | #define rewind FCGI_rewind 173 | #undef fgetpos 174 | #define fgetpos FCGI_fgetpos 175 | #undef fsetpos 176 | #define fsetpos FCGI_fsetpos 177 | 178 | #undef fgetc 179 | #define fgetc FCGI_fgetc 180 | #undef getc 181 | #define getc FCGI_fgetc 182 | #undef getchar 183 | #define getchar FCGI_getchar 184 | #undef ungetc 185 | #define ungetc FCGI_ungetc 186 | 187 | #undef fgets 188 | #define fgets FCGI_fgets 189 | #undef gets 190 | #define gets FCGI_gets 191 | 192 | #undef fputc 193 | #define fputc FCGI_fputc 194 | #undef putc 195 | #define putc FCGI_fputc 196 | #undef putchar 197 | #define putchar FCGI_putchar 198 | 199 | #undef fputs 200 | #define fputs FCGI_fputs 201 | #undef puts 202 | #define puts FCGI_puts 203 | 204 | #undef fprintf 205 | #define fprintf FCGI_fprintf 206 | #undef printf 207 | #define printf FCGI_printf 208 | 209 | #undef vfprintf 210 | #define vfprintf FCGI_vfprintf 211 | #undef vprintf 212 | #define vprintf FCGI_vprintf 213 | 214 | #undef fread 215 | #define fread FCGI_fread 216 | #undef fwrite 217 | #define fwrite FCGI_fwrite 218 | 219 | #undef feof 220 | #define feof FCGI_feof 221 | #undef ferror 222 | #define ferror FCGI_ferror 223 | #undef clearerr 224 | #define clearerr FCGI_clearerr 225 | 226 | #undef tmpfile 227 | #define tmpfile FCGI_tmpfile 228 | 229 | #undef fileno 230 | #define fileno FCGI_fileno 231 | #undef fdopen 232 | #define fdopen FCGI_fdopen 233 | #undef popen 234 | #define popen FCGI_popen 235 | #undef pclose 236 | #define pclose FCGI_pclose 237 | 238 | #endif /* NO_FCGI_DEFINES */ 239 | 240 | #if defined (__cplusplus) || defined (c_plusplus) 241 | } /* terminate extern "C" { */ 242 | #endif 243 | 244 | #endif /* _FCGI_STDIO */ 245 | 246 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fcgiapp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fcgiapp.h -- 3 | * 4 | * Definitions for FastCGI application server programs 5 | * 6 | * 7 | * Copyright (c) 1996 Open Market, Inc. 8 | * 9 | * See the file "LICENSE.TERMS" for information on usage and redistribution 10 | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 11 | * 12 | * $Id: fcgiapp.h,v 1.12 2001/11/21 21:10:11 robs Exp $ 13 | */ 14 | 15 | #ifndef _FCGIAPP_H 16 | #define _FCGIAPP_H 17 | 18 | /* Hack to see if we are building TCL - TCL needs varargs not stdarg */ 19 | #ifndef TCL_LIBRARY 20 | #include 21 | #else 22 | #include 23 | #endif 24 | 25 | #ifndef DLLAPI 26 | #ifdef _WIN32 27 | #define DLLAPI __declspec(dllimport) 28 | #else 29 | #define DLLAPI 30 | #endif 31 | #endif 32 | 33 | #if defined (c_plusplus) || defined (__cplusplus) 34 | extern "C" { 35 | #endif 36 | 37 | /* 38 | * Error codes. Assigned to avoid conflict with EOF and errno(2). 39 | */ 40 | #define FCGX_UNSUPPORTED_VERSION -2 41 | #define FCGX_PROTOCOL_ERROR -3 42 | #define FCGX_PARAMS_ERROR -4 43 | #define FCGX_CALL_SEQ_ERROR -5 44 | 45 | /* 46 | * This structure defines the state of a FastCGI stream. 47 | * Streams are modeled after the FILE type defined in stdio.h. 48 | * (We wouldn't need our own if platform vendors provided a 49 | * standard way to subclass theirs.) 50 | * The state of a stream is private and should only be accessed 51 | * by the procedures defined below. 52 | */ 53 | typedef struct FCGX_Stream { 54 | unsigned char *rdNext; /* reader: first valid byte 55 | * writer: equals stop */ 56 | unsigned char *wrNext; /* writer: first free byte 57 | * reader: equals stop */ 58 | unsigned char *stop; /* reader: last valid byte + 1 59 | * writer: last free byte + 1 */ 60 | unsigned char *stopUnget; /* reader: first byte of current buffer 61 | * fragment, for ungetc 62 | * writer: undefined */ 63 | int isReader; 64 | int isClosed; 65 | int wasFCloseCalled; 66 | int FCGI_errno; /* error status */ 67 | void (*fillBuffProc) (struct FCGX_Stream *stream); 68 | void (*emptyBuffProc) (struct FCGX_Stream *stream, int doClose); 69 | void *data; 70 | } FCGX_Stream; 71 | 72 | /* 73 | * An environment (as defined by environ(7)): A NULL-terminated array 74 | * of strings, each string having the form name=value. 75 | */ 76 | typedef char **FCGX_ParamArray; 77 | 78 | /* 79 | * FCGX_Request Flags 80 | * 81 | * Setting FCGI_FAIL_ACCEPT_ON_INTR prevents FCGX_Accept() from 82 | * restarting upon being interrupted. 83 | */ 84 | #define FCGI_FAIL_ACCEPT_ON_INTR 1 85 | 86 | /* 87 | * FCGX_Request -- State associated with a request. 88 | * 89 | * Its exposed for API simplicity, I expect parts of it to change! 90 | */ 91 | typedef struct FCGX_Request { 92 | int requestId; /* valid if isBeginProcessed */ 93 | int role; 94 | FCGX_Stream *in; 95 | FCGX_Stream *out; 96 | FCGX_Stream *err; 97 | char **envp; 98 | 99 | /* Don't use anything below here */ 100 | 101 | struct Params *paramsPtr; 102 | int ipcFd; /* < 0 means no connection */ 103 | int isBeginProcessed; /* FCGI_BEGIN_REQUEST seen */ 104 | int keepConnection; /* don't close ipcFd at end of request */ 105 | int appStatus; 106 | int nWriters; /* number of open writers (0..2) */ 107 | int flags; 108 | int listen_sock; 109 | } FCGX_Request; 110 | 111 | 112 | /* 113 | *====================================================================== 114 | * Control 115 | *====================================================================== 116 | */ 117 | 118 | /* 119 | *---------------------------------------------------------------------- 120 | * 121 | * FCGX_IsCGI -- 122 | * 123 | * Returns TRUE iff this process appears to be a CGI process 124 | * rather than a FastCGI process. 125 | * 126 | *---------------------------------------------------------------------- 127 | */ 128 | DLLAPI int FCGX_IsCGI(void); 129 | 130 | /* 131 | *---------------------------------------------------------------------- 132 | * 133 | * FCGX_Init -- 134 | * 135 | * Initialize the FCGX library. Call in multi-threaded apps 136 | * before calling FCGX_Accept_r(). 137 | * 138 | * Returns 0 upon success. 139 | * 140 | *---------------------------------------------------------------------- 141 | */ 142 | DLLAPI int FCGX_Init(void); 143 | 144 | /* 145 | *---------------------------------------------------------------------- 146 | * 147 | * FCGX_OpenSocket -- 148 | * 149 | * Create a FastCGI listen socket. 150 | * 151 | * path is the Unix domain socket (named pipe for WinNT), or a colon 152 | * followed by a port number. e.g. "/tmp/fastcgi/mysocket", ":5000" 153 | * 154 | * backlog is the listen queue depth used in the listen() call. 155 | * 156 | * Returns the socket's file descriptor or -1 on error. 157 | * 158 | *---------------------------------------------------------------------- 159 | */ 160 | DLLAPI int FCGX_OpenSocket(const char *path, int backlog); 161 | 162 | /* 163 | *---------------------------------------------------------------------- 164 | * 165 | * FCGX_InitRequest -- 166 | * 167 | * Initialize a FCGX_Request for use with FCGX_Accept_r(). 168 | * 169 | * sock is a file descriptor returned by FCGX_OpenSocket() or 0 (default). 170 | * The only supported flag at this time is FCGI_FAIL_ON_INTR. 171 | * 172 | * Returns 0 upon success. 173 | *---------------------------------------------------------------------- 174 | */ 175 | DLLAPI int FCGX_InitRequest(FCGX_Request *request, int sock, int flags); 176 | 177 | /* 178 | *---------------------------------------------------------------------- 179 | * 180 | * FCGX_Accept_r -- 181 | * 182 | * Accept a new request (multi-thread safe). Be sure to call 183 | * FCGX_Init() first. 184 | * 185 | * Results: 186 | * 0 for successful call, -1 for error. 187 | * 188 | * Side effects: 189 | * 190 | * Finishes the request accepted by (and frees any 191 | * storage allocated by) the previous call to FCGX_Accept. 192 | * Creates input, output, and error streams and 193 | * assigns them to *in, *out, and *err respectively. 194 | * Creates a parameters data structure to be accessed 195 | * via getenv(3) (if assigned to environ) or by FCGX_GetParam 196 | * and assigns it to *envp. 197 | * 198 | * DO NOT retain pointers to the envp array or any strings 199 | * contained in it (e.g. to the result of calling FCGX_GetParam), 200 | * since these will be freed by the next call to FCGX_Finish 201 | * or FCGX_Accept. 202 | * 203 | * DON'T use the FCGX_Request, its structure WILL change. 204 | * 205 | *---------------------------------------------------------------------- 206 | */ 207 | DLLAPI int FCGX_Accept_r(FCGX_Request *request); 208 | 209 | /* 210 | *---------------------------------------------------------------------- 211 | * 212 | * FCGX_Finish_r -- 213 | * 214 | * Finish the request (multi-thread safe). 215 | * 216 | * Side effects: 217 | * 218 | * Finishes the request accepted by (and frees any 219 | * storage allocated by) the previous call to FCGX_Accept. 220 | * 221 | * DO NOT retain pointers to the envp array or any strings 222 | * contained in it (e.g. to the result of calling FCGX_GetParam), 223 | * since these will be freed by the next call to FCGX_Finish 224 | * or FCGX_Accept. 225 | * 226 | *---------------------------------------------------------------------- 227 | */ 228 | DLLAPI void FCGX_Finish_r(FCGX_Request *request); 229 | 230 | /* 231 | *---------------------------------------------------------------------- 232 | * 233 | * FCGX_Free -- 234 | * 235 | * Free the memory and, if close is true, 236 | * IPC FD associated with the request (multi-thread safe). 237 | * 238 | *---------------------------------------------------------------------- 239 | */ 240 | DLLAPI void FCGX_Free(FCGX_Request * request, int close); 241 | 242 | /* 243 | *---------------------------------------------------------------------- 244 | * 245 | * FCGX_Accept -- 246 | * 247 | * Accept a new request (NOT multi-thread safe). 248 | * 249 | * Results: 250 | * 0 for successful call, -1 for error. 251 | * 252 | * Side effects: 253 | * 254 | * Finishes the request accepted by (and frees any 255 | * storage allocated by) the previous call to FCGX_Accept. 256 | * Creates input, output, and error streams and 257 | * assigns them to *in, *out, and *err respectively. 258 | * Creates a parameters data structure to be accessed 259 | * via getenv(3) (if assigned to environ) or by FCGX_GetParam 260 | * and assigns it to *envp. 261 | * 262 | * DO NOT retain pointers to the envp array or any strings 263 | * contained in it (e.g. to the result of calling FCGX_GetParam), 264 | * since these will be freed by the next call to FCGX_Finish 265 | * or FCGX_Accept. 266 | * 267 | *---------------------------------------------------------------------- 268 | */ 269 | DLLAPI int FCGX_Accept( 270 | FCGX_Stream **in, 271 | FCGX_Stream **out, 272 | FCGX_Stream **err, 273 | FCGX_ParamArray *envp); 274 | 275 | /* 276 | *---------------------------------------------------------------------- 277 | * 278 | * FCGX_Finish -- 279 | * 280 | * Finish the current request (NOT multi-thread safe). 281 | * 282 | * Side effects: 283 | * 284 | * Finishes the request accepted by (and frees any 285 | * storage allocated by) the previous call to FCGX_Accept. 286 | * 287 | * DO NOT retain pointers to the envp array or any strings 288 | * contained in it (e.g. to the result of calling FCGX_GetParam), 289 | * since these will be freed by the next call to FCGX_Finish 290 | * or FCGX_Accept. 291 | * 292 | *---------------------------------------------------------------------- 293 | */ 294 | DLLAPI void FCGX_Finish(void); 295 | 296 | /* 297 | *---------------------------------------------------------------------- 298 | * 299 | * FCGX_StartFilterData -- 300 | * 301 | * stream is an input stream for a FCGI_FILTER request. 302 | * stream is positioned at EOF on FCGI_STDIN. 303 | * Repositions stream to the start of FCGI_DATA. 304 | * If the preconditions are not met (e.g. FCGI_STDIN has not 305 | * been read to EOF) sets the stream error code to 306 | * FCGX_CALL_SEQ_ERROR. 307 | * 308 | * Results: 309 | * 0 for a normal return, < 0 for error 310 | * 311 | *---------------------------------------------------------------------- 312 | */ 313 | DLLAPI int FCGX_StartFilterData(FCGX_Stream *stream); 314 | 315 | /* 316 | *---------------------------------------------------------------------- 317 | * 318 | * FCGX_SetExitStatus -- 319 | * 320 | * Sets the exit status for stream's request. The exit status 321 | * is the status code the request would have exited with, had 322 | * the request been run as a CGI program. You can call 323 | * SetExitStatus several times during a request; the last call 324 | * before the request ends determines the value. 325 | * 326 | *---------------------------------------------------------------------- 327 | */ 328 | DLLAPI void FCGX_SetExitStatus(int status, FCGX_Stream *stream); 329 | 330 | /* 331 | *====================================================================== 332 | * Parameters 333 | *====================================================================== 334 | */ 335 | 336 | /* 337 | *---------------------------------------------------------------------- 338 | * 339 | * FCGX_GetParam -- obtain value of FCGI parameter in environment 340 | * 341 | * 342 | * Results: 343 | * Value bound to name, NULL if name not present in the 344 | * environment envp. Caller must not mutate the result 345 | * or retain it past the end of this request. 346 | * 347 | *---------------------------------------------------------------------- 348 | */ 349 | DLLAPI char *FCGX_GetParam(const char *name, FCGX_ParamArray envp); 350 | 351 | /* 352 | *====================================================================== 353 | * Readers 354 | *====================================================================== 355 | */ 356 | 357 | /* 358 | *---------------------------------------------------------------------- 359 | * 360 | * FCGX_GetChar -- 361 | * 362 | * Reads a byte from the input stream and returns it. 363 | * 364 | * Results: 365 | * The byte, or EOF (-1) if the end of input has been reached. 366 | * 367 | *---------------------------------------------------------------------- 368 | */ 369 | DLLAPI int FCGX_GetChar(FCGX_Stream *stream); 370 | 371 | /* 372 | *---------------------------------------------------------------------- 373 | * 374 | * FCGX_UnGetChar -- 375 | * 376 | * Pushes back the character c onto the input stream. One 377 | * character of pushback is guaranteed once a character 378 | * has been read. No pushback is possible for EOF. 379 | * 380 | * Results: 381 | * Returns c if the pushback succeeded, EOF if not. 382 | * 383 | *---------------------------------------------------------------------- 384 | */ 385 | DLLAPI int FCGX_UnGetChar(int c, FCGX_Stream *stream); 386 | 387 | /* 388 | *---------------------------------------------------------------------- 389 | * 390 | * FCGX_GetStr -- 391 | * 392 | * Reads up to n consecutive bytes from the input stream 393 | * into the character array str. Performs no interpretation 394 | * of the input bytes. 395 | * 396 | * Results: 397 | * Number of bytes read. If result is smaller than n, 398 | * the end of input has been reached. 399 | * 400 | *---------------------------------------------------------------------- 401 | */ 402 | DLLAPI int FCGX_GetStr(char *str, int n, FCGX_Stream *stream); 403 | 404 | /* 405 | *---------------------------------------------------------------------- 406 | * 407 | * FCGX_GetLine -- 408 | * 409 | * Reads up to n-1 consecutive bytes from the input stream 410 | * into the character array str. Stops before n-1 bytes 411 | * have been read if '\n' or EOF is read. The terminating '\n' 412 | * is copied to str. After copying the last byte into str, 413 | * stores a '\0' terminator. 414 | * 415 | * Results: 416 | * NULL if EOF is the first thing read from the input stream, 417 | * str otherwise. 418 | * 419 | *---------------------------------------------------------------------- 420 | */ 421 | DLLAPI char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream); 422 | 423 | /* 424 | *---------------------------------------------------------------------- 425 | * 426 | * FCGX_HasSeenEOF -- 427 | * 428 | * Returns EOF if end-of-file has been detected while reading 429 | * from stream; otherwise returns 0. 430 | * 431 | * Note that FCGX_HasSeenEOF(s) may return 0, yet an immediately 432 | * following FCGX_GetChar(s) may return EOF. This function, like 433 | * the standard C stdio function feof, does not provide the 434 | * ability to peek ahead. 435 | * 436 | * Results: 437 | * EOF if end-of-file has been detected, 0 if not. 438 | * 439 | *---------------------------------------------------------------------- 440 | */ 441 | 442 | DLLAPI int FCGX_HasSeenEOF(FCGX_Stream *stream); 443 | 444 | /* 445 | *====================================================================== 446 | * Writers 447 | *====================================================================== 448 | */ 449 | 450 | /* 451 | *---------------------------------------------------------------------- 452 | * 453 | * FCGX_PutChar -- 454 | * 455 | * Writes a byte to the output stream. 456 | * 457 | * Results: 458 | * The byte, or EOF (-1) if an error occurred. 459 | * 460 | *---------------------------------------------------------------------- 461 | */ 462 | DLLAPI int FCGX_PutChar(int c, FCGX_Stream *stream); 463 | 464 | /* 465 | *---------------------------------------------------------------------- 466 | * 467 | * FCGX_PutStr -- 468 | * 469 | * Writes n consecutive bytes from the character array str 470 | * into the output stream. Performs no interpretation 471 | * of the output bytes. 472 | * 473 | * Results: 474 | * Number of bytes written (n) for normal return, 475 | * EOF (-1) if an error occurred. 476 | * 477 | *---------------------------------------------------------------------- 478 | */ 479 | DLLAPI int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream); 480 | 481 | /* 482 | *---------------------------------------------------------------------- 483 | * 484 | * FCGX_PutS -- 485 | * 486 | * Writes a null-terminated character string to the output stream. 487 | * 488 | * Results: 489 | * number of bytes written for normal return, 490 | * EOF (-1) if an error occurred. 491 | * 492 | *---------------------------------------------------------------------- 493 | */ 494 | DLLAPI int FCGX_PutS(const char *str, FCGX_Stream *stream); 495 | 496 | /* 497 | *---------------------------------------------------------------------- 498 | * 499 | * FCGX_FPrintF, FCGX_VFPrintF -- 500 | * 501 | * Performs printf-style output formatting and writes the results 502 | * to the output stream. 503 | * 504 | * Results: 505 | * number of bytes written for normal return, 506 | * EOF (-1) if an error occurred. 507 | * 508 | *---------------------------------------------------------------------- 509 | */ 510 | DLLAPI int FCGX_FPrintF(FCGX_Stream *stream, const char *format, ...); 511 | 512 | DLLAPI int FCGX_VFPrintF(FCGX_Stream *stream, const char *format, va_list arg); 513 | 514 | /* 515 | *---------------------------------------------------------------------- 516 | * 517 | * FCGX_FFlush -- 518 | * 519 | * Flushes any buffered output. 520 | * 521 | * Server-push is a legitimate application of FCGX_FFlush. 522 | * Otherwise, FCGX_FFlush is not very useful, since FCGX_Accept 523 | * does it implicitly. Calling FCGX_FFlush in non-push applications 524 | * results in extra writes and therefore reduces performance. 525 | * 526 | * Results: 527 | * EOF (-1) if an error occurred. 528 | * 529 | *---------------------------------------------------------------------- 530 | */ 531 | DLLAPI int FCGX_FFlush(FCGX_Stream *stream); 532 | 533 | /* 534 | *====================================================================== 535 | * Both Readers and Writers 536 | *====================================================================== 537 | */ 538 | 539 | /* 540 | *---------------------------------------------------------------------- 541 | * 542 | * FCGX_FClose -- 543 | * 544 | * Closes the stream. For writers, flushes any buffered 545 | * output. 546 | * 547 | * Close is not a very useful operation since FCGX_Accept 548 | * does it implicitly. Closing the out stream before the 549 | * err stream results in an extra write if there's nothing 550 | * in the err stream, and therefore reduces performance. 551 | * 552 | * Results: 553 | * EOF (-1) if an error occurred. 554 | * 555 | *---------------------------------------------------------------------- 556 | */ 557 | DLLAPI int FCGX_FClose(FCGX_Stream *stream); 558 | 559 | /* 560 | *---------------------------------------------------------------------- 561 | * 562 | * FCGX_GetError -- 563 | * 564 | * Return the stream error code. 0 means no error, > 0 565 | * is an errno(2) error, < 0 is an FastCGI error. 566 | * 567 | *---------------------------------------------------------------------- 568 | */ 569 | DLLAPI int FCGX_GetError(FCGX_Stream *stream); 570 | 571 | /* 572 | *---------------------------------------------------------------------- 573 | * 574 | * FCGX_ClearError -- 575 | * 576 | * Clear the stream error code and end-of-file indication. 577 | * 578 | *---------------------------------------------------------------------- 579 | */ 580 | DLLAPI void FCGX_ClearError(FCGX_Stream *stream); 581 | 582 | /* 583 | *---------------------------------------------------------------------- 584 | * 585 | * FCGX_CreateWriter -- 586 | * 587 | * Create a FCGX_Stream (used by cgi-fcgi). This shouldn't 588 | * be needed by a FastCGI applictaion. 589 | * 590 | *---------------------------------------------------------------------- 591 | */ 592 | DLLAPI FCGX_Stream *FCGX_CreateWriter( 593 | int socket, 594 | int requestId, 595 | int bufflen, 596 | int streamType); 597 | 598 | /* 599 | *---------------------------------------------------------------------- 600 | * 601 | * FCGX_FreeStream -- 602 | * 603 | * Free a FCGX_Stream (used by cgi-fcgi). This shouldn't 604 | * be needed by a FastCGI applictaion. 605 | * 606 | *---------------------------------------------------------------------- 607 | */ 608 | DLLAPI void FCGX_FreeStream(FCGX_Stream **stream); 609 | 610 | /* ---------------------------------------------------------------------- 611 | * 612 | * Prevent the lib from accepting any new requests. Signal handler safe. 613 | * 614 | * ---------------------------------------------------------------------- 615 | */ 616 | DLLAPI void FCGX_ShutdownPending(void); 617 | 618 | #if defined (__cplusplus) || defined (c_plusplus) 619 | } /* terminate extern "C" { */ 620 | #endif 621 | 622 | #endif /* _FCGIAPP_H */ 623 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fcgimisc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fcgimisc.h -- 3 | * 4 | * Miscellaneous definitions 5 | * 6 | * 7 | * Copyright (c) 1996 Open Market, Inc. 8 | * 9 | * See the file "LICENSE.TERMS" for information on usage and redistribution 10 | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 11 | * 12 | * $Id: fcgimisc.h,v 1.3 2001/06/18 14:25:47 robs Exp $ 13 | */ 14 | 15 | #ifndef _FCGIMISC_H 16 | #define _FCGIMISC_H 17 | 18 | #ifndef FALSE 19 | #define FALSE (0) 20 | #endif 21 | 22 | #ifndef TRUE 23 | #define TRUE (1) 24 | #endif 25 | 26 | #ifndef min 27 | #define min(a,b) ((a) < (b) ? (a) : (b)) 28 | #endif 29 | 30 | #ifndef max 31 | #define max(a,b) ((a) > (b) ? (a) : (b)) 32 | #endif 33 | 34 | #ifndef ASSERT 35 | #define ASSERT(assertion) assert(assertion) 36 | #endif 37 | 38 | #endif /* _FCGIMISC_H */ 39 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fcgio.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // $Id: fcgio.cpp,v 1.13 2002/02/24 20:12:22 robs Exp $ 3 | // 4 | // Allows you communicate with FastCGI streams using C++ iostreams 5 | // 6 | // ORIGINAL AUTHOR: George Feinberg 7 | // REWRITTEN BY: Michael Richards 06/20/1999 8 | // REWRITTEN AGAIN BY: Michael Shell 02/23/2000 9 | // REWRITTEN AGAIN BY: Rob Saccoccio 11 Nov 2001 10 | // 11 | // Copyright (c) 2000 Tux the Linux Penguin 12 | // 13 | // You are free to use this software without charge or royalty 14 | // as long as this notice is not removed or altered, and recognition 15 | // is given to the author(s) 16 | // 17 | // This code is offered as-is without any warranty either expressed or 18 | // implied; without even the implied warranty of MERCHANTABILITY or 19 | // FITNESS FOR A PARTICULAR PURPOSE. 20 | 21 | #ifdef _WIN32 22 | #define DLLAPI __declspec(dllexport) 23 | #endif 24 | 25 | #include 26 | #include "fcgio.h" 27 | 28 | using std::streambuf; 29 | using std::istream; 30 | using std::ostream; 31 | using std::streamsize; 32 | 33 | fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs, char * b, int bs) 34 | { 35 | init(fs, b, bs); 36 | } 37 | 38 | fcgi_streambuf::fcgi_streambuf(char_type * b, streamsize bs) 39 | { 40 | init(0, b, bs); 41 | } 42 | 43 | fcgi_streambuf::fcgi_streambuf(FCGX_Stream * fs) 44 | { 45 | init(fs, 0, 0); 46 | } 47 | 48 | fcgi_streambuf::~fcgi_streambuf(void) 49 | { 50 | overflow(EOF); 51 | // FCGX_Finish()/FCGX_Accept() will flush and close 52 | } 53 | 54 | void fcgi_streambuf::init(FCGX_Stream * fs, char_type * b, streamsize bs) 55 | { 56 | this->fcgx = fs; 57 | this->buf = 0; 58 | this->bufsize = 0; 59 | setbuf(b, bs); 60 | } 61 | 62 | int fcgi_streambuf::overflow(int c) 63 | { 64 | if (this->bufsize) 65 | { 66 | int plen = pptr() - pbase(); 67 | 68 | if (plen) 69 | { 70 | if (FCGX_PutStr(pbase(), plen, this->fcgx) != plen) return EOF; 71 | pbump(-plen); 72 | } 73 | } 74 | 75 | if (c != EOF) 76 | { 77 | if (FCGX_PutChar(c, this->fcgx) != c) return EOF; 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | // default base class behaviour seems to be inconsistent 84 | int fcgi_streambuf::sync() 85 | { 86 | if (overflow(EOF)) return EOF; 87 | if (FCGX_FFlush(this->fcgx)) return EOF; 88 | return 0; 89 | } 90 | 91 | // uflow() removes the char, underflow() doesn't 92 | int fcgi_streambuf::uflow() 93 | { 94 | int rv = underflow(); 95 | if (this->bufsize) gbump(1); 96 | return rv; 97 | } 98 | 99 | // Note that the expected behaviour when there is no buffer varies 100 | int fcgi_streambuf::underflow() 101 | { 102 | if (this->bufsize) 103 | { 104 | if (in_avail() == 0) 105 | { 106 | int glen = FCGX_GetStr(eback(), this->bufsize, this->fcgx); 107 | if (glen <= 0) return EOF; 108 | 109 | setg(eback(), eback(), eback() + glen); 110 | } 111 | 112 | return (unsigned char) *gptr(); 113 | } 114 | else 115 | { 116 | return FCGX_GetChar(this->fcgx); 117 | } 118 | } 119 | 120 | void fcgi_streambuf::reset(void) 121 | { 122 | // it should be ok to set up both the get and put areas 123 | setg(this->buf, this->buf, this->buf); 124 | setp(this->buf, this->buf + this->bufsize); 125 | } 126 | 127 | std::streambuf * fcgi_streambuf::setbuf(char_type * b, streamsize bs) 128 | { 129 | // XXX support moving data from an old buffer 130 | if (this->bufsize) return 0; 131 | 132 | this->buf = b; 133 | this->bufsize = bs; 134 | 135 | // the base setbuf() *has* to be called 136 | streambuf::setbuf(b, bs); 137 | 138 | reset(); 139 | 140 | return this; 141 | } 142 | 143 | int fcgi_streambuf::attach(FCGX_Stream * fs) 144 | { 145 | this->fcgx = fs; 146 | 147 | if (this->bufsize) 148 | { 149 | reset(); 150 | } 151 | 152 | return 0; 153 | } 154 | 155 | streamsize fcgi_streambuf::xsgetn(char_type * s, streamsize n) 156 | { 157 | if (n > INT_MAX) return 0; 158 | return (this->bufsize) 159 | ? streambuf::xsgetn(s, n) 160 | : (streamsize) FCGX_GetStr((char *) s, (int) n, this->fcgx); 161 | } 162 | 163 | streamsize fcgi_streambuf::xsputn(const char_type * s, streamsize n) 164 | { 165 | if (n > INT_MAX) return 0; 166 | return (this->bufsize) 167 | ? streambuf::xsputn(s, n) 168 | : (streamsize) FCGX_PutStr((char *) s, (int) n, this->fcgx); 169 | } 170 | 171 | // deprecated 172 | fcgi_istream::fcgi_istream(FCGX_Stream * fs) : 173 | istream(&fcgi_strmbuf) 174 | { 175 | fcgi_strmbuf.attach(fs); 176 | } 177 | 178 | // deprecated 179 | void fcgi_istream::attach(FCGX_Stream * fs) 180 | { 181 | fcgi_strmbuf.attach(fs); 182 | } 183 | 184 | // deprecated 185 | fcgi_ostream::fcgi_ostream(FCGX_Stream * fs) : 186 | ostream(&fcgi_strmbuf) 187 | { 188 | fcgi_strmbuf.attach(fs); 189 | } 190 | 191 | // deprecated 192 | void fcgi_ostream::attach(FCGX_Stream * fs) 193 | { 194 | fcgi_strmbuf.attach(fs); 195 | } 196 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fcgio.h: -------------------------------------------------------------------------------- 1 | // 2 | // Provides support for FastCGI via C++ iostreams. 3 | // 4 | // $Id: fcgio.h,v 1.15 2002/02/25 13:16:11 robs Exp $ 5 | // 6 | // This work is based on routines written by George Feinberg. They 7 | // have been mostly re-written and extensively changed by 8 | // Michael Richards. 9 | // 10 | // Rewritten again with bug fixes and numerous enhancements by 11 | // Michael Shell. 12 | // 13 | // And rewritten again by Rob Saccoccio. 14 | // 15 | // Special Thanks to Dietmar Kuehl for his help and the numerous custom 16 | // streambuf examples on his web site. 17 | // 18 | // Copyright (c) 2000 Tux the Linux Penguin 19 | // Copyright (c) 2001 Rob Saccoccio and Chelsea Networks 20 | // 21 | // You are free to use this software without charge or royalty 22 | // as long as this notice is not removed or altered, and recognition 23 | // is given to the author(s) 24 | // 25 | // This code is offered as-is without any warranty either expressed or 26 | // implied; without even the implied warranty of MERCHANTABILITY or 27 | // FITNESS FOR A PARTICULAR PURPOSE. If it breaks, you get to keep 28 | // both halves. 29 | 30 | #ifndef FCGIO_H 31 | #define FCGIO_H 32 | 33 | #include 34 | 35 | #include "fcgiapp.h" 36 | 37 | #ifndef DLLAPI 38 | #ifdef _WIN32 39 | #define DLLAPI __declspec(dllimport) 40 | #else 41 | #define DLLAPI 42 | #endif 43 | #endif 44 | 45 | #if ! HAVE_STREAMBUF_CHAR_TYPE 46 | typedef char char_type; 47 | #endif 48 | 49 | /* 50 | * fcgi_streambuf 51 | */ 52 | class DLLAPI fcgi_streambuf : public std::streambuf 53 | { 54 | public: 55 | 56 | // Note that if no buf is assigned (the default), iostream methods 57 | // such as peek(), unget() and putback() will fail. If a buf is 58 | // assigned, I/O is a bit less effecient and output streams will 59 | // have to be flushed (or the streambuf destroyed) before the next 60 | // call to "accept". 61 | fcgi_streambuf(FCGX_Stream * fcgx, char * buf, int len); 62 | 63 | fcgi_streambuf(char_type * buf, std::streamsize len); 64 | 65 | fcgi_streambuf(FCGX_Stream * fcgx = 0); 66 | 67 | ~fcgi_streambuf(void); 68 | 69 | int attach(FCGX_Stream * fcgx); 70 | 71 | protected: 72 | 73 | // Consume the put area (if buffered) and c (if c is not EOF). 74 | virtual int overflow(int); 75 | 76 | // Flush the put area (if buffered) and the FCGX buffer to the client. 77 | virtual int sync(); 78 | 79 | // Remove and return the current character. 80 | virtual int uflow(); 81 | 82 | // Fill the get area (if buffered) and return the current character. 83 | virtual int underflow(); 84 | 85 | // Use a buffer. The only reasons that a buffer would be useful is 86 | // to support the use of the unget()/putback() or seek() methods. Using 87 | // a buffer will result in less efficient I/O. Note: the underlying 88 | // FastCGI library (FCGX) maintains its own input and output buffers. 89 | virtual std::streambuf * setbuf(char_type * buf, std::streamsize len); 90 | 91 | virtual std::streamsize xsgetn(char_type * s, std::streamsize n); 92 | virtual std::streamsize xsputn(const char_type * s, std::streamsize n); 93 | 94 | private: 95 | 96 | FCGX_Stream * fcgx; 97 | 98 | // buf is just handy to have around 99 | char_type * buf; 100 | 101 | // this isn't kept by the base class 102 | std::streamsize bufsize; 103 | 104 | void init(FCGX_Stream * fcgx, char_type * buf, std::streamsize bufsize); 105 | 106 | void reset(void); 107 | }; 108 | 109 | /* 110 | * fcgi_istream - deprecated 111 | */ 112 | class DLLAPI fcgi_istream : public std::istream 113 | { 114 | public: 115 | 116 | // deprecated 117 | fcgi_istream(FCGX_Stream * fcgx = 0); 118 | 119 | // deprecated 120 | ~fcgi_istream(void) {} 121 | 122 | // deprecated 123 | virtual void attach(FCGX_Stream * fcgx); 124 | 125 | private: 126 | 127 | fcgi_streambuf fcgi_strmbuf; 128 | }; 129 | 130 | /* 131 | * fcgi_ostream - deprecated 132 | */ 133 | class DLLAPI fcgi_ostream : public std::ostream 134 | { 135 | public: 136 | 137 | // deprecated 138 | fcgi_ostream(FCGX_Stream * fcgx = 0); 139 | 140 | // deprecated 141 | ~fcgi_ostream(void) {} 142 | 143 | // deprecated 144 | virtual void attach(FCGX_Stream *fcgx); 145 | 146 | private: 147 | 148 | fcgi_streambuf fcgi_strmbuf; 149 | }; 150 | 151 | #endif /* FCGIO_H */ 152 | -------------------------------------------------------------------------------- /plugins/fastcgi/src/fcgios.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fcgios.h -- 3 | * 4 | * Description of file. 5 | * 6 | * 7 | * Copyright (c) 1996 Open Market, Inc. 8 | * All rights reserved. 9 | * 10 | * This file contains proprietary and confidential information and 11 | * remains the unpublished property of Open Market, Inc. Use, 12 | * disclosure, or reproduction is prohibited except as permitted by 13 | * express written license agreement with Open Market, Inc. 14 | * 15 | * Bill Snapper 16 | * snapper@openmarket.com 17 | */ 18 | #ifndef _FCGIOS_H 19 | #define _FCGIOS_H 20 | 21 | #ifdef _WIN32 22 | #define WIN32_LEAN_AND_MEAN 23 | #include 24 | #include 25 | #endif 26 | 27 | #include "fcgi_config.h" 28 | 29 | #ifdef HAVE_SYS_TIME_H 30 | #include 31 | #endif 32 | 33 | #ifdef HAVE_SYS_TYPES_H 34 | #include 35 | #endif 36 | 37 | #if defined (c_plusplus) || defined (__cplusplus) 38 | extern "C" { 39 | #endif 40 | 41 | #ifdef _WIN32 42 | #define OS_Errno GetLastError() 43 | #define OS_SetErrno(err) SetLastError(err) 44 | #ifndef O_NONBLOCK 45 | #define O_NONBLOCK 0x0004 /* no delay */ 46 | #endif 47 | #else /* !_WIN32 */ 48 | #define OS_Errno errno 49 | #define OS_SetErrno(err) errno = (err) 50 | #endif /* !_WIN32 */ 51 | 52 | #ifndef DLLAPI 53 | #ifdef _WIN32 54 | #define DLLAPI __declspec(dllimport) 55 | #else 56 | #define DLLAPI 57 | #endif 58 | #endif 59 | 60 | 61 | /* This is the initializer for a "struct timeval" used in a select() call 62 | * right after a new request is accept()ed to determine readablity. Its 63 | * a drop-dead timer. Its only used for AF_UNIX sockets (not TCP sockets). 64 | * Its a workaround for a kernel bug in Linux 2.0.x and SCO Unixware. 65 | * Making this as small as possible, yet remain reliable would be best. 66 | * 2 seconds is very conservative. 0,0 is not reliable. The shorter the 67 | * timeout, the faster request processing will recover. The longer the 68 | * timeout, the more likely this application being "busy" will cause other 69 | * requests to abort and cause more dead sockets that need this timeout. */ 70 | #define READABLE_UNIX_FD_DROP_DEAD_TIMEVAL 2,0 71 | 72 | #ifndef STDIN_FILENO 73 | #define STDIN_FILENO 0 74 | #endif 75 | 76 | #ifndef STDOUT_FILENO 77 | #define STDOUT_FILENO 1 78 | #endif 79 | 80 | #ifndef STDERR_FILENO 81 | #define STDERR_FILENO 2 82 | #endif 83 | 84 | #ifndef MAXPATHLEN 85 | #define MAXPATHLEN 1024 86 | #endif 87 | 88 | #ifndef X_OK 89 | #define X_OK 0x01 90 | #endif 91 | 92 | #ifndef _CLIENTDATA 93 | # if defined(__STDC__) || defined(__cplusplus) 94 | typedef void *ClientData; 95 | # else 96 | typedef int *ClientData; 97 | # endif /* __STDC__ */ 98 | #define _CLIENTDATA 99 | #endif 100 | 101 | typedef void (*OS_AsyncProc) (ClientData clientData, int len); 102 | 103 | DLLAPI int OS_LibInit(int stdioFds[3]); 104 | DLLAPI void OS_LibShutdown(void); 105 | DLLAPI int OS_CreateLocalIpcFd(const char *bindPath, int backlog); 106 | DLLAPI int OS_FcgiConnect(char *bindPath); 107 | DLLAPI int OS_Read(int fd, char * buf, size_t len); 108 | DLLAPI int OS_Write(int fd, char * buf, size_t len); 109 | DLLAPI int OS_SpawnChild(char *execPath, int listenFd); 110 | DLLAPI int OS_AsyncReadStdin(void *buf, int len, OS_AsyncProc procPtr, 111 | ClientData clientData); 112 | DLLAPI int OS_AsyncRead(int fd, int offset, void *buf, int len, 113 | OS_AsyncProc procPtr, ClientData clientData); 114 | DLLAPI int OS_AsyncWrite(int fd, int offset, void *buf, int len, 115 | OS_AsyncProc procPtr, ClientData clientData); 116 | DLLAPI int OS_Close(int fd); 117 | DLLAPI int OS_CloseRead(int fd); 118 | DLLAPI int OS_DoIo(struct timeval *tmo); 119 | DLLAPI int OS_Accept(int listen_sock, int fail_on_intr, const char *webServerAddrs); 120 | DLLAPI int OS_IpcClose(int ipcFd); 121 | DLLAPI int OS_IsFcgi(int sock); 122 | DLLAPI void OS_SetFlags(int fd, int flags); 123 | 124 | DLLAPI void OS_ShutdownPending(void); 125 | 126 | #if defined (__cplusplus) || defined (c_plusplus) 127 | } /* terminate extern "C" { */ 128 | #endif 129 | 130 | #endif /* _FCGIOS_H */ 131 | -------------------------------------------------------------------------------- /plugins/mysql/libs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timmylindh/CHL/a573099e8b75b253acd9b41cc45739b5536caf4d/plugins/mysql/libs/.gitignore -------------------------------------------------------------------------------- /plugins/mysql/libscompile: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # GET OS BIT TYPE 4 | SYS_TYPE=$(uname -m) 5 | 6 | # WHETHER TO COMPILE OR NOT 7 | COMPILE=true 8 | 9 | # FILE NAMES 10 | DFILE="mysql.tar.gz" 11 | DIR_NAME="mysql" 12 | LIB_NAME="libmysqlclient.so" 13 | 14 | # MYSQL C CONNECTOR DOWNLOAD URLS 15 | MYSQL_64="https://dev.mysql.com/get/Downloads/Connector-C/mysql-connector-c-6.1.6-linux-glibc2.5-x86_64.tar.gz" 16 | MYSQL_32="https://dev.mysql.com/get/Downloads/Connector-C/mysql-connector-c-6.1.6-linux-glibc2.5-i686.tar.gz" 17 | 18 | echo "fetching MySQL C Connector..." 19 | # DOWNLOAD MYSQL C CONNECTOR 20 | if [ ${SYS_TYPE} == "x86_64" ]; then 21 | wget -q ${MYSQL_64} -O ${DFILE} 22 | elif [[ ${SYS_TYPE,,} == *"arm"* ]]; then 23 | echo "ARM - no MYSQL support" 24 | COMPILE=false 25 | else 26 | wget -q ${MYSQL_32} -O ${DFILE} 27 | fi 28 | 29 | if [ "${COMPILE}" = true ]; then 30 | echo "extracting files..." 31 | # EXTRACT FILES 32 | mkdir ${DIR_NAME} 33 | tar xf ${DFILE} -C ${DIR_NAME} --strip-components 1 34 | 35 | # MOVE LIBRARY 36 | mv $(readlink -f ${DIR_NAME}/lib/${LIB_NAME}) libs 37 | 38 | # COMPILE 39 | echo "Compiling..." 40 | gcc -std=c11 -c -Wall -Werror -fPIC src/*.c 41 | mv *.o ../../cmp 42 | 43 | echo "clean up..." 44 | # CLEAN UP 45 | rm -r ${DFILE} ${DIR_NAME} 46 | fi 47 | 48 | -------------------------------------------------------------------------------- /plugins/mysql/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | # Fetch MYSQL libraries and compile 3 | bash libscompile 4 | 5 | -------------------------------------------------------------------------------- /plugins/mysql/mysql.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the standard header file for CHL MySQL library 3 | * Contains all of the available functions and properties part of the CHL MySQL API 4 | * Built on top of standard MySQL C connector library 5 | */ 6 | #ifndef MYSQL_H_ 7 | #define MYSQL_H_ 8 | 9 | // Used for fetching MySQL data 10 | typedef char ** MYSQL_ROW; 11 | 12 | // Errors state definitions 13 | #define ERRORS_STATE_TRUE 1 14 | #define ERRORS_STATE_FALSE 0 15 | 16 | // chlmysql.c 17 | 18 | /* 19 | * Function for connection to MySQL server. 20 | * [host]: server host 21 | * [username]: mysql username 22 | * [password]: myqsl password 23 | * [database]: mysql database, leave NULL if none 24 | * 25 | * Return: 1 if successful, 0 on error 26 | */ 27 | char chl_mysql_connect(char * host, char * username, char * password, char * database); 28 | 29 | /* 30 | * Function for issuing a MySQL query. 31 | * [query]: the query 32 | * 33 | * Return: 1 if successful, 0 on error 34 | */ 35 | char chl_mysql_query(char * query); 36 | 37 | /* 38 | * Function for fetching the next row after issuing a fetch query 39 | * 40 | * Return: the row if successful, 0 if no rows left or on error 41 | */ 42 | MYSQL_ROW chl_mysql_next_row(); 43 | 44 | /* 45 | * Function for freeing MySQL result data, should be called in the end every time you fetch 46 | * something from the database 47 | */ 48 | void chl_mysql_free_result(); 49 | 50 | /* 51 | * Function for fetching the amount of rows in a MySQL result after a fetch query. 52 | * 53 | * Return: number of rows 54 | */ 55 | int chl_mysql_num_rows(); 56 | 57 | /* 58 | * Function for selecting MySQL database 59 | * [database]: database name 60 | */ 61 | void chl_mysql_db(char * database); 62 | 63 | /* 64 | * Function for closing the MySQL connection. Should be called when you are done 65 | * with the MySQL server. 66 | */ 67 | void chl_mysql_close(); 68 | 69 | /* 70 | * Function to toggle whether to turn on or off automatic MySQL error printing 71 | * [state]: ERRORS_STATE_TRUE | ERRORS_STATE_FALSE 72 | */ 73 | void chl_mysql_toggle_errors(char state); 74 | 75 | /* 76 | * Function to acquire MySQL error message 77 | * 78 | * Return: a string of the error message 79 | */ 80 | const char * chl_mysql_error(); 81 | 82 | #endif /* MYSQL_H_ */ 83 | -------------------------------------------------------------------------------- /plugins/mysql/src/HEADERS: -------------------------------------------------------------------------------- 1 | my_alloc.h mysql_com.h mysql_time.h typelib.h 2 | my_list.h mysql.h mysql_version.h 3 | 4 | -------------------------------------------------------------------------------- /plugins/mysql/src/chlmysql.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This source file's purpose is to provide an interface for the standard MySQL API 3 | */ 4 | 5 | #include 6 | #include "../../../core/src/error.h" 7 | #include "chlmysql.h" 8 | #include "mysql.h" 9 | 10 | static MYSQL * con; // MySQL connection struct 11 | static MYSQL_RES * sql_result = NULL; // MySQL result 12 | static MYSQL_ROW sql_row = NULL; 13 | static char errors_state = ERRORS_STATE_TRUE; // Whether to output errors or not 14 | 15 | // Connect to mysql server 16 | char chl_mysql_connect(char * host, char * username, char * password, char * database) { 17 | // Create MySQL struct 18 | if((con = mysql_init(NULL)) == NULL) { 19 | if(errors_state) 20 | _print_errors(); 21 | 22 | return 0; 23 | } 24 | 25 | // Connect to MySQL server 26 | if(mysql_real_connect(con, host, username, password, database, 0, NULL, 0) == NULL) { 27 | if(errors_state) 28 | _print_errors(); 29 | 30 | return 0; 31 | } 32 | 33 | return 1; 34 | } 35 | 36 | // Issue a MySQL query 37 | char chl_mysql_query(char * query) { 38 | if(mysql_query(con, query)) { 39 | if(errors_state) 40 | _print_errors(); 41 | 42 | return 0; 43 | } 44 | 45 | return 1; 46 | } 47 | 48 | // Check if there is a mysql row available, run in a loop by caller 49 | MYSQL_ROW chl_mysql_next_row() { 50 | // If no result has been acquired 51 | if(sql_result == NULL) { 52 | // Fetch result 53 | if((sql_result = mysql_store_result(con)) == NULL) { 54 | if(errors_state) 55 | _print_errors(); 56 | 57 | chl_mysql_free_result(); 58 | return 0; 59 | } 60 | } 61 | 62 | // Check if no rows left, fetch row if there are rows left 63 | if(! (sql_row = mysql_fetch_row(sql_result))) { 64 | chl_mysql_free_result(); // End reached, free result 65 | return 0; 66 | } 67 | 68 | return sql_row; 69 | } 70 | 71 | // Free and reset result 72 | void chl_mysql_free_result() { 73 | mysql_free_result(sql_result); 74 | sql_result = NULL; 75 | sql_row = NULL; 76 | } 77 | 78 | // Return number of rows in result 79 | int chl_mysql_num_rows() { 80 | // Fetch result if not already fetched 81 | if(sql_result == NULL) 82 | if((sql_result = mysql_store_result(con)) == NULL) { 83 | chl_mysql_free_result(); 84 | return 0; 85 | } 86 | 87 | return mysql_num_rows(sql_result); 88 | } 89 | 90 | // Select MySQL database 91 | void chl_mysql_db(char * database) { 92 | mysql_select_db(con, database); 93 | } 94 | 95 | // Disconnect from mysql server 96 | void chl_mysql_close() { 97 | mysql_close(con); 98 | } 99 | 100 | // Turn on or off automatic output of errors 101 | void chl_mysql_toggle_errors(char state) { 102 | errors_state = state; 103 | } 104 | 105 | // Return mysql error message 106 | const char * chl_mysql_error() { 107 | return mysql_error(con); 108 | } 109 | 110 | // Print errors wrapper function 111 | void _print_errors() { 112 | chl_error_append(CHL_E_MYSQL, "%s", mysql_error(con)); 113 | chl_print_errors(); 114 | } 115 | -------------------------------------------------------------------------------- /plugins/mysql/src/chlmysql.h: -------------------------------------------------------------------------------- 1 | #ifndef CHLMYSQL_H_ 2 | #define CHLMYSQL_H_ 3 | 4 | // Whether to compile as FastCGI 5 | #ifdef _F_CHL_ 6 | #include "../../../core/src/fcgi_stdio.h" 7 | #endif 8 | 9 | typedef char ** MYSQL_ROW; 10 | 11 | // Errors state definitions 12 | #define ERRORS_STATE_TRUE 1 13 | #define ERRORS_STATE_FALSE 0 14 | 15 | char chl_mysql_connect(char *, char *, char *, char *); 16 | MYSQL_ROW chl_mysql_next_row(); 17 | void chl_mysql_free_result(); 18 | char chl_mysql_query(char *); 19 | void chl_mysql_close(); 20 | int chl_mysql_num_rows(); 21 | void chl_mysql_db(char *); 22 | void chl_mysql_toggle_errors(char); 23 | const char * chl_mysql_error(); 24 | void _print_errors(); 25 | 26 | #endif /* CHLMYSQL_H_ */ 27 | -------------------------------------------------------------------------------- /plugins/mysql/src/my_alloc.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 of the License. 6 | 7 | This program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 15 | 16 | /* 17 | Data structures for mysys/my_alloc.c (root memory allocator) 18 | */ 19 | 20 | #ifndef _my_alloc_h 21 | #define _my_alloc_h 22 | 23 | #define ALLOC_MAX_BLOCK_TO_DROP 4096 24 | #define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10 25 | 26 | /* PSI_memory_key */ 27 | typedef unsigned int PSI_memory_key; 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | typedef struct st_used_mem 34 | { /* struct for once_alloc (block) */ 35 | struct st_used_mem *next; /* Next block in use */ 36 | unsigned int left; /* memory left in block */ 37 | unsigned int size; /* size of block */ 38 | } USED_MEM; 39 | 40 | 41 | typedef struct st_mem_root 42 | { 43 | USED_MEM *free; /* blocks with free memory in it */ 44 | USED_MEM *used; /* blocks almost without free memory */ 45 | USED_MEM *pre_alloc; /* preallocated block */ 46 | /* if block have less memory it will be put in 'used' list */ 47 | size_t min_malloc; 48 | size_t block_size; /* initial block size */ 49 | unsigned int block_num; /* allocated blocks counter */ 50 | /* 51 | first free block in queue test counter (if it exceed 52 | MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list) 53 | */ 54 | unsigned int first_block_usage; 55 | 56 | void (*error_handler)(void); 57 | 58 | PSI_memory_key m_psi_key; 59 | } MEM_ROOT; 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /plugins/mysql/src/my_list.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 of the License. 6 | 7 | This program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 15 | 16 | #ifndef _list_h_ 17 | #define _list_h_ 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | typedef struct st_list { 24 | struct st_list *prev,*next; 25 | void *data; 26 | } LIST; 27 | 28 | typedef int (*list_walk_action)(void *,void *); 29 | 30 | extern LIST *list_add(LIST *root,LIST *element); 31 | extern LIST *list_delete(LIST *root,LIST *element); 32 | extern LIST *list_cons(void *data,LIST *root); 33 | extern LIST *list_reverse(LIST *root); 34 | extern void list_free(LIST *root,unsigned int free_data); 35 | extern unsigned int list_length(LIST *); 36 | extern int list_walk(LIST *,list_walk_action action,unsigned char * argument); 37 | 38 | #define list_rest(a) ((a)->next) 39 | #define list_push(a,b) (a)=list_cons((b),(a)) 40 | #define list_pop(A) {LIST *old=(A); (A)=list_delete(old,old); my_free(old); } 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | #endif 46 | -------------------------------------------------------------------------------- /plugins/mysql/src/mysql_com.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 of the License. 6 | 7 | This program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 15 | 16 | /* 17 | ** Common definition between mysql server & client 18 | */ 19 | 20 | #ifndef _mysql_com_h 21 | #define _mysql_com_h 22 | 23 | #define HOSTNAME_LENGTH 60 24 | #define SYSTEM_CHARSET_MBMAXLEN 3 25 | #define NAME_CHAR_LEN 64 /* Field/table name length */ 26 | #define USERNAME_CHAR_LENGTH 16 27 | #define NAME_LEN (NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN) 28 | #define USERNAME_LENGTH (USERNAME_CHAR_LENGTH*SYSTEM_CHARSET_MBMAXLEN) 29 | 30 | #define MYSQL_AUTODETECT_CHARSET_NAME "auto" 31 | 32 | #define SERVER_VERSION_LENGTH 60 33 | #define SQLSTATE_LENGTH 5 34 | 35 | /* 36 | Maximum length of comments 37 | */ 38 | #define TABLE_COMMENT_INLINE_MAXLEN 180 /* pre 6.0: 60 characters */ 39 | #define TABLE_COMMENT_MAXLEN 2048 40 | #define COLUMN_COMMENT_MAXLEN 1024 41 | #define INDEX_COMMENT_MAXLEN 1024 42 | #define TABLE_PARTITION_COMMENT_MAXLEN 1024 43 | 44 | /* 45 | Maximum length of protocol packet. 46 | OK packet length limit also restricted to this value as any length greater 47 | than this value will have first byte of OK packet to be 254 thus does not 48 | provide a means to identify if this is OK or EOF packet. 49 | */ 50 | #define MAX_PACKET_LENGTH (256L*256L*256L-1) 51 | 52 | /* 53 | USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain 54 | username and hostname parts of the user identifier with trailing zero in 55 | MySQL standard format: 56 | user_name_part@host_name_part\0 57 | */ 58 | #define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2 59 | 60 | #define LOCAL_HOST "localhost" 61 | #define LOCAL_HOST_NAMEDPIPE "." 62 | 63 | 64 | #if defined(_WIN32) 65 | #define MYSQL_NAMEDPIPE "MySQL" 66 | #define MYSQL_SERVICENAME "MySQL" 67 | #endif /* _WIN32 */ 68 | 69 | /* 70 | You should add new commands to the end of this list, otherwise old 71 | servers won't be able to handle them as 'unsupported'. 72 | */ 73 | 74 | enum enum_server_command 75 | { 76 | COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST, 77 | COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS, 78 | COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING, 79 | COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP, 80 | COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE, 81 | COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, 82 | COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON, 83 | COM_BINLOG_DUMP_GTID, COM_RESET_CONNECTION, 84 | /* don't forget to update const char *command_name[] in sql_parse.cc */ 85 | 86 | /* Must be last */ 87 | COM_END 88 | }; 89 | 90 | 91 | /* 92 | Length of random string sent by server on handshake; this is also length of 93 | obfuscated password, recieved from client 94 | */ 95 | #define SCRAMBLE_LENGTH 20 96 | #define AUTH_PLUGIN_DATA_PART_1_LENGTH 8 97 | /* length of password stored in the db: new passwords are preceeded with '*' */ 98 | #define SCRAMBLED_PASSWORD_CHAR_LENGTH (SCRAMBLE_LENGTH*2+1) 99 | 100 | 101 | #define NOT_NULL_FLAG 1 /* Field can't be NULL */ 102 | #define PRI_KEY_FLAG 2 /* Field is part of a primary key */ 103 | #define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */ 104 | #define MULTIPLE_KEY_FLAG 8 /* Field is part of a key */ 105 | #define BLOB_FLAG 16 /* Field is a blob */ 106 | #define UNSIGNED_FLAG 32 /* Field is unsigned */ 107 | #define ZEROFILL_FLAG 64 /* Field is zerofill */ 108 | #define BINARY_FLAG 128 /* Field is binary */ 109 | 110 | /* The following are only sent to new clients */ 111 | #define ENUM_FLAG 256 /* field is an enum */ 112 | #define AUTO_INCREMENT_FLAG 512 /* field is a autoincrement field */ 113 | #define TIMESTAMP_FLAG 1024 /* Field is a timestamp */ 114 | #define SET_FLAG 2048 /* field is a set */ 115 | #define NO_DEFAULT_VALUE_FLAG 4096 /* Field doesn't have default value */ 116 | #define ON_UPDATE_NOW_FLAG 8192 /* Field is set to NOW on UPDATE */ 117 | #define NUM_FLAG 32768 /* Field is num (for clients) */ 118 | #define PART_KEY_FLAG 16384 /* Intern; Part of some key */ 119 | #define GROUP_FLAG 32768 /* Intern: Group field */ 120 | #define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */ 121 | #define BINCMP_FLAG 131072 /* Intern: Used by sql_yacc */ 122 | #define GET_FIXED_FIELDS_FLAG (1 << 18) /* Used to get fields in item tree */ 123 | #define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */ 124 | /** 125 | Intern: Field in TABLE object for new version of altered table, 126 | which participates in a newly added index. 127 | */ 128 | #define FIELD_IN_ADD_INDEX (1 << 20) 129 | #define FIELD_IS_RENAMED (1<< 21) /* Intern: Field is being renamed */ 130 | #define FIELD_FLAGS_STORAGE_MEDIA 22 /* Field storage media, bit 22-23 */ 131 | #define FIELD_FLAGS_STORAGE_MEDIA_MASK (3 << FIELD_FLAGS_STORAGE_MEDIA) 132 | #define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25 */ 133 | #define FIELD_FLAGS_COLUMN_FORMAT_MASK (3 << FIELD_FLAGS_COLUMN_FORMAT) 134 | #define FIELD_IS_DROPPED (1<< 26) /* Intern: Field is being dropped */ 135 | #define EXPLICIT_NULL_FLAG (1<< 27) /* Field is explicitly specified as 136 | NULL by the user */ 137 | 138 | #define REFRESH_GRANT 1 /* Refresh grant tables */ 139 | #define REFRESH_LOG 2 /* Start on new log file */ 140 | #define REFRESH_TABLES 4 /* close all tables */ 141 | #define REFRESH_HOSTS 8 /* Flush host cache */ 142 | #define REFRESH_STATUS 16 /* Flush status variables */ 143 | #define REFRESH_THREADS 32 /* Flush thread cache */ 144 | #define REFRESH_SLAVE 64 /* Reset master info and restart slave 145 | thread */ 146 | #define REFRESH_MASTER 128 /* Remove all bin logs in the index 147 | and truncate the index */ 148 | #define REFRESH_ERROR_LOG 256 /* Rotate only the erorr log */ 149 | #define REFRESH_ENGINE_LOG 512 /* Flush all storage engine logs */ 150 | #define REFRESH_BINARY_LOG 1024 /* Flush the binary log */ 151 | #define REFRESH_RELAY_LOG 2048 /* Flush the relay log */ 152 | #define REFRESH_GENERAL_LOG 4096 /* Flush the general log */ 153 | #define REFRESH_SLOW_LOG 8192 /* Flush the slow query log */ 154 | 155 | /* The following can't be set with mysql_refresh() */ 156 | #define REFRESH_READ_LOCK 16384 /* Lock tables for read */ 157 | #define REFRESH_FAST 32768 /* Intern flag */ 158 | 159 | /* RESET (remove all queries) from query cache */ 160 | #define REFRESH_QUERY_CACHE 65536 161 | #define REFRESH_QUERY_CACHE_FREE 0x20000L /* pack query cache */ 162 | #define REFRESH_DES_KEY_FILE 0x40000L 163 | #define REFRESH_USER_RESOURCES 0x80000L 164 | #define REFRESH_FOR_EXPORT 0x100000L /* FLUSH TABLES ... FOR EXPORT */ 165 | #define REFRESH_OPTIMIZER_COSTS 0x200000L /* FLUSH OPTIMIZER_COSTS */ 166 | 167 | #define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ 168 | #define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ 169 | #define CLIENT_LONG_FLAG 4 /* Get all column flags */ 170 | #define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */ 171 | #define CLIENT_NO_SCHEMA 16 /* Don't allow database.table.column */ 172 | #define CLIENT_COMPRESS 32 /* Can use compression protocol */ 173 | #define CLIENT_ODBC 64 /* Odbc client */ 174 | #define CLIENT_LOCAL_FILES 128 /* Can use LOAD DATA LOCAL */ 175 | #define CLIENT_IGNORE_SPACE 256 /* Ignore spaces before '(' */ 176 | #define CLIENT_PROTOCOL_41 512 /* New 4.1 protocol */ 177 | #define CLIENT_INTERACTIVE 1024 /* This is an interactive client */ 178 | #define CLIENT_SSL 2048 /* Switch to SSL after handshake */ 179 | #define CLIENT_IGNORE_SIGPIPE 4096 /* IGNORE sigpipes */ 180 | #define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */ 181 | #define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */ 182 | #define CLIENT_RESERVED2 32768 /* Old flag for 4.1 authentication */ 183 | #define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ 184 | #define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ 185 | #define CLIENT_PS_MULTI_RESULTS (1UL << 18) /* Multi-results in PS-protocol */ 186 | 187 | #define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */ 188 | #define CLIENT_CONNECT_ATTRS (1UL << 20) /* Client supports connection attributes */ 189 | 190 | /* Enable authentication response packet to be larger than 255 bytes. */ 191 | #define CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA (1UL << 21) 192 | 193 | /* Don't close the connection for a connection with expired password. */ 194 | #define CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS (1UL << 22) 195 | 196 | /** 197 | Capable of handling server state change information. Its a hint to the 198 | server to include the state change information in Ok packet. 199 | */ 200 | #define CLIENT_SESSION_TRACK (1UL << 23) 201 | /* Client no longer needs EOF packet */ 202 | #define CLIENT_DEPRECATE_EOF (1UL << 24) 203 | 204 | #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) 205 | #define CLIENT_REMEMBER_OPTIONS (1UL << 31) 206 | 207 | #ifdef HAVE_COMPRESS 208 | #define CAN_CLIENT_COMPRESS CLIENT_COMPRESS 209 | #else 210 | #define CAN_CLIENT_COMPRESS 0 211 | #endif 212 | 213 | /* Gather all possible capabilites (flags) supported by the server */ 214 | #define CLIENT_ALL_FLAGS (CLIENT_LONG_PASSWORD \ 215 | | CLIENT_FOUND_ROWS \ 216 | | CLIENT_LONG_FLAG \ 217 | | CLIENT_CONNECT_WITH_DB \ 218 | | CLIENT_NO_SCHEMA \ 219 | | CLIENT_COMPRESS \ 220 | | CLIENT_ODBC \ 221 | | CLIENT_LOCAL_FILES \ 222 | | CLIENT_IGNORE_SPACE \ 223 | | CLIENT_PROTOCOL_41 \ 224 | | CLIENT_INTERACTIVE \ 225 | | CLIENT_SSL \ 226 | | CLIENT_IGNORE_SIGPIPE \ 227 | | CLIENT_TRANSACTIONS \ 228 | | CLIENT_RESERVED \ 229 | | CLIENT_RESERVED2 \ 230 | | CLIENT_MULTI_STATEMENTS \ 231 | | CLIENT_MULTI_RESULTS \ 232 | | CLIENT_PS_MULTI_RESULTS \ 233 | | CLIENT_SSL_VERIFY_SERVER_CERT \ 234 | | CLIENT_REMEMBER_OPTIONS \ 235 | | CLIENT_PLUGIN_AUTH \ 236 | | CLIENT_CONNECT_ATTRS \ 237 | | CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA \ 238 | | CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS \ 239 | | CLIENT_SESSION_TRACK \ 240 | | CLIENT_DEPRECATE_EOF \ 241 | ) 242 | 243 | /* 244 | Switch off the flags that are optional and depending on build flags 245 | If any of the optional flags is supported by the build it will be switched 246 | on before sending to the client during the connection handshake. 247 | */ 248 | #define CLIENT_BASIC_FLAGS (((CLIENT_ALL_FLAGS & ~CLIENT_SSL) \ 249 | & ~CLIENT_COMPRESS) \ 250 | & ~CLIENT_SSL_VERIFY_SERVER_CERT) 251 | 252 | /** 253 | Is raised when a multi-statement transaction 254 | has been started, either explicitly, by means 255 | of BEGIN or COMMIT AND CHAIN, or 256 | implicitly, by the first transactional 257 | statement, when autocommit=off. 258 | */ 259 | #define SERVER_STATUS_IN_TRANS 1 260 | #define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */ 261 | #define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ 262 | #define SERVER_QUERY_NO_GOOD_INDEX_USED 16 263 | #define SERVER_QUERY_NO_INDEX_USED 32 264 | /** 265 | The server was able to fulfill the clients request and opened a 266 | read-only non-scrollable cursor for a query. This flag comes 267 | in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands. 268 | */ 269 | #define SERVER_STATUS_CURSOR_EXISTS 64 270 | /** 271 | This flag is sent when a read-only cursor is exhausted, in reply to 272 | COM_STMT_FETCH command. 273 | */ 274 | #define SERVER_STATUS_LAST_ROW_SENT 128 275 | #define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */ 276 | #define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512 277 | /** 278 | Sent to the client if after a prepared statement reprepare 279 | we discovered that the new statement returns a different 280 | number of result set columns. 281 | */ 282 | #define SERVER_STATUS_METADATA_CHANGED 1024 283 | #define SERVER_QUERY_WAS_SLOW 2048 284 | 285 | /** 286 | To mark ResultSet containing output parameter values. 287 | */ 288 | #define SERVER_PS_OUT_PARAMS 4096 289 | 290 | /** 291 | Set at the same time as SERVER_STATUS_IN_TRANS if the started 292 | multi-statement transaction is a read-only transaction. Cleared 293 | when the transaction commits or aborts. Since this flag is sent 294 | to clients in OK and EOF packets, the flag indicates the 295 | transaction status at the end of command execution. 296 | */ 297 | #define SERVER_STATUS_IN_TRANS_READONLY 8192 298 | 299 | /** 300 | This status flag, when on, implies that one of the state information has 301 | changed on the server because of the execution of the last statement. 302 | */ 303 | #define SERVER_SESSION_STATE_CHANGED (1UL << 14) 304 | 305 | /** 306 | Server status flags that must be cleared when starting 307 | execution of a new SQL statement. 308 | Flags from this set are only added to the 309 | current server status by the execution engine, but 310 | never removed -- the execution engine expects them 311 | to disappear automagically by the next command. 312 | */ 313 | #define SERVER_STATUS_CLEAR_SET (SERVER_QUERY_NO_GOOD_INDEX_USED| \ 314 | SERVER_QUERY_NO_INDEX_USED|\ 315 | SERVER_MORE_RESULTS_EXISTS|\ 316 | SERVER_STATUS_METADATA_CHANGED |\ 317 | SERVER_QUERY_WAS_SLOW |\ 318 | SERVER_STATUS_DB_DROPPED |\ 319 | SERVER_STATUS_CURSOR_EXISTS|\ 320 | SERVER_STATUS_LAST_ROW_SENT|\ 321 | SERVER_SESSION_STATE_CHANGED) 322 | 323 | #define MYSQL_ERRMSG_SIZE 512 324 | #define NET_READ_TIMEOUT 30 /* Timeout on read */ 325 | #define NET_WRITE_TIMEOUT 60 /* Timeout on write */ 326 | #define NET_WAIT_TIMEOUT 8*60*60 /* Wait for new query */ 327 | 328 | #define ONLY_KILL_QUERY 1 329 | 330 | 331 | struct st_vio; /* Only C */ 332 | typedef struct st_vio Vio; 333 | 334 | #define MAX_TINYINT_WIDTH 3 /* Max width for a TINY w.o. sign */ 335 | #define MAX_SMALLINT_WIDTH 5 /* Max width for a SHORT w.o. sign */ 336 | #define MAX_MEDIUMINT_WIDTH 8 /* Max width for a INT24 w.o. sign */ 337 | #define MAX_INT_WIDTH 10 /* Max width for a LONG w.o. sign */ 338 | #define MAX_BIGINT_WIDTH 20 /* Max width for a LONGLONG */ 339 | #define MAX_CHAR_WIDTH 255 /* Max length for a CHAR colum */ 340 | #define MAX_BLOB_WIDTH 16777216 /* Default width for blob */ 341 | 342 | typedef struct st_net { 343 | Vio *vio; 344 | unsigned char *buff,*buff_end,*write_pos,*read_pos; 345 | my_socket fd; /* For Perl DBI/dbd */ 346 | /* 347 | The following variable is set if we are doing several queries in one 348 | command ( as in LOAD TABLE ... FROM MASTER ), 349 | and do not want to confuse the client with OK at the wrong time 350 | */ 351 | unsigned long remain_in_buf,length, buf_length, where_b; 352 | unsigned long max_packet,max_packet_size; 353 | unsigned int pkt_nr,compress_pkt_nr; 354 | unsigned int write_timeout, read_timeout, retry_count; 355 | int fcntl; 356 | unsigned int *return_status; 357 | unsigned char reading_or_writing; 358 | char save_char; 359 | my_bool unused1; /* Please remove with the next incompatible ABI change */ 360 | my_bool unused2; /* Please remove with the next incompatible ABI change */ 361 | my_bool compress; 362 | my_bool unused3; /* Please remove with the next incompatible ABI change. */ 363 | /* 364 | Pointer to query object in query cache, do not equal NULL (0) for 365 | queries in cache that have not stored its results yet 366 | */ 367 | /* 368 | Unused, please remove with the next incompatible ABI change. 369 | */ 370 | unsigned char *unused; 371 | unsigned int last_errno; 372 | unsigned char error; 373 | my_bool unused4; /* Please remove with the next incompatible ABI change. */ 374 | my_bool unused5; /* Please remove with the next incompatible ABI change. */ 375 | /** Client library error message buffer. Actually belongs to struct MYSQL. */ 376 | char last_error[MYSQL_ERRMSG_SIZE]; 377 | /** Client library sqlstate buffer. Set along with the error message. */ 378 | char sqlstate[SQLSTATE_LENGTH+1]; 379 | /** 380 | Extension pointer, for the caller private use. 381 | Any program linking with the networking library can use this pointer, 382 | which is handy when private connection specific data needs to be 383 | maintained. 384 | The mysqld server process uses this pointer internally, 385 | to maintain the server internal instrumentation for the connection. 386 | */ 387 | void *extension; 388 | } NET; 389 | 390 | 391 | #define packet_error (~(unsigned long) 0) 392 | 393 | enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY, 394 | MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG, 395 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE, 396 | MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, 397 | MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24, 398 | MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, 399 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR, 400 | MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR, 401 | MYSQL_TYPE_BIT, 402 | MYSQL_TYPE_TIMESTAMP2, 403 | MYSQL_TYPE_DATETIME2, 404 | MYSQL_TYPE_TIME2, 405 | MYSQL_TYPE_NEWDECIMAL=246, 406 | MYSQL_TYPE_ENUM=247, 407 | MYSQL_TYPE_SET=248, 408 | MYSQL_TYPE_TINY_BLOB=249, 409 | MYSQL_TYPE_MEDIUM_BLOB=250, 410 | MYSQL_TYPE_LONG_BLOB=251, 411 | MYSQL_TYPE_BLOB=252, 412 | MYSQL_TYPE_VAR_STRING=253, 413 | MYSQL_TYPE_STRING=254, 414 | MYSQL_TYPE_GEOMETRY=255 415 | 416 | }; 417 | 418 | /* For backward compatibility */ 419 | #define CLIENT_MULTI_QUERIES CLIENT_MULTI_STATEMENTS 420 | #define FIELD_TYPE_DECIMAL MYSQL_TYPE_DECIMAL 421 | #define FIELD_TYPE_NEWDECIMAL MYSQL_TYPE_NEWDECIMAL 422 | #define FIELD_TYPE_TINY MYSQL_TYPE_TINY 423 | #define FIELD_TYPE_SHORT MYSQL_TYPE_SHORT 424 | #define FIELD_TYPE_LONG MYSQL_TYPE_LONG 425 | #define FIELD_TYPE_FLOAT MYSQL_TYPE_FLOAT 426 | #define FIELD_TYPE_DOUBLE MYSQL_TYPE_DOUBLE 427 | #define FIELD_TYPE_NULL MYSQL_TYPE_NULL 428 | #define FIELD_TYPE_TIMESTAMP MYSQL_TYPE_TIMESTAMP 429 | #define FIELD_TYPE_LONGLONG MYSQL_TYPE_LONGLONG 430 | #define FIELD_TYPE_INT24 MYSQL_TYPE_INT24 431 | #define FIELD_TYPE_DATE MYSQL_TYPE_DATE 432 | #define FIELD_TYPE_TIME MYSQL_TYPE_TIME 433 | #define FIELD_TYPE_DATETIME MYSQL_TYPE_DATETIME 434 | #define FIELD_TYPE_YEAR MYSQL_TYPE_YEAR 435 | #define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE 436 | #define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM 437 | #define FIELD_TYPE_SET MYSQL_TYPE_SET 438 | #define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB 439 | #define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB 440 | #define FIELD_TYPE_LONG_BLOB MYSQL_TYPE_LONG_BLOB 441 | #define FIELD_TYPE_BLOB MYSQL_TYPE_BLOB 442 | #define FIELD_TYPE_VAR_STRING MYSQL_TYPE_VAR_STRING 443 | #define FIELD_TYPE_STRING MYSQL_TYPE_STRING 444 | #define FIELD_TYPE_CHAR MYSQL_TYPE_TINY 445 | #define FIELD_TYPE_INTERVAL MYSQL_TYPE_ENUM 446 | #define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY 447 | #define FIELD_TYPE_BIT MYSQL_TYPE_BIT 448 | 449 | 450 | /* Shutdown/kill enums and constants */ 451 | 452 | /* Bits for THD::killable. */ 453 | #define MYSQL_SHUTDOWN_KILLABLE_CONNECT (unsigned char)(1 << 0) 454 | #define MYSQL_SHUTDOWN_KILLABLE_TRANS (unsigned char)(1 << 1) 455 | #define MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE (unsigned char)(1 << 2) 456 | #define MYSQL_SHUTDOWN_KILLABLE_UPDATE (unsigned char)(1 << 3) 457 | 458 | enum mysql_enum_shutdown_level { 459 | /* 460 | We want levels to be in growing order of hardness (because we use number 461 | comparisons). Note that DEFAULT does not respect the growing property, but 462 | it's ok. 463 | */ 464 | SHUTDOWN_DEFAULT = 0, 465 | /* wait for existing connections to finish */ 466 | SHUTDOWN_WAIT_CONNECTIONS= MYSQL_SHUTDOWN_KILLABLE_CONNECT, 467 | /* wait for existing trans to finish */ 468 | SHUTDOWN_WAIT_TRANSACTIONS= MYSQL_SHUTDOWN_KILLABLE_TRANS, 469 | /* wait for existing updates to finish (=> no partial MyISAM update) */ 470 | SHUTDOWN_WAIT_UPDATES= MYSQL_SHUTDOWN_KILLABLE_UPDATE, 471 | /* flush InnoDB buffers and other storage engines' buffers*/ 472 | SHUTDOWN_WAIT_ALL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1), 473 | /* don't flush InnoDB buffers, flush other storage engines' buffers*/ 474 | SHUTDOWN_WAIT_CRITICAL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1) + 1, 475 | /* Now the 2 levels of the KILL command */ 476 | #if MYSQL_VERSION_ID >= 50000 477 | KILL_QUERY= 254, 478 | #endif 479 | KILL_CONNECTION= 255 480 | }; 481 | 482 | 483 | enum enum_cursor_type 484 | { 485 | CURSOR_TYPE_NO_CURSOR= 0, 486 | CURSOR_TYPE_READ_ONLY= 1, 487 | CURSOR_TYPE_FOR_UPDATE= 2, 488 | CURSOR_TYPE_SCROLLABLE= 4 489 | }; 490 | 491 | 492 | /* options for mysql_set_option */ 493 | enum enum_mysql_set_option 494 | { 495 | MYSQL_OPTION_MULTI_STATEMENTS_ON, 496 | MYSQL_OPTION_MULTI_STATEMENTS_OFF 497 | }; 498 | 499 | /* 500 | Type of state change information that the server can include in the Ok 501 | packet. 502 | Note : 1) session_state_type shouldn't go past 255 (i.e. 1-byte boundary). 503 | 2) Modify the definition of SESSION_TRACK_END when a new member is 504 | added. 505 | */ 506 | enum enum_session_state_type 507 | { 508 | SESSION_TRACK_SYSTEM_VARIABLES, /* Session system variables */ 509 | SESSION_TRACK_SCHEMA, /* Current schema */ 510 | SESSION_TRACK_STATE_CHANGE /* track session state changes */ 511 | }; 512 | 513 | #define SESSION_TRACK_BEGIN SESSION_TRACK_SYSTEM_VARIABLES 514 | 515 | #define SESSION_TRACK_END SESSION_TRACK_STATE_CHANGE 516 | 517 | #define IS_SESSION_STATE_TYPE(T) \ 518 | (((int)(T) >= SESSION_TRACK_BEGIN) && ((T) <= SESSION_TRACK_END)) 519 | 520 | #define net_new_transaction(net) ((net)->pkt_nr=0) 521 | 522 | #ifdef __cplusplus 523 | extern "C" { 524 | #endif 525 | 526 | my_bool my_net_init(NET *net, Vio* vio); 527 | void my_net_local_init(NET *net); 528 | void net_end(NET *net); 529 | void net_clear(NET *net, my_bool check_buffer); 530 | my_bool net_realloc(NET *net, size_t length); 531 | my_bool net_flush(NET *net); 532 | my_bool my_net_write(NET *net,const unsigned char *packet, size_t len); 533 | my_bool net_write_command(NET *net,unsigned char command, 534 | const unsigned char *header, size_t head_len, 535 | const unsigned char *packet, size_t len); 536 | my_bool net_write_packet(NET *net, const unsigned char *packet, size_t length); 537 | unsigned long my_net_read(NET *net); 538 | 539 | #ifdef MY_GLOBAL_INCLUDED 540 | void my_net_set_write_timeout(NET *net, uint timeout); 541 | void my_net_set_read_timeout(NET *net, uint timeout); 542 | #endif 543 | 544 | struct rand_struct { 545 | unsigned long seed1,seed2,max_value; 546 | double max_value_dbl; 547 | }; 548 | 549 | #ifdef __cplusplus 550 | } 551 | #endif 552 | 553 | /* The following is for user defined functions */ 554 | 555 | enum Item_result {STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, 556 | DECIMAL_RESULT}; 557 | 558 | typedef struct st_udf_args 559 | { 560 | unsigned int arg_count; /* Number of arguments */ 561 | enum Item_result *arg_type; /* Pointer to item_results */ 562 | char **args; /* Pointer to argument */ 563 | unsigned long *lengths; /* Length of string arguments */ 564 | char *maybe_null; /* Set to 1 for all maybe_null args */ 565 | char **attributes; /* Pointer to attribute name */ 566 | unsigned long *attribute_lengths; /* Length of attribute arguments */ 567 | void *extension; 568 | } UDF_ARGS; 569 | 570 | /* This holds information about the result */ 571 | 572 | typedef struct st_udf_init 573 | { 574 | my_bool maybe_null; /* 1 if function can return NULL */ 575 | unsigned int decimals; /* for real functions */ 576 | unsigned long max_length; /* For string functions */ 577 | char *ptr; /* free pointer for function data */ 578 | my_bool const_item; /* 1 if function always returns the same value */ 579 | void *extension; 580 | } UDF_INIT; 581 | /* 582 | TODO: add a notion for determinism of the UDF. 583 | See Item_udf_func::update_used_tables () 584 | */ 585 | 586 | /* Constants when using compression */ 587 | #define NET_HEADER_SIZE 4 /* standard header size */ 588 | #define COMP_HEADER_SIZE 3 /* compression header extra size */ 589 | 590 | /* Prototypes to password functions */ 591 | 592 | #ifdef __cplusplus 593 | extern "C" { 594 | #endif 595 | 596 | /* 597 | These functions are used for authentication by client and server and 598 | implemented in sql/password.c 599 | */ 600 | 601 | void randominit(struct rand_struct *, unsigned long seed1, 602 | unsigned long seed2); 603 | double my_rnd(struct rand_struct *); 604 | void create_random_string(char *to, unsigned int length, struct rand_struct *rand_st); 605 | 606 | void hash_password(unsigned long *to, const char *password, unsigned int password_len); 607 | void make_scrambled_password_323(char *to, const char *password); 608 | void scramble_323(char *to, const char *message, const char *password); 609 | my_bool check_scramble_323(const unsigned char *reply, const char *message, 610 | unsigned long *salt); 611 | void get_salt_from_password_323(unsigned long *res, const char *password); 612 | void make_password_from_salt_323(char *to, const unsigned long *salt); 613 | 614 | void make_scrambled_password(char *to, const char *password); 615 | void scramble(char *to, const char *message, const char *password); 616 | my_bool check_scramble(const unsigned char *reply, const char *message, 617 | const unsigned char *hash_stage2); 618 | void get_salt_from_password(unsigned char *res, const char *password); 619 | void make_password_from_salt(char *to, const unsigned char *hash_stage2); 620 | char *octet2hex(char *to, const char *str, unsigned int len); 621 | 622 | /* end of password.c */ 623 | 624 | char *get_tty_password(const char *opt_message); 625 | const char *mysql_errno_to_sqlstate(unsigned int mysql_errno); 626 | 627 | /* Some other useful functions */ 628 | 629 | my_bool my_thread_init(void); 630 | void my_thread_end(void); 631 | 632 | #ifdef MY_GLOBAL_INCLUDED 633 | ulong STDCALL net_field_length(uchar **packet); 634 | my_ulonglong net_field_length_ll(uchar **packet); 635 | uchar *net_store_length(uchar *pkg, ulonglong length); 636 | unsigned int net_length_size(ulonglong num); 637 | #endif 638 | 639 | #ifdef __cplusplus 640 | } 641 | #endif 642 | 643 | #define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */ 644 | #define MYSQL_STMT_HEADER 4 645 | #define MYSQL_LONG_DATA_HEADER 6 646 | 647 | #define NOT_FIXED_DEC 31 648 | #endif 649 | -------------------------------------------------------------------------------- /plugins/mysql/src/mysql_time.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 of the License. 6 | 7 | This program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ 15 | 16 | #ifndef _mysql_time_h_ 17 | #define _mysql_time_h_ 18 | 19 | /* 20 | Time declarations shared between the server and client API: 21 | you should not add anything to this header unless it's used 22 | (and hence should be visible) in mysql.h. 23 | If you're looking for a place to add new time-related declaration, 24 | it's most likely my_time.h. See also "C API Handling of Date 25 | and Time Values" chapter in documentation. 26 | */ 27 | 28 | enum enum_mysql_timestamp_type 29 | { 30 | MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1, 31 | MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2 32 | }; 33 | 34 | 35 | /* 36 | Structure which is used to represent datetime values inside MySQL. 37 | 38 | We assume that values in this structure are normalized, i.e. year <= 9999, 39 | month <= 12, day <= 31, hour <= 23, hour <= 59, hour <= 59. Many functions 40 | in server such as my_system_gmt_sec() or make_time() family of functions 41 | rely on this (actually now usage of make_*() family relies on a bit weaker 42 | restriction). Also functions that produce MYSQL_TIME as result ensure this. 43 | There is one exception to this rule though if this structure holds time 44 | value (time_type == MYSQL_TIMESTAMP_TIME) days and hour member can hold 45 | bigger values. 46 | */ 47 | typedef struct st_mysql_time 48 | { 49 | unsigned int year, month, day, hour, minute, second; 50 | unsigned long second_part; /**< microseconds */ 51 | my_bool neg; 52 | enum enum_mysql_timestamp_type time_type; 53 | } MYSQL_TIME; 54 | 55 | #endif /* _mysql_time_h_ */ 56 | -------------------------------------------------------------------------------- /plugins/mysql/src/mysql_version.h: -------------------------------------------------------------------------------- 1 | /* Copyright Abandoned 1996,1999 TCX DataKonsult AB & Monty Program KB 2 | & Detron HB, 1996, 1999-2004, 2007 MySQL AB. 3 | This file is public domain and comes with NO WARRANTY of any kind 4 | */ 5 | 6 | /* Version numbers for protocol & mysqld */ 7 | 8 | #ifndef _mysql_version_h 9 | #define _mysql_version_h 10 | #ifdef _CUSTOMCONFIG_ 11 | #include 12 | #else 13 | #define PROTOCOL_VERSION 10 14 | #define MYSQL_SERVER_VERSION "5.7.6-m16" 15 | #define MYSQL_VERSION_ID 50706 16 | #define MYSQL_PORT 3306 17 | #define MYSQL_PORT_DEFAULT 0 18 | #define MYSQL_UNIX_ADDR "/tmp/mysql.sock" 19 | #define MYSQL_CONFIG_NAME "my" 20 | #define MYSQL_COMPILATION_COMMENT "MySQL Connector/C (GPL)" 21 | #define LIBMYSQL_VERSION "6.1.6" 22 | #define LIBMYSQL_VERSION_ID 60106 23 | 24 | /* mysqld compile time options */ 25 | #endif /* _CUSTOMCONFIG_ */ 26 | 27 | #ifndef LICENSE 28 | #define LICENSE GPL 29 | #endif /* LICENSE */ 30 | 31 | #endif /* _mysql_version_h */ 32 | -------------------------------------------------------------------------------- /plugins/mysql/src/typelib.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 of the License. 6 | 7 | This program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ 15 | 16 | 17 | #ifndef _typelib_h 18 | #define _typelib_h 19 | 20 | #include "my_alloc.h" 21 | 22 | typedef struct st_typelib { /* Different types saved here */ 23 | unsigned int count; /* How many types */ 24 | const char *name; /* Name of typelib */ 25 | const char **type_names; 26 | unsigned int *type_lengths; 27 | } TYPELIB; 28 | 29 | extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position); 30 | extern int find_type_or_exit(const char *x, TYPELIB *typelib, 31 | const char *option); 32 | #define FIND_TYPE_BASIC 0 33 | /** makes @c find_type() require the whole name, no prefix */ 34 | #define FIND_TYPE_NO_PREFIX (1 << 0) 35 | /** always implicitely on, so unused, but old code may pass it */ 36 | #define FIND_TYPE_NO_OVERWRITE (1 << 1) 37 | /** makes @c find_type() accept a number */ 38 | #define FIND_TYPE_ALLOW_NUMBER (1 << 2) 39 | /** makes @c find_type() treat ',' as terminator */ 40 | #define FIND_TYPE_COMMA_TERM (1 << 3) 41 | 42 | extern int find_type(const char *x, const TYPELIB *typelib, unsigned int flags); 43 | extern void make_type(char *to,unsigned int nr,TYPELIB *typelib); 44 | extern const char *get_type(TYPELIB *typelib,unsigned int nr); 45 | extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from); 46 | 47 | extern TYPELIB sql_protocol_typelib; 48 | 49 | my_ulonglong find_set_from_flags(const TYPELIB *lib, unsigned int default_name, 50 | my_ulonglong cur_set, my_ulonglong default_set, 51 | const char *str, unsigned int length, 52 | char **err_pos, unsigned int *err_len); 53 | 54 | #endif /* _typelib_h */ 55 | --------------------------------------------------------------------------------