And now let's attach the updated patch too.

L.

Lenar Lõhmus wrote:

> Hi,
> 
> Next time I'll post patches in the morning after good sleep.
> Updated version attached. The original I sent is not useful.
> 
> Lenar
> 
>> Hi,
>> 
>> I'v implemented new_link paramater (as in mysql_connect) for
>> mysql_pconnect().
Common subdirectories: old/libmysql and new/libmysql
diff -ub old/php_mysql.c new/php_mysql.c
--- old/php_mysql.c	2003-08-08 16:36:44.000000000 +0300
+++ new/php_mysql.c	2003-09-14 22:00:09.000000000 +0300
@@ -90,6 +90,10 @@
 #define MYSQL_HAS_YEAR
 #endif
 
+#if MYSQL_VERSION_ID >= 32303
+#define MYSQL_HAS_CHANGE_USER
+#endif
+
 #define MYSQL_ASSOC		1<<0
 #define MYSQL_NUM		1<<1
 #define MYSQL_BOTH		(MYSQL_ASSOC|MYSQL_NUM)
@@ -420,6 +424,10 @@
  */
 PHP_RINIT_FUNCTION(mysql)
 {
+#ifdef MYSQL_HAS_CHANGE_USER
+	ALLOC_HASHTABLE(MySG(inuse_list));
+	zend_hash_init(MySG(inuse_list), 1, NULL, NULL, 0);
+#endif
 	MySG(default_link)=-1;
 	MySG(num_links) = MySG(num_persistent);
 	/* Reset connect error/errno on every request */
@@ -442,10 +450,13 @@
 			php_error_docref("function.mysql-free-result" TSRMLS_CC, E_WARNING, tmp);
 		}
 	}
-
 	if (MySG(connect_error)!=NULL) {
 		efree(MySG(connect_error));
 	}
+#ifdef MYSQL_HAS_CHANGE_USER
+	zend_hash_destroy(MySG(inuse_list));
+	FREE_HASHTABLE(MySG(inuse_list));
+#endif
 	return SUCCESS;
 }
 /* }}} */
@@ -501,6 +512,7 @@
 	zval **z_host=NULL, **z_user=NULL, **z_passwd=NULL, **z_new_link=NULL, **z_client_flags=NULL;
 	zend_bool free_host=0, new_link=0;
 	long connect_timeout;
+	list_entry *inuse_le=NULL;
 
 
 	connect_timeout = MySG(connect_timeout);
@@ -513,9 +525,6 @@
 		}
 		host_and_port=passwd=NULL;
 		user=php_get_current_user();
-		hashed_details_length = strlen(user)+5+3;
-		hashed_details = (char *) emalloc(hashed_details_length+1);
-		sprintf(hashed_details, "mysql__%s_", user);
 		client_flags = CLIENT_INTERACTIVE;
 	} else {
 		host_and_port = MySG(default_host);
@@ -575,9 +584,16 @@
 				}
 				break;
 			case 5: {
+					if (persistent) {
+						if (zend_get_parameters_ex(5, &z_host, &z_user, &z_passwd, &z_client_flags, &z_new_link) == FAILURE) {
+							MYSQL_DO_CONNECT_RETURN_FALSE();
+						}
+					}
+					else {
 					if (zend_get_parameters_ex(5, &z_host, &z_user, &z_passwd, &z_new_link, &z_client_flags) == FAILURE) {
 						MYSQL_DO_CONNECT_RETURN_FALSE();
 					}
+					}
 					convert_to_string_ex(z_user);
 					convert_to_string_ex(z_passwd);
 					convert_to_boolean_ex(z_new_link);
@@ -610,11 +626,36 @@
 				}
 			}
 		}
+	}
 
+	if (!MySG(allow_persistent)) {
+		persistent=0;
+	}
+
+#ifdef MYSQL_HAS_CHANGE_USER
+	if (!(new_link && persistent)) {
+#endif
+		if (PG(sql_safe_mode)) {
+			hashed_details_length = strlen(user)+5+3;
+			hashed_details = (char *) emalloc(hashed_details_length+1);
+			sprintf(hashed_details, "mysql__%s_", user);
+		} else {
 		hashed_details_length = sizeof("mysql___")-1 + strlen(SAFE_STRING(host_and_port))+strlen(SAFE_STRING(user))+strlen(SAFE_STRING(passwd));
 		hashed_details = (char *) emalloc(hashed_details_length+1);
 		sprintf(hashed_details, "mysql_%s_%s_%s", SAFE_STRING(host_and_port), SAFE_STRING(user), SAFE_STRING(passwd));
 	}
+#ifdef MYSQL_HAS_CHANGE_USER
+	} else {
+		long count = 0;
+
+		if (zend_hash_find(MySG(inuse_list), SAFE_STRING(host_and_port), strlen(SAFE_STRING(host_and_port))+1, (void **) &inuse_le)==SUCCESS) {
+			count = (long) inuse_le->ptr;
+		}
+		hashed_details_length = sizeof("mysqlp__")-1 + strlen(SAFE_STRING(host_and_port)) + 10;
+		hashed_details = (char *) emalloc(hashed_details_length+1);
+		sprintf(hashed_details, "mysqlp_%s_%ld", SAFE_STRING(host_and_port), count);
+	}
+#endif
 
 	/* We cannot use mysql_port anymore in windows, need to use
 	 * mysql_real_connect() to set the port.
@@ -641,9 +682,6 @@
 	mysql_port = port;
 #endif
 
-	if (!MySG(allow_persistent)) {
-		persistent=0;
-	}
 	if (persistent) {
 		list_entry *le;
 
@@ -698,6 +736,7 @@
 			MySG(num_links)++;
 		} else {  /* The link is in our list of persistent connections */
 			if (Z_TYPE_P(le) != le_plink) {
+				efree(hashed_details);
 				MYSQL_DO_CONNECT_RETURN_FALSE();
 			}
 			/* ensure that the link did not die */
@@ -724,12 +763,43 @@
 					MYSQL_DO_CONNECT_RETURN_FALSE();
 				}
 			}
+#ifdef MYSQL_HAS_CHANGE_USER
+			else if (new_link) {
+				if (mysql_change_user(le->ptr, user, passwd, NULL)) { /* access denied probably */
+					if (MySG(connect_error)!=NULL) efree(MySG(connect_error));
+					MySG(connect_error)=estrdup(mysql_error(&((php_mysql_conn *)le->ptr)->conn));
+					php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
+					MySG(connect_errno)=mysql_errno(&((php_mysql_conn *)le->ptr)->conn);
+					efree(hashed_details);
+					MYSQL_DO_CONNECT_RETURN_FALSE();
+				}
+			}
+#endif
+
 #if MYSQL_VERSION_ID < 32231
 			signal(SIGPIPE, handler);
 #endif
 
 			mysql = (php_mysql_conn *) le->ptr;
 		}
+
+#ifdef MYSQL_HAS_CHANGE_USER
+		if (new_link) {
+			if (inuse_le) { /* increase in use count for this host_and_port */
+				((long)inuse_le->ptr)++;
+			} else {
+				list_entry new_inuse_le;
+
+				((long) new_inuse_le.ptr) = 1; /* in use count */
+				if (zend_hash_update(MySG(inuse_list), SAFE_STRING(host_and_port), strlen(SAFE_STRING(host_and_port))+1, (void *) &new_inuse_le, sizeof(list_entry), NULL)==FAILURE) {
+					free(mysql);
+					efree(hashed_details);
+					MYSQL_DO_CONNECT_RETURN_FALSE();
+				}
+			}
+		}
+#endif
+
 		ZEND_REGISTER_RESOURCE(return_value, mysql, le_plink);
 	} else { /* non persistent */
 		list_entry *index_ptr, new_index_ptr;
@@ -1278,7 +1348,7 @@
 		RETURN_FALSE;
 	}
 #endif
-	if(use_store == MYSQL_USE_RESULT) {
+	if (use_store == MYSQL_USE_RESULT) {
 		mysql_result=mysql_use_result(&mysql->conn);
 	} else {
 		mysql_result=mysql_store_result(&mysql->conn);
diff -ub old/php_mysql.h new/php_mysql.h
--- old/php_mysql.h	2002-12-31 18:35:00.000000000 +0200
+++ new/php_mysql.h	2003-09-14 19:11:49.000000000 +0300
@@ -105,6 +105,7 @@
 	long connect_timeout;
 	long result_allocated;
 	long trace_mode;
+	HashTable *inuse_list;
 ZEND_END_MODULE_GLOBALS(mysql)
 
 #ifdef ZTS

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to