xref: /PHP-5.5/ext/interbase/ibase_blobs.c (revision 73c1be26)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2015 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    | Authors: Ard Biesheuvel <a.k.biesheuvel@its.tudelft.nl>              |
16    +----------------------------------------------------------------------+
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #include "php.h"
24 
25 #if HAVE_IBASE
26 
27 #include "php_interbase.h"
28 #include "php_ibase_includes.h"
29 
30 #define BLOB_CLOSE		1
31 #define BLOB_CANCEL		2
32 
33 static int le_blob;
34 
_php_ibase_free_blob(zend_rsrc_list_entry * rsrc TSRMLS_DC)35 static void _php_ibase_free_blob(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
36 {
37 	ibase_blob *ib_blob = (ibase_blob *)rsrc->ptr;
38 
39 	if (ib_blob->bl_handle != NULL) { /* blob open*/
40 		if (isc_cancel_blob(IB_STATUS, &ib_blob->bl_handle)) {
41 			_php_ibase_module_error("You can lose data. Close any blob after reading from or "
42 				"writing to it. Use ibase_blob_close() before calling ibase_close()" TSRMLS_CC);
43 		}
44 	}
45 	efree(ib_blob);
46 }
47 /* }}} */
48 
php_ibase_blobs_minit(INIT_FUNC_ARGS)49 void php_ibase_blobs_minit(INIT_FUNC_ARGS) /* {{{ */
50 {
51 	le_blob = zend_register_list_destructors_ex(_php_ibase_free_blob, NULL,
52 	    "interbase blob", module_number);
53 }
54 /* }}} */
55 
_php_ibase_string_to_quad(char const * id,ISC_QUAD * qd)56 int _php_ibase_string_to_quad(char const *id, ISC_QUAD *qd) /* {{{ */
57 {
58 	/* shortcut for most common case */
59 	if (sizeof(ISC_QUAD) == sizeof(ISC_UINT64)) {
60 		return sscanf(id, BLOB_ID_MASK, (ISC_UINT64 *) qd);
61 	} else {
62 		ISC_UINT64 res;
63 		if (sscanf(id, BLOB_ID_MASK, &res)) {
64 			qd->gds_quad_high = (ISC_LONG) (res >> 0x20);
65 			qd->gds_quad_low = (ISC_LONG) (res & 0xFFFFFFFF);
66 			return 1;
67 		}
68 		return 0;
69 	}
70 }
71 /* }}} */
72 
_php_ibase_quad_to_string(ISC_QUAD const qd)73 char *_php_ibase_quad_to_string(ISC_QUAD const qd) /* {{{ */
74 {
75 	char *result;
76 
77 	/* shortcut for most common case */
78 	if (sizeof(ISC_QUAD) == sizeof(ISC_UINT64)) {
79 		spprintf(&result, BLOB_ID_LEN+1, "0x%0*" LL_MASK "x", 16, *(ISC_UINT64*)(void *) &qd);
80 	} else {
81 		ISC_UINT64 res = ((ISC_UINT64) qd.gds_quad_high << 0x20) | qd.gds_quad_low;
82 		spprintf(&result, BLOB_ID_LEN+1, "0x%0*" LL_MASK "x", 16, res);
83 	}
84 	return result;
85 }
86 /* }}} */
87 
88 typedef struct { /* {{{ */
89 	ISC_LONG  max_segment;		/* Length of longest segment */
90 	ISC_LONG  num_segments;		/* Total number of segments */
91 	ISC_LONG  total_length;		/* Total length of blob */
92 	int		  bl_stream;		/* blob is stream ? */
93 /* }}} */
94 } IBASE_BLOBINFO;
95 
_php_ibase_blob_get(zval * return_value,ibase_blob * ib_blob,unsigned long max_len TSRMLS_DC)96 int _php_ibase_blob_get(zval *return_value, ibase_blob *ib_blob, unsigned long max_len TSRMLS_DC) /* {{{ */
97 {
98 	if (ib_blob->bl_qd.gds_quad_high || ib_blob->bl_qd.gds_quad_low) { /*not null ?*/
99 
100 		ISC_STATUS stat;
101 		char *bl_data;
102 		unsigned long cur_len;
103 		unsigned short seg_len;
104 
105 		bl_data = safe_emalloc(1, max_len, 1);
106 
107 		for (cur_len = stat = 0; (stat == 0 || stat == isc_segment) && cur_len < max_len; cur_len += seg_len) {
108 
109 			unsigned short chunk_size = (max_len-cur_len) > USHRT_MAX ? USHRT_MAX
110 				: (unsigned short)(max_len-cur_len);
111 
112 			stat = isc_get_segment(IB_STATUS, &ib_blob->bl_handle, &seg_len, chunk_size, &bl_data[cur_len]);
113 		}
114 
115 		bl_data[cur_len] = '\0';
116 		if (IB_STATUS[0] == 1 && (stat != 0 && stat != isc_segstr_eof && stat != isc_segment)) {
117 			efree(bl_data);
118 			_php_ibase_error(TSRMLS_C);
119 			return FAILURE;
120 		}
121 		RETVAL_STRINGL(bl_data, cur_len, 0);
122 	} else { /* null blob */
123 		RETVAL_STRING("", 1); /* empty string */
124 	}
125 	return SUCCESS;
126 }
127 /* }}} */
128 
_php_ibase_blob_add(zval ** string_arg,ibase_blob * ib_blob TSRMLS_DC)129 int _php_ibase_blob_add(zval **string_arg, ibase_blob *ib_blob TSRMLS_DC) /* {{{ */
130 {
131 	unsigned long put_cnt = 0, rem_cnt;
132 	unsigned short chunk_size;
133 
134 	convert_to_string_ex(string_arg);
135 
136 	for (rem_cnt = Z_STRLEN_PP(string_arg); rem_cnt > 0; rem_cnt -= chunk_size)  {
137 
138 		chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt;
139 
140 		if (isc_put_segment(IB_STATUS, &ib_blob->bl_handle, chunk_size, &Z_STRVAL_PP(string_arg)[put_cnt] )) {
141 			_php_ibase_error(TSRMLS_C);
142 			return FAILURE;
143 		}
144 		put_cnt += chunk_size;
145 	}
146 	return SUCCESS;
147 }
148 /* }}} */
149 
_php_ibase_blob_info(isc_blob_handle bl_handle,IBASE_BLOBINFO * bl_info TSRMLS_DC)150 static int _php_ibase_blob_info(isc_blob_handle bl_handle, IBASE_BLOBINFO *bl_info TSRMLS_DC) /* {{{ */
151 {
152 	static char bl_items[] = {
153 		isc_info_blob_num_segments,
154 		isc_info_blob_max_segment,
155 		isc_info_blob_total_length,
156 		isc_info_blob_type
157 	};
158 
159 	char bl_inf[sizeof(long)*8], *p;
160 
161 	bl_info->max_segment = 0;
162 	bl_info->num_segments = 0;
163 	bl_info->total_length = 0;
164 	bl_info->bl_stream = 0;
165 
166 	if (isc_blob_info(IB_STATUS, &bl_handle, sizeof(bl_items), bl_items, sizeof(bl_inf), bl_inf)) {
167 		_php_ibase_error(TSRMLS_C);
168 		return FAILURE;
169 	}
170 
171 	for (p = bl_inf; *p != isc_info_end && p < bl_inf + sizeof(bl_inf);) {
172 		unsigned short item_len;
173 		int item = *p++;
174 
175 		item_len = (short) isc_vax_integer(p, 2);
176 		p += 2;
177 		switch (item) {
178 			case isc_info_blob_num_segments:
179 				bl_info->num_segments = isc_vax_integer(p, item_len);
180 				break;
181 			case isc_info_blob_max_segment:
182 				bl_info->max_segment = isc_vax_integer(p, item_len);
183 				break;
184 			case isc_info_blob_total_length:
185 				bl_info->total_length = isc_vax_integer(p, item_len);
186 				break;
187 			case isc_info_blob_type:
188 				bl_info->bl_stream = isc_vax_integer(p, item_len);
189 				break;
190 			case isc_info_end:
191 				break;
192 			case isc_info_truncated:
193 			case isc_info_error:  /* hmm. don't think so...*/
194 				_php_ibase_module_error("PHP module internal error" TSRMLS_CC);
195 				return FAILURE;
196 		} /* switch */
197 		p += item_len;
198 	} /* for */
199 	return SUCCESS;
200 }
201 /* }}} */
202 
203 /* {{{ proto resource ibase_blob_create([resource link_identifier])
204    Create blob for adding data */
PHP_FUNCTION(ibase_blob_create)205 PHP_FUNCTION(ibase_blob_create)
206 {
207 	zval *link = NULL;
208 	ibase_db_link *ib_link;
209 	ibase_trans *trans = NULL;
210 	ibase_blob *ib_blob;
211 
212 	RESET_ERRMSG;
213 
214 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &link)) {
215 		RETURN_FALSE;
216 	}
217 
218 	PHP_IBASE_LINK_TRANS(link, ib_link, trans);
219 
220 	ib_blob = (ibase_blob *) emalloc(sizeof(ibase_blob));
221 	ib_blob->bl_handle = NULL;
222 	ib_blob->type = BLOB_INPUT;
223 
224 	if (isc_create_blob(IB_STATUS, &ib_link->handle, &trans->handle, &ib_blob->bl_handle, &ib_blob->bl_qd)) {
225 		_php_ibase_error(TSRMLS_C);
226 		efree(ib_blob);
227 		RETURN_FALSE;
228 	}
229 
230 	ZEND_REGISTER_RESOURCE(return_value, ib_blob, le_blob);
231 }
232 /* }}} */
233 
234 /* {{{ proto resource ibase_blob_open([ resource link_identifier, ] string blob_id)
235    Open blob for retrieving data parts */
PHP_FUNCTION(ibase_blob_open)236 PHP_FUNCTION(ibase_blob_open)
237 {
238 	char *blob_id;
239 	int blob_id_len;
240 	zval *link = NULL;
241 	ibase_db_link *ib_link;
242 	ibase_trans *trans = NULL;
243 	ibase_blob *ib_blob;
244 
245 	RESET_ERRMSG;
246 
247 	switch (ZEND_NUM_ARGS()) {
248 		default:
249 			WRONG_PARAM_COUNT;
250 		case 1:
251 			if (FAILURE == zend_parse_parameters(1 TSRMLS_CC, "s", &blob_id, &blob_id_len)) {
252 				RETURN_FALSE;
253 			}
254 			break;
255 		case 2:
256 			if (FAILURE == zend_parse_parameters(2 TSRMLS_CC, "rs", &link, &blob_id, &blob_id_len)) {
257 				RETURN_FALSE;
258 			}
259 			break;
260 	}
261 
262 	PHP_IBASE_LINK_TRANS(link, ib_link, trans);
263 
264 	ib_blob = (ibase_blob *) emalloc(sizeof(ibase_blob));
265 	ib_blob->bl_handle = NULL;
266 	ib_blob->type = BLOB_OUTPUT;
267 
268 	do {
269 		if (! _php_ibase_string_to_quad(blob_id, &ib_blob->bl_qd)) {
270 			_php_ibase_module_error("String is not a BLOB ID" TSRMLS_CC);
271 			break;
272 		}
273 
274 		if (isc_open_blob(IB_STATUS, &ib_link->handle, &trans->handle, &ib_blob->bl_handle,
275 				&ib_blob->bl_qd)) {
276 			_php_ibase_error(TSRMLS_C);
277 			break;
278 		}
279 
280 		ZEND_REGISTER_RESOURCE(return_value, ib_blob, le_blob);
281 		return;
282 
283 	} while (0);
284 
285 	efree(ib_blob);
286 	RETURN_FALSE;
287 }
288 /* }}} */
289 
290 /* {{{ proto bool ibase_blob_add(resource blob_handle, string data)
291    Add data into created blob */
PHP_FUNCTION(ibase_blob_add)292 PHP_FUNCTION(ibase_blob_add)
293 {
294 	zval **blob_arg, **string_arg;
295 	ibase_blob *ib_blob;
296 
297 	RESET_ERRMSG;
298 
299 	if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &blob_arg, &string_arg) == FAILURE) {
300 		WRONG_PARAM_COUNT;
301 	}
302 
303 	ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob);
304 
305 	if (ib_blob->type != BLOB_INPUT) {
306 		_php_ibase_module_error("BLOB is not open for input" TSRMLS_CC);
307 		RETURN_FALSE;
308 	}
309 
310 	if (_php_ibase_blob_add(string_arg, ib_blob TSRMLS_CC) != SUCCESS) {
311 		RETURN_FALSE;
312 	}
313 }
314 /* }}} */
315 
316 /* {{{ proto string ibase_blob_get(resource blob_handle, int len)
317    Get len bytes data from open blob */
PHP_FUNCTION(ibase_blob_get)318 PHP_FUNCTION(ibase_blob_get)
319 {
320 	zval **blob_arg, **len_arg;
321 	ibase_blob *ib_blob;
322 
323 	RESET_ERRMSG;
324 
325 	if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &blob_arg, &len_arg) == FAILURE) {
326 		WRONG_PARAM_COUNT;
327 	}
328 
329 	ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob);
330 
331 	if (ib_blob->type != BLOB_OUTPUT) {
332 		_php_ibase_module_error("BLOB is not open for output" TSRMLS_CC);
333 		RETURN_FALSE;
334 	}
335 
336 	convert_to_long_ex(len_arg);
337 
338 	if (_php_ibase_blob_get(return_value, ib_blob, Z_LVAL_PP(len_arg) TSRMLS_CC) != SUCCESS) {
339 		RETURN_FALSE;
340 	}
341 }
342 /* }}} */
343 
_php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS,int bl_end)344 static void _php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS, int bl_end) /* {{{ */
345 {
346 	zval **blob_arg;
347 	ibase_blob *ib_blob;
348 
349 	RESET_ERRMSG;
350 
351 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &blob_arg) == FAILURE) {
352 		WRONG_PARAM_COUNT;
353 	}
354 
355 	ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob);
356 
357 	if (bl_end == BLOB_CLOSE) { /* return id here */
358 
359 		if (ib_blob->bl_qd.gds_quad_high || ib_blob->bl_qd.gds_quad_low) { /*not null ?*/
360 			if (isc_close_blob(IB_STATUS, &ib_blob->bl_handle)) {
361 				_php_ibase_error(TSRMLS_C);
362 				RETURN_FALSE;
363 			}
364 		}
365 		ib_blob->bl_handle = NULL;
366 
367 		RETVAL_STRINGL(_php_ibase_quad_to_string(ib_blob->bl_qd), BLOB_ID_LEN, 0);
368 	} else { /* discard created blob */
369 		if (isc_cancel_blob(IB_STATUS, &ib_blob->bl_handle)) {
370 			_php_ibase_error(TSRMLS_C);
371 			RETURN_FALSE;
372 		}
373 		ib_blob->bl_handle = NULL;
374 		RETVAL_TRUE;
375 	}
376 	zend_list_delete(Z_LVAL_PP(blob_arg));
377 }
378 /* }}} */
379 
380 /* {{{ proto string ibase_blob_close(resource blob_handle)
381    Close blob */
PHP_FUNCTION(ibase_blob_close)382 PHP_FUNCTION(ibase_blob_close)
383 {
384 	_php_ibase_blob_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, BLOB_CLOSE);
385 }
386 /* }}} */
387 
388 /* {{{ proto bool ibase_blob_cancel(resource blob_handle)
389    Cancel creating blob */
PHP_FUNCTION(ibase_blob_cancel)390 PHP_FUNCTION(ibase_blob_cancel)
391 {
392 	_php_ibase_blob_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, BLOB_CANCEL);
393 }
394 /* }}} */
395 
396 /* {{{ proto array ibase_blob_info([ resource link_identifier, ] string blob_id)
397    Return blob length and other useful info */
PHP_FUNCTION(ibase_blob_info)398 PHP_FUNCTION(ibase_blob_info)
399 {
400 	char *blob_id;
401 	int blob_id_len;
402 	zval *link = NULL;
403 	ibase_db_link *ib_link;
404 	ibase_trans *trans = NULL;
405 	ibase_blob ib_blob = { NULL, BLOB_INPUT };
406 	IBASE_BLOBINFO bl_info;
407 
408 	RESET_ERRMSG;
409 
410 	switch (ZEND_NUM_ARGS()) {
411 		default:
412 			WRONG_PARAM_COUNT;
413 		case 1:
414 			if (FAILURE == zend_parse_parameters(1 TSRMLS_CC, "s", &blob_id, &blob_id_len)) {
415 				RETURN_FALSE;
416 			}
417 			break;
418 		case 2:
419 			if (FAILURE == zend_parse_parameters(2 TSRMLS_CC, "rs", &link, &blob_id, &blob_id_len)) {
420 				RETURN_FALSE;
421 			}
422 			break;
423 	}
424 
425 	PHP_IBASE_LINK_TRANS(link, ib_link, trans);
426 
427 	if (! _php_ibase_string_to_quad(blob_id, &ib_blob.bl_qd)) {
428 		_php_ibase_module_error("Unrecognized BLOB ID" TSRMLS_CC);
429 		RETURN_FALSE;
430 	}
431 
432 	if (ib_blob.bl_qd.gds_quad_high || ib_blob.bl_qd.gds_quad_low) { /* not null ? */
433 		if (isc_open_blob(IB_STATUS, &ib_link->handle, &trans->handle, &ib_blob.bl_handle,
434 				&ib_blob.bl_qd)) {
435 			_php_ibase_error(TSRMLS_C);
436 			RETURN_FALSE;
437 		}
438 
439 		if (_php_ibase_blob_info(ib_blob.bl_handle, &bl_info TSRMLS_CC)) {
440 			RETURN_FALSE;
441 		}
442 		if (isc_close_blob(IB_STATUS, &ib_blob.bl_handle)) {
443 			_php_ibase_error(TSRMLS_C);
444 			RETURN_FALSE;
445 		}
446 	} else { /* null blob, all values to zero */
447 		bl_info.max_segment = 0;
448 		bl_info.num_segments = 0;
449 		bl_info.total_length = 0;
450 		bl_info.bl_stream = 0;
451 	}
452 
453 	array_init(return_value);
454 
455 	add_index_long(return_value, 0, bl_info.total_length);
456  	add_assoc_long(return_value, "length", bl_info.total_length);
457 
458 	add_index_long(return_value, 1, bl_info.num_segments);
459  	add_assoc_long(return_value, "numseg", bl_info.num_segments);
460 
461 	add_index_long(return_value, 2, bl_info.max_segment);
462  	add_assoc_long(return_value, "maxseg", bl_info.max_segment);
463 
464 	add_index_bool(return_value, 3, bl_info.bl_stream);
465  	add_assoc_bool(return_value, "stream", bl_info.bl_stream);
466 
467 	add_index_bool(return_value, 4, (!ib_blob.bl_qd.gds_quad_high && !ib_blob.bl_qd.gds_quad_low));
468  	add_assoc_bool(return_value, "isnull", (!ib_blob.bl_qd.gds_quad_high && !ib_blob.bl_qd.gds_quad_low));
469 }
470 /* }}} */
471 
472 /* {{{ proto bool ibase_blob_echo([ resource link_identifier, ] string blob_id)
473    Output blob contents to browser */
PHP_FUNCTION(ibase_blob_echo)474 PHP_FUNCTION(ibase_blob_echo)
475 {
476 	char *blob_id;
477 	int blob_id_len;
478 	zval *link = NULL;
479 	ibase_db_link *ib_link;
480 	ibase_trans *trans = NULL;
481 	ibase_blob ib_blob_id = { NULL, BLOB_OUTPUT  };
482 	char bl_data[IBASE_BLOB_SEG];
483 	unsigned short seg_len;
484 
485 	RESET_ERRMSG;
486 
487 	switch (ZEND_NUM_ARGS()) {
488 		default:
489 			WRONG_PARAM_COUNT;
490 		case 1:
491 			if (FAILURE == zend_parse_parameters(1 TSRMLS_CC, "s", &blob_id, &blob_id_len)) {
492 				RETURN_FALSE;
493 			}
494 			break;
495 		case 2:
496 			if (FAILURE == zend_parse_parameters(2 TSRMLS_CC, "rs", &link, &blob_id, &blob_id_len)) {
497 				RETURN_FALSE;
498 			}
499 			break;
500 	}
501 
502 	PHP_IBASE_LINK_TRANS(link, ib_link, trans);
503 
504 	if (! _php_ibase_string_to_quad(blob_id, &ib_blob_id.bl_qd)) {
505 		_php_ibase_module_error("Unrecognized BLOB ID" TSRMLS_CC);
506 		RETURN_FALSE;
507 	}
508 
509 	do {
510 		if (isc_open_blob(IB_STATUS, &ib_link->handle, &trans->handle, &ib_blob_id.bl_handle,
511 				&ib_blob_id.bl_qd)) {
512 			break;
513 		}
514 
515 		while (!isc_get_segment(IB_STATUS, &ib_blob_id.bl_handle, &seg_len, sizeof(bl_data), bl_data)
516 				|| IB_STATUS[1] == isc_segment) {
517 			PHPWRITE(bl_data, seg_len);
518 		}
519 
520 		if (IB_STATUS[0] && (IB_STATUS[1] != isc_segstr_eof)) {
521 			break;
522 		}
523 
524 		if (isc_close_blob(IB_STATUS, &ib_blob_id.bl_handle)) {
525 			break;
526 		}
527 		RETURN_TRUE;
528 	} while (0);
529 
530 	_php_ibase_error(TSRMLS_C);
531 	RETURN_FALSE;
532 }
533 /* }}} */
534 
535 /* {{{ proto string ibase_blob_import([ resource link_identifier, ] resource file)
536    Create blob, copy file in it, and close it */
PHP_FUNCTION(ibase_blob_import)537 PHP_FUNCTION(ibase_blob_import)
538 {
539 	zval *link = NULL, *file;
540 	int size;
541 	unsigned short b;
542 	ibase_blob ib_blob = { NULL, 0 };
543 	ibase_db_link *ib_link;
544 	ibase_trans *trans = NULL;
545 	char bl_data[IBASE_BLOB_SEG];
546 	php_stream *stream;
547 
548 	RESET_ERRMSG;
549 
550 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|r",
551 			(ZEND_NUM_ARGS()-1) ? &link : &file, &file)) {
552 		RETURN_FALSE;
553 	}
554 
555 	PHP_IBASE_LINK_TRANS(link, ib_link, trans);
556 
557 	php_stream_from_zval(stream, &file);
558 
559 	do {
560 		if (isc_create_blob(IB_STATUS, &ib_link->handle, &trans->handle, &ib_blob.bl_handle,
561 				&ib_blob.bl_qd)) {
562 			break;
563 		}
564 
565 		for (size = 0; (b = php_stream_read(stream, bl_data, sizeof(bl_data))); size += b) {
566 			if (isc_put_segment(IB_STATUS, &ib_blob.bl_handle, b, bl_data)) {
567 				break;
568 			}
569 		}
570 
571 		if (isc_close_blob(IB_STATUS, &ib_blob.bl_handle)) {
572 			break;
573 		}
574 		RETURN_STRINGL( _php_ibase_quad_to_string(ib_blob.bl_qd), BLOB_ID_LEN, 0);
575 	} while (0);
576 
577 	_php_ibase_error(TSRMLS_C);
578 	RETURN_FALSE;
579 }
580 /* }}} */
581 
582 #endif /* HAVE_IBASE */
583 
584 /*
585  * Local variables:
586  * tab-width: 4
587  * c-basic-offset: 4
588  * End:
589  * vim600: sw=4 ts=4 fdm=marker
590  * vim<600: sw=4 ts=4
591  */
592