~ubuntu-branches/ubuntu/hardy/php5/hardy-updates

« back to all changes in this revision

Viewing changes to ext/pfpro/pfpro.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-10-09 03:14:32 UTC
  • Revision ID: james.westby@ubuntu.com-20051009031432-kspik3lobxstafv9
Tags: upstream-5.0.5
ImportĀ upstreamĀ versionĀ 5.0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   +----------------------------------------------------------------------+
 
3
   | PHP Version 5                                                        |
 
4
   +----------------------------------------------------------------------+
 
5
   | Copyright (c) 1997-2004 The PHP Group                                |
 
6
   +----------------------------------------------------------------------+
 
7
   | This source file is subject to version 3.0 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_0.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: David Croft <david@infotrek.co.uk>,                         |
 
16
   |          John Donagher <john@webmeta.com>                            |
 
17
   +----------------------------------------------------------------------+
 
18
*/
 
19
 
 
20
/* $Id: pfpro.c,v 1.33 2004/05/20 00:11:11 iliaa Exp $ */
 
21
 
 
22
#ifdef HAVE_CONFIG_H
 
23
#include "config.h"
 
24
#endif
 
25
 
 
26
#include "php.h"
 
27
#include "php_pfpro.h"
 
28
 
 
29
#if HAVE_PFPRO
 
30
 
 
31
/* {{{ includes */
 
32
#include "php_ini.h"
 
33
#include "ext/standard/info.h"
 
34
#include "ext/standard/php_string.h"
 
35
#include <pfpro.h>
 
36
/* }}} */
 
37
 
 
38
/* {{{ zts */
 
39
ZEND_DECLARE_MODULE_GLOBALS(pfpro)
 
40
/* }}} */
 
41
 
 
42
/* {{{ Function table */
 
43
function_entry pfpro_functions[] = {
 
44
        PHP_FE(pfpro_version, NULL)
 
45
        PHP_FE(pfpro_init, NULL)
 
46
        PHP_FE(pfpro_cleanup, NULL)
 
47
        PHP_FE(pfpro_process_raw, NULL)
 
48
        PHP_FE(pfpro_process, NULL)
 
49
        {NULL, NULL, NULL}
 
50
};
 
51
/* }}} */
 
52
 
 
53
/* {{{ Zend module entry */
 
54
zend_module_entry pfpro_module_entry = {
 
55
        STANDARD_MODULE_HEADER,
 
56
        "pfpro",
 
57
        pfpro_functions,
 
58
        PHP_MINIT(pfpro),
 
59
        PHP_MSHUTDOWN(pfpro),
 
60
        PHP_RINIT(pfpro),                                       /* request start */
 
61
        PHP_RSHUTDOWN(pfpro),                           /* request end */
 
62
        PHP_MINFO(pfpro),
 
63
        NO_VERSION_YET,
 
64
        STANDARD_MODULE_PROPERTIES
 
65
};
 
66
/* }}} */
 
67
 
 
68
/* {{{ dl() stuff */
 
69
#ifdef COMPILE_DL_PFPRO
 
70
ZEND_GET_MODULE(pfpro)
 
71
#endif
 
72
/* }}} */
 
73
 
 
74
/* {{{ initialization defaults */
 
75
PHP_INI_BEGIN()
 
76
        STD_PHP_INI_ENTRY("pfpro.defaulthost",    "test-payflow.verisign.com", PHP_INI_ALL, OnUpdateString,     defaulthost, zend_pfpro_globals, pfpro_globals)
 
77
        STD_PHP_INI_ENTRY("pfpro.defaultport",    "443", PHP_INI_ALL, OnUpdateLong,    defaultport,    zend_pfpro_globals, pfpro_globals)
 
78
        STD_PHP_INI_ENTRY("pfpro.defaulttimeout", "30",  PHP_INI_ALL, OnUpdateLong,    defaulttimeout, zend_pfpro_globals, pfpro_globals)
 
79
        STD_PHP_INI_ENTRY("pfpro.proxyaddress",   "",    PHP_INI_ALL, OnUpdateString, proxyaddress,   zend_pfpro_globals, pfpro_globals)
 
80
        STD_PHP_INI_ENTRY("pfpro.proxyport",      "",    PHP_INI_ALL, OnUpdateLong,    proxyport,      zend_pfpro_globals, pfpro_globals)
 
81
        STD_PHP_INI_ENTRY("pfpro.proxylogon",     "",    PHP_INI_ALL, OnUpdateString, proxylogon,     zend_pfpro_globals, pfpro_globals)
 
82
        STD_PHP_INI_ENTRY("pfpro.proxypassword",  "",    PHP_INI_ALL, OnUpdateString, proxypassword,  zend_pfpro_globals, pfpro_globals)
 
83
PHP_INI_END()
 
84
 
 
85
/* {{{ php_extname_init_globals
 
86
 */
 
87
static void php_pfpro_init_globals(zend_pfpro_globals *pfpro_globals)
 
88
{
 
89
        pfpro_globals->initialized    = 0;
 
90
        pfpro_globals->defaulthost    = NULL;
 
91
        pfpro_globals->defaultport    = 0;
 
92
        pfpro_globals->defaulttimeout = 0;
 
93
        pfpro_globals->proxyaddress   = NULL;
 
94
        pfpro_globals->proxyport      = 0;
 
95
        pfpro_globals->proxylogon     = NULL;
 
96
        pfpro_globals->proxypassword  = NULL;
 
97
}
 
98
/* }}} */
 
99
 
 
100
PHP_MINIT_FUNCTION(pfpro)
 
101
{
 
102
        ZEND_INIT_MODULE_GLOBALS(pfpro, php_pfpro_init_globals, NULL);
 
103
        REGISTER_INI_ENTRIES();
 
104
        return SUCCESS;
 
105
}
 
106
 
 
107
PHP_MSHUTDOWN_FUNCTION(pfpro)
 
108
{
 
109
        UNREGISTER_INI_ENTRIES();
 
110
        return SUCCESS;
 
111
}
 
112
 
 
113
PHP_RINIT_FUNCTION(pfpro)
 
114
{
 
115
        PFPROG(initialized) = 0;
 
116
 
 
117
        return SUCCESS;
 
118
}
 
119
 
 
120
PHP_RSHUTDOWN_FUNCTION(pfpro)
 
121
{
 
122
        if (PFPROG(initialized) == 1) {
 
123
                pfproCleanup();
 
124
        }
 
125
 
 
126
        return SUCCESS;
 
127
}
 
128
/* }}} */
 
129
 
 
130
/* {{{ minfo registration */
 
131
PHP_MINFO_FUNCTION(pfpro)
 
132
{
 
133
        php_info_print_table_start();
 
134
        php_info_print_table_row(2, "Verisign Payflow Pro support", "enabled");
 
135
        php_info_print_table_row(2, "libpfpro version", pfproVersion());
 
136
        php_info_print_table_end();
 
137
 
 
138
        DISPLAY_INI_ENTRIES();
 
139
}
 
140
/* }}} */
 
141
 
 
142
/* {{{ proto string pfpro_version()
 
143
   Returns the version of the Payflow Pro library */
 
144
PHP_FUNCTION(pfpro_version)
 
145
{
 
146
        if (ZEND_NUM_ARGS() != 0) {
 
147
                WRONG_PARAM_COUNT;
 
148
        }
 
149
 
 
150
        RETURN_STRING((char *)pfproVersion(), 1);
 
151
}
 
152
/* }}} */
 
153
 
 
154
/* {{{ proto bool pfpro_init()
 
155
   Initializes the Payflow Pro library */
 
156
PHP_FUNCTION(pfpro_init)
 
157
{
 
158
        if (ZEND_NUM_ARGS() != 0) {
 
159
                WRONG_PARAM_COUNT;
 
160
        }
 
161
 
 
162
        pfproInit();
 
163
 
 
164
        PFPROG(initialized) = 1;
 
165
 
 
166
        RETURN_TRUE;
 
167
}
 
168
/* }}} */
 
169
 
 
170
/* {{{ proto bool pfpro_cleanup()
 
171
   Shuts down the Payflow Pro library */
 
172
PHP_FUNCTION(pfpro_cleanup)
 
173
{
 
174
        if (ZEND_NUM_ARGS() != 0) {
 
175
                WRONG_PARAM_COUNT;
 
176
        }
 
177
 
 
178
        pfproCleanup();
 
179
 
 
180
        PFPROG(initialized) = 0;
 
181
 
 
182
        RETURN_TRUE;
 
183
}
 
184
/* }}} */
 
185
 
 
186
/* {{{ proto string pfpro_process_raw(string parmlist [, string hostaddress [, int port, [, int timeout [, string proxyAddress [, int proxyPort [, string proxyLogon [, string proxyPassword]]]]]]])
 
187
   Raw Payflow Pro transaction processing */
 
188
PHP_FUNCTION(pfpro_process_raw)
 
189
{
 
190
        zval ***args;
 
191
        char *parmlist = NULL;
 
192
        char *address = NULL;
 
193
        int port = PFPROG(defaultport);
 
194
        int timeout = PFPROG(defaulttimeout);
 
195
        char *proxyAddress = PFPROG(proxyaddress);
 
196
        int proxyPort = PFPROG(proxyport);
 
197
        char *proxyLogon = PFPROG(proxylogon);
 
198
        char *proxyPassword = PFPROG(proxypassword);
 
199
        int freeaddress = 0;
 
200
#if PFPRO_VERSION < 3
 
201
        char response[512] = "";
 
202
#else
 
203
        int context;
 
204
        char *response;
 
205
#endif
 
206
 
 
207
        if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 8) {
 
208
                WRONG_PARAM_COUNT;
 
209
        }
 
210
 
 
211
        args = (zval ***) safe_emalloc(sizeof(zval **), ZEND_NUM_ARGS(), 0);
 
212
 
 
213
        if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
 
214
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to read parameters in pfpro_process_raw()");
 
215
                efree(args);
 
216
                RETURN_FALSE;
 
217
        }
 
218
 
 
219
        switch (ZEND_NUM_ARGS()) {
 
220
                case 8:
 
221
                        convert_to_string_ex(args[7]);
 
222
                        proxyPassword = Z_STRVAL_PP(args[7]);
 
223
                        /* fall through */
 
224
 
 
225
                case 7:
 
226
                        convert_to_string_ex(args[6]);
 
227
                        proxyLogon = Z_STRVAL_PP(args[6]);
 
228
                        /* fall through */
 
229
 
 
230
                case 6:
 
231
                        convert_to_long_ex(args[5]);
 
232
                        proxyPort = Z_LVAL_PP(args[5]);
 
233
                        /* fall through */
 
234
 
 
235
                case 5:
 
236
                        convert_to_string_ex(args[4]);
 
237
                        proxyAddress = Z_STRVAL_PP(args[4]);
 
238
                        /* fall through */
 
239
 
 
240
                case 4:
 
241
                        convert_to_long_ex(args[3]);
 
242
                        timeout = Z_LVAL_PP(args[3]);
 
243
                        /* fall through */
 
244
 
 
245
                case 3:
 
246
                        convert_to_long_ex(args[2]);
 
247
                        port = Z_LVAL_PP(args[2]);
 
248
                        /* fall through */
 
249
 
 
250
                case 2:
 
251
                        convert_to_string_ex(args[1]);
 
252
                        address = Z_STRVAL_PP(args[1]);
 
253
        }
 
254
 
 
255
        convert_to_string_ex(args[0]);
 
256
        parmlist = Z_STRVAL_PP(args[0]);
 
257
 
 
258
        efree(args);
 
259
 
 
260
        if (address == NULL) {
 
261
                address = estrdup(PFPROG(defaulthost));
 
262
                freeaddress = 1;
 
263
        }
 
264
 
 
265
#if PFPRO_VERSION < 3
 
266
        /* Blank the response buffer */
 
267
        memset(response, 0, sizeof(response));
 
268
#endif
 
269
 
 
270
        /* Initialize the library if needed */
 
271
 
 
272
        if (PFPROG(initialized) == 0) {
 
273
                pfproInit();
 
274
                PFPROG(initialized) = 1;
 
275
        }
 
276
 
 
277
        /* Perform the transaction */
 
278
 
 
279
#if PFPRO_VERSION < 3
 
280
        ProcessPNTransaction(address, port, proxyAddress, proxyPort, proxyLogon, proxyPassword, parmlist, strlen(parmlist), timeout, response);
 
281
#else
 
282
        pfproCreateContext(&context, address, port, timeout, proxyAddress, proxyPort, proxyLogon, proxyPassword);
 
283
        pfproSubmitTransaction(context, parmlist, strlen(parmlist), &response);
 
284
        pfproDestroyContext(context);
 
285
#endif
 
286
 
 
287
        if (freeaddress) {
 
288
                efree(address);
 
289
        }
 
290
 
 
291
        RETURN_STRING(response, 1);
 
292
}
 
293
/* }}} */
 
294
 
 
295
/* {{{ proto array pfpro_process(array parmlist [, string hostaddress [, int port, [, int timeout [, string proxyAddress [, int proxyPort [, string proxyLogon [, string proxyPassword]]]]]]])
 
296
   Payflow Pro transaction processing using arrays */
 
297
PHP_FUNCTION(pfpro_process)
 
298
{
 
299
        zval ***args;
 
300
        HashTable *target_hash;
 
301
        ulong num_key;
 
302
        char *string_key;
 
303
        zval **entry;
 
304
        int pass;
 
305
        char *parmlist = NULL;
 
306
        char *address = NULL;
 
307
        int port = PFPROG(defaultport);
 
308
        int timeout = PFPROG(defaulttimeout);
 
309
        char *proxyAddress = PFPROG(proxyaddress);
 
310
        int proxyPort = PFPROG(proxyport);
 
311
        char *proxyLogon = PFPROG(proxylogon);
 
312
        char *proxyPassword = PFPROG(proxypassword);
 
313
        int parmlength = 0;
 
314
        int freeaddress = 0;
 
315
#if PFPRO_VERSION < 3
 
316
        char response[512] = "";
 
317
#else
 
318
        int context;
 
319
        char *response;
 
320
#endif
 
321
        char tmpbuf[128];
 
322
        char *var,*val,*strtok_buf=NULL; /* Pointers for string manipulation */
 
323
 
 
324
        if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 8) {
 
325
                WRONG_PARAM_COUNT;
 
326
        }
 
327
 
 
328
        args = (zval ***) safe_emalloc(sizeof(zval **), ZEND_NUM_ARGS(), 0);
 
329
 
 
330
        if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
 
331
                efree(args);
 
332
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to read parameters in pfpro_process()");
 
333
                RETURN_FALSE;
 
334
        }
 
335
 
 
336
        if (Z_TYPE_PP(args[0]) != IS_ARRAY) {
 
337
                efree(args);
 
338
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "First parameter to pfpro_process() must be an array");
 
339
                RETURN_FALSE;
 
340
        }
 
341
 
 
342
        switch (ZEND_NUM_ARGS()) {
 
343
                case 8:
 
344
                        convert_to_string_ex(args[7]);
 
345
                        proxyPassword = Z_STRVAL_PP(args[7]);
 
346
                        /* fall through */
 
347
 
 
348
                case 7:
 
349
                        convert_to_string_ex(args[6]);
 
350
                        proxyLogon = Z_STRVAL_PP(args[6]);
 
351
                        /* fall through */
 
352
 
 
353
                case 6:
 
354
                        convert_to_long_ex(args[5]);
 
355
                        proxyPort = Z_LVAL_PP(args[5]);
 
356
                        /* fall through */
 
357
 
 
358
                case 5:
 
359
                        convert_to_string_ex(args[4]);
 
360
                        proxyAddress = Z_STRVAL_PP(args[4]);
 
361
                        /* fall through */
 
362
 
 
363
                case 4:
 
364
                        convert_to_long_ex(args[3]);
 
365
                        timeout = Z_LVAL_PP(args[3]);
 
366
                        /* fall through */
 
367
 
 
368
                case 3:
 
369
                        convert_to_long_ex(args[2]);
 
370
                        port = Z_LVAL_PP(args[2]);
 
371
                        /* fall through */
 
372
 
 
373
                case 2:
 
374
                        convert_to_string_ex(args[1]);
 
375
                        address = Z_STRVAL_PP(args[1]);
 
376
        }
 
377
 
 
378
        /* Concatenate the passed array as specified by Verisign.
 
379
           Basically it's all key=value&key=value, the only exception
 
380
           being if the value contains = or &, in which case we also
 
381
           encode the length, e.g. key[5]=bl&ah */
 
382
 
 
383
        target_hash = HASH_OF(*args[0]);
 
384
 
 
385
        for (pass = 0; pass <= 1; pass ++) {
 
386
 
 
387
                parmlength = 0;
 
388
                /* we go around the array twice. the first time to calculate
 
389
                   the string length, the second time to actually store it */
 
390
 
 
391
                zend_hash_internal_pointer_reset(target_hash);
 
392
 
 
393
                while (zend_hash_get_current_data(target_hash, (void **)&entry) == SUCCESS) {
 
394
 
 
395
                        if (parmlength > 0) {
 
396
                                if (pass == 1)
 
397
                                        strcpy(parmlist + parmlength, "&");
 
398
                                parmlength += 1;
 
399
                        }
 
400
 
 
401
                        switch (zend_hash_get_current_key(target_hash, &string_key, &num_key, 0)) {
 
402
 
 
403
                                case HASH_KEY_IS_STRING:
 
404
 
 
405
                                        if (pass == 1)
 
406
                                                strcpy(parmlist + parmlength, string_key);
 
407
                                        parmlength += strlen(string_key);
 
408
 
 
409
                                        break;
 
410
 
 
411
                                case HASH_KEY_IS_LONG:
 
412
 
 
413
                                        sprintf(tmpbuf, "%ld", num_key);
 
414
                                        if (pass == 1)
 
415
                                                strcpy(parmlist + parmlength, tmpbuf);
 
416
                                        parmlength += strlen(tmpbuf);
 
417
 
 
418
                                        break;
 
419
 
 
420
                                default:
 
421
                                        if (parmlist) {
 
422
                                                efree(parmlist);
 
423
                                        }
 
424
                                        efree(args);
 
425
                                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "pfpro_process() array keys must be strings or integers");
 
426
                                        RETURN_FALSE;
 
427
                        }
 
428
 
 
429
 
 
430
                        switch (Z_TYPE_PP(entry)) {
 
431
                                case IS_STRING:
 
432
                                        if (strchr(Z_STRVAL_PP(entry), '&')
 
433
                                                || strchr(Z_STRVAL_PP(entry), '=')) {
 
434
                                                sprintf(tmpbuf, "[%d]=", Z_STRLEN_PP(entry));
 
435
                                                if (pass == 1)
 
436
                                                        strcpy(parmlist + parmlength, tmpbuf);
 
437
                                                parmlength += strlen(tmpbuf);
 
438
                                        } else {
 
439
                                                if (pass == 1)
 
440
                                                        strcpy(parmlist + parmlength, "=");
 
441
                                                parmlength += 1;
 
442
                                        }
 
443
 
 
444
                                        if (pass == 1)
 
445
                                                strcpy(parmlist + parmlength, Z_STRVAL_PP(entry));
 
446
                                        parmlength += Z_STRLEN_PP(entry);
 
447
 
 
448
                                        break;
 
449
 
 
450
                                case IS_LONG:
 
451
                                        sprintf(tmpbuf, "=%ld", Z_LVAL_PP(entry));
 
452
                                        if (pass == 1)
 
453
                                                strcpy(parmlist + parmlength, tmpbuf);
 
454
                                        parmlength += strlen(tmpbuf);
 
455
 
 
456
                                        break;
 
457
 
 
458
                                case IS_DOUBLE:
 
459
                                        sprintf(tmpbuf, "=%.2f", Z_DVAL_PP(entry));
 
460
                                        if (pass == 1)
 
461
                                                strcpy(parmlist + parmlength, tmpbuf);
 
462
                                        parmlength += strlen(tmpbuf);
 
463
 
 
464
                                        break;
 
465
 
 
466
                                default:
 
467
                                        if (parmlist) {
 
468
                                                efree(parmlist);
 
469
                                        }
 
470
                                        efree(args);
 
471
                                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "pfpro_process() array values must be strings, ints or floats");
 
472
                                        RETURN_FALSE;
 
473
                        }
 
474
                        zend_hash_move_forward(target_hash);
 
475
                }
 
476
 
 
477
                if (pass == 0) {
 
478
                        parmlist = emalloc(parmlength + 1);
 
479
                }
 
480
        }
 
481
 
 
482
        efree(args);
 
483
 
 
484
        if (address == NULL) {
 
485
                address = estrdup(PFPROG(defaulthost));
 
486
                freeaddress = 1;
 
487
        }
 
488
 
 
489
        /* Allocate the array for the response now - so we catch any errors
 
490
           from this BEFORE we knock it off to the bank */
 
491
 
 
492
        array_init(return_value);
 
493
 
 
494
#if PFPRO_VERSION < 3
 
495
        /* Blank the response buffer */
 
496
        memset(response, 0, sizeof(response));
 
497
#endif
 
498
 
 
499
        /* Initialize the library if needed */
 
500
 
 
501
        if (PFPROG(initialized) == 0) {
 
502
                pfproInit();
 
503
                PFPROG(initialized) = 1;
 
504
        }
 
505
 
 
506
        /* Perform the transaction */
 
507
 
 
508
#if PFPRO_VERSION < 3
 
509
        ProcessPNTransaction(address, port, proxyAddress, proxyPort, proxyLogon, proxyPassword, parmlist, strlen(parmlist), timeout, response);
 
510
#else
 
511
        pfproCreateContext(&context, address, port, timeout, proxyAddress, proxyPort, proxyLogon, proxyPassword);
 
512
        pfproSubmitTransaction(context, parmlist, strlen(parmlist), &response);
 
513
        pfproDestroyContext(context);
 
514
#endif
 
515
 
 
516
        if (freeaddress) {
 
517
                efree(address);
 
518
        }
 
519
 
 
520
        if (parmlist) {
 
521
                efree(parmlist);
 
522
        }
 
523
 
 
524
        /* This final chunk of code is to walk the returned string
 
525
         * and build the return array to the user.
 
526
     */
 
527
        var = php_strtok_r(response, "&", &strtok_buf);
 
528
 
 
529
        while (var) {
 
530
                val = strchr(var, '=');
 
531
                if (val) { /* have a value */
 
532
                        *val++ = '\0';
 
533
                        add_assoc_string(return_value, var, val, 1);
 
534
                }
 
535
                var = php_strtok_r(NULL, "&", &strtok_buf);
 
536
        }
 
537
}
 
538
/* }}} */
 
539
 
 
540
#endif  /* HAVE_PFPRO */
 
541
 
 
542
/*
 
543
 * Local variables:
 
544
 * tab-width: 4
 
545
 * c-basic-offset: 4
 
546
 * End:
 
547
 * vim600: sw=4 ts=4 fdm=marker
 
548
 * vim<600: sw=4 ts=4
 
549
 */