1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Wez Furlong <wez@php.net> |
16 | Frank M. Kromann <frank@kromann.info> |
17 +----------------------------------------------------------------------+
18 */
19
20 /* $Id$ */
21
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #include "php.h"
27 #include "php_ini.h"
28 #include "ext/standard/info.h"
29 #include "pdo/php_pdo.h"
30 #include "pdo/php_pdo_driver.h"
31 #include "php_pdo_dblib.h"
32 #include "php_pdo_dblib_int.h"
33 #include "zend_exceptions.h"
34
35 ZEND_DECLARE_MODULE_GLOBALS(dblib)
36 static PHP_GINIT_FUNCTION(dblib);
37
38 const zend_function_entry pdo_dblib_functions[] = {
39 PHP_FE_END
40 };
41
42 static const zend_module_dep pdo_dblib_deps[] = {
43 ZEND_MOD_REQUIRED("pdo")
44 ZEND_MOD_END
45 };
46
47 #if PDO_DBLIB_IS_MSSQL
48 zend_module_entry pdo_mssql_module_entry = {
49 #else
50 zend_module_entry pdo_dblib_module_entry = {
51 #endif
52 STANDARD_MODULE_HEADER_EX, NULL,
53 pdo_dblib_deps,
54 #if PDO_DBLIB_IS_MSSQL
55 "pdo_mssql",
56 #elif defined(PHP_WIN32)
57 "pdo_sybase",
58 #else
59 "pdo_dblib",
60 #endif
61 pdo_dblib_functions,
62 PHP_MINIT(pdo_dblib),
63 PHP_MSHUTDOWN(pdo_dblib),
64 NULL,
65 PHP_RSHUTDOWN(pdo_dblib),
66 PHP_MINFO(pdo_dblib),
67 PHP_PDO_DBLIB_VERSION,
68 PHP_MODULE_GLOBALS(dblib),
69 PHP_GINIT(dblib),
70 NULL,
71 NULL,
72 STANDARD_MODULE_PROPERTIES_EX
73 };
74
75 #if defined(COMPILE_DL_PDO_DBLIB) || defined(COMPILE_DL_PDO_MSSQL)
76 #if PDO_DBLIB_IS_MSSQL
ZEND_GET_MODULE(pdo_mssql)77 ZEND_GET_MODULE(pdo_mssql)
78 #else
79 ZEND_GET_MODULE(pdo_dblib)
80 #endif
81 #endif
82
83 int pdo_dblib_error_handler(DBPROCESS *dbproc, int severity, int dberr,
84 int oserr, char *dberrstr, char *oserrstr)
85 {
86 pdo_dblib_err *einfo;
87 char *state = "HY000";
88
89 if(dbproc) {
90 einfo = (pdo_dblib_err*)dbgetuserdata(dbproc);
91 if (!einfo) einfo = &DBLIB_G(err);
92 } else {
93 einfo = &DBLIB_G(err);
94 }
95
96 einfo->severity = severity;
97 einfo->oserr = oserr;
98 einfo->dberr = dberr;
99
100 if (einfo->oserrstr) {
101 efree(einfo->oserrstr);
102 }
103 if (einfo->dberrstr) {
104 efree(einfo->dberrstr);
105 }
106 if (oserrstr) {
107 einfo->oserrstr = estrdup(oserrstr);
108 } else {
109 einfo->oserrstr = NULL;
110 }
111 if (dberrstr) {
112 einfo->dberrstr = estrdup(dberrstr);
113 } else {
114 einfo->dberrstr = NULL;
115 }
116
117 switch (dberr) {
118 case SYBESEOF:
119 case SYBEFCON: state = "01002"; break;
120 case SYBEMEM: state = "HY001"; break;
121 case SYBEPWD: state = "28000"; break;
122 }
123 strcpy(einfo->sqlstate, state);
124
125 return INT_CANCEL;
126 }
127
pdo_dblib_msg_handler(DBPROCESS * dbproc,DBINT msgno,int msgstate,int severity,char * msgtext,char * srvname,char * procname,DBUSMALLINT line)128 int pdo_dblib_msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate,
129 int severity, char *msgtext, char *srvname, char *procname, DBUSMALLINT line)
130 {
131 pdo_dblib_err *einfo;
132
133 if (severity) {
134 einfo = (pdo_dblib_err*)dbgetuserdata(dbproc);
135 if (!einfo) {
136 einfo = &DBLIB_G(err);
137 }
138
139 if (einfo->lastmsg) {
140 efree(einfo->lastmsg);
141 }
142
143 einfo->lastmsg = estrdup(msgtext);
144 }
145
146 return 0;
147 }
148
pdo_dblib_err_dtor(pdo_dblib_err * err)149 void pdo_dblib_err_dtor(pdo_dblib_err *err)
150 {
151 if (!err) {
152 return;
153 }
154
155 if (err->dberrstr) {
156 efree(err->dberrstr);
157 err->dberrstr = NULL;
158 }
159 if (err->lastmsg) {
160 efree(err->lastmsg);
161 err->lastmsg = NULL;
162 }
163 if (err->oserrstr) {
164 efree(err->oserrstr);
165 err->oserrstr = NULL;
166 }
167 }
168
PHP_GINIT_FUNCTION(dblib)169 static PHP_GINIT_FUNCTION(dblib)
170 {
171 memset(dblib_globals, 0, sizeof(*dblib_globals));
172 dblib_globals->err.sqlstate = dblib_globals->sqlstate;
173 }
174
PHP_RSHUTDOWN_FUNCTION(pdo_dblib)175 PHP_RSHUTDOWN_FUNCTION(pdo_dblib)
176 {
177 if (DBLIB_G(err).oserrstr) {
178 efree(DBLIB_G(err).oserrstr);
179 DBLIB_G(err).oserrstr = NULL;
180 }
181 if (DBLIB_G(err).dberrstr) {
182 efree(DBLIB_G(err).dberrstr);
183 DBLIB_G(err).dberrstr = NULL;
184 }
185 if (DBLIB_G(err).lastmsg) {
186 efree(DBLIB_G(err).lastmsg);
187 DBLIB_G(err).lastmsg = NULL;
188 }
189 return SUCCESS;
190 }
191
PHP_MINIT_FUNCTION(pdo_dblib)192 PHP_MINIT_FUNCTION(pdo_dblib)
193 {
194 REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_CONNECTION_TIMEOUT", (long) PDO_DBLIB_ATTR_CONNECTION_TIMEOUT);
195 REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_QUERY_TIMEOUT", (long) PDO_DBLIB_ATTR_QUERY_TIMEOUT);
196 REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER", (long) PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER);
197
198 if (FAIL == dbinit()) {
199 return FAILURE;
200 }
201
202 if (FAILURE == php_pdo_register_driver(&pdo_dblib_driver)) {
203 return FAILURE;
204 }
205
206 #if !PHP_DBLIB_IS_MSSQL
207 dberrhandle((EHANDLEFUNC) pdo_dblib_error_handler);
208 dbmsghandle((MHANDLEFUNC) pdo_dblib_msg_handler);
209 #endif
210
211 return SUCCESS;
212 }
213
PHP_MSHUTDOWN_FUNCTION(pdo_dblib)214 PHP_MSHUTDOWN_FUNCTION(pdo_dblib)
215 {
216 php_pdo_unregister_driver(&pdo_dblib_driver);
217 dbexit();
218 return SUCCESS;
219 }
220
PHP_MINFO_FUNCTION(pdo_dblib)221 PHP_MINFO_FUNCTION(pdo_dblib)
222 {
223 php_info_print_table_start();
224 php_info_print_table_header(2, "PDO Driver for "
225 #if PDO_DBLIB_IS_MSSQL
226 "MSSQL"
227 #elif defined(PHP_WIN32)
228 "FreeTDS/Sybase/MSSQL"
229 #else
230 "FreeTDS/Sybase"
231 #endif
232 " DB-lib", "enabled");
233 php_info_print_table_row(2, "Flavour", PDO_DBLIB_FLAVOUR);
234 php_info_print_table_end();
235 }
236