/* cybercash.c by jsc@arsdigita.com; June 1998 defines three Tcl procedures for the AOLserver API: cc_generate_order_id, returns a unique order ID (not useful if you are generating keys with an Oracle sequence or whatever) cc_send_to_server_21, access to the direct Cybercash API documented in Appendix B of the CashRegister Service Development Guide (1.0) cc_do_direct_payment, access to the directpaycredit facility documented in Appendix A of the CashRegister Service Development Guide (1.0) note that cc_send_to_server_21 provides a superset of the capabilities of cc_do_direct_payment this software is copyright 1998 by ArsDigita, LLC and Jin S. Choi it is distributed free under the GNU General Public License (available at http://www.gnu.org/copyleft/gpl.html ) */ #include "ns.h" #include "CCMckDirect.h" #include "CCMckDirectPayment.h" #include "CCErrno.h" #define CONFFILE "/home/cybercash/mck-cgi/conf/merchant_conf" DllExport int Ns_ModuleVersion = 1; static Tcl_CmdProc GenerateOrderIDCmd; static Tcl_CmdProc SendToServer21Cmd; static int GenerateOrderIDCmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) { struct tm* timerec; pid_t mypid; time_t mytime; if (argc != 1) { interp->result = "Usage: cc_generate_order_id"; return TCL_ERROR; } mytime = time((time_t *) NULL); mypid = getpid(); timerec = gmtime(&mytime); sprintf(interp->result,"%02d%02d%02d%02d%02d%05ld", timerec->tm_year, timerec->tm_mon + 1, timerec->tm_mday, timerec->tm_hour, timerec->tm_min, mypid); return TCL_OK; } /** * Returns CC_SUCCESS if successful, CC error code if one of the * CCAddPairNVlist()'s failed. */ static int copy_ns_set_to_NVlist(Ns_Set *set, CCNVlistPtr nv) { int i; int set_size = Ns_SetSize(set); for (i = 0; i < set_size; i++) { char *key = Ns_SetKey(set, i); char *value = Ns_SetValue(set, i); int err; err = CCAddPairNVlist(nv, key, value); if (err != CC_SUCCESS) return err; } return CC_SUCCESS; } static void copy_NVlist_to_ns_set(CCNVlistPtr nv, Ns_Set *set) { int i; int len = CCSizeNVlist(nv); for (i = 0; i < len; i++) { CCNVpairPtr pair = CCGetPairNVlist(nv, i); char *key = pair->name; char *value = pair->value; Ns_SetPut(set, key, value); } } /** * Takes two ns_set's, input and output. * Output set is cleared and filled with result values. */ static int SendToServer21Cmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) { Ns_Set *input, *output; CCNVlistPtr args, result; char *command; if (argc != 4) { interp->result = "Usage: cc_send_to_server_21 "; return TCL_ERROR; } command = argv[1]; input = Ns_TclGetSet(interp, argv[2]); output = Ns_TclGetSet(interp, argv[3]); if (input == NULL || output == NULL) { interp->result = "input or output was not a valid ns_set"; return TCL_ERROR; } args = CCNewNVlist(); if (copy_ns_set_to_NVlist(input, args) != CC_SUCCESS) { interp->result = "send_to_server couldn't convert input args to CCNVlist"; return TCL_ERROR; } result = SendCC2_1Server(command, args); CCDeleteNVlist(args); copy_NVlist_to_ns_set(result, output); CCDeleteNVlist(result); return TCL_OK; } static int DirectPaymentCmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) { Ns_Set *input, *pop, *tokenlist; CCNVlistPtr args, POP, TokenList; char *url; /* Check input values. */ if (argc != 5) { interp->result = "Usage: cc_do_direct_payment "; return TCL_ERROR; } url = argv[1]; input = Ns_TclGetSet(interp, argv[2]); pop = Ns_TclGetSet(interp, argv[3]); tokenlist = Ns_TclGetSet(interp, argv[4]); if (input == NULL || tokenlist == NULL || pop == NULL) { interp->result = "one of the arguments was not a valid ns_set"; return TCL_ERROR; } /* Convert input args. */ args = CCNewNVlist(); if (copy_ns_set_to_NVlist(input, args) != CC_SUCCESS) { interp->result = "couldn't convert input args to CCNVlist"; return TCL_ERROR; } /* Call the CC function. */ TokenList = NULL; doDirectPayment(url, args, &POP, &TokenList); CCDeleteNVlist(args); /* Convert output to ns_set's. */ copy_NVlist_to_ns_set(POP, pop); copy_NVlist_to_ns_set(TokenList, tokenlist); CCDeleteNVlist(POP); CCDeleteNVlist(TokenList); return TCL_OK; } static int CybercashInterpInit(Tcl_Interp *interp, void *context) { int error_code; error_code = CCMckDirectSetup(CONFFILE); if (error_code != 0) { Ns_Log(Error, "Couldn't initialize cybercash module with conf file %s: %s [%d]\n", CONFFILE, CCGetErrorMessage(error_code), error_code); return NS_ERROR; } Tcl_CreateCommand(interp, "cc_generate_order_id", GenerateOrderIDCmd, NULL, NULL); Tcl_CreateCommand(interp, "cc_send_to_server_21", SendToServer21Cmd, NULL, NULL); Tcl_CreateCommand(interp, "cc_do_direct_payment", DirectPaymentCmd, NULL, NULL); return NS_OK; } DllExport int Ns_ModuleInit(char *hServer, char *hModule) { return (Ns_TclInitInterps(hServer, CybercashInterpInit, NULL)); }