ofxconnect.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002          ofx_connect.cpp 
00003                              -------------------
00004     copyright            : (C) 2005 by Ace Jones
00005     email                : acejones@users.sourceforge.net
00006 ***************************************************************************/
00023 /***************************************************************************
00024  *                                                                         *
00025  *   This program is free software; you can redistribute it and/or modify  *
00026  *   it under the terms of the GNU General Public License as published by  *
00027  *   the Free Software Foundation; either version 2 of the License, or     *
00028  *   (at your option) any later version.                                   *
00029  *                                                                         *
00030  ***************************************************************************/
00031 #include <iostream>
00032 #include <fstream>
00033 #include <string>
00034 #include "libofx.h"
00035 #include <config.h>             /* Include config constants, e.g., VERSION TF */
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <unistd.h>
00039 
00040 #ifdef HAVE_LIBCURL
00041 #include <curl/curl.h>
00042 #endif
00043 
00044 #include "cmdline.h" /* Gengetopt generated parser */
00045 
00046 #include "nodeparser.h"
00047 #include "ofxpartner.h"
00048 
00049 using namespace std;
00050 
00051 #ifdef HAVE_LIBCURL
00052 bool post(const char* request, const char* url, const char* filename)
00053 {
00054   CURL *curl = curl_easy_init();
00055   if(! curl)
00056     return false;
00057 
00058   unlink("tmpout");  
00059   FILE* file = fopen(filename,"wb");
00060   if (! file )
00061   {
00062     curl_easy_cleanup(curl);
00063     return false;
00064   }
00065     
00066   curl_easy_setopt(curl, CURLOPT_URL, url);
00067   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);
00068 
00069   struct curl_slist *headerlist=NULL;
00070   headerlist=curl_slist_append(headerlist, "Content-type: application/x-ofx");
00071   headerlist=curl_slist_append(headerlist, "Accept: */*, application/x-ofx");    
00072   
00073   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
00074   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
00075   curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)file);
00076     
00077   CURLcode res = curl_easy_perform(curl);
00078 
00079   curl_easy_cleanup(curl);
00080   curl_slist_free_all (headerlist);
00081   
00082   fclose(file);
00083   
00084   return true;
00085 }
00086 #else
00087 bool post(const char*, const char*, const char*)
00088 {
00089   cerr << "ERROR: libox must be configured with libcurl to post this request directly" << endl;
00090   return false;
00091 }
00092 #endif
00093 
00094 ostream& operator<<(ostream& os,const vector<string>& strvect)
00095 {
00096   for( vector<string>::const_iterator it=strvect.begin(); it!=strvect.end(); ++it)
00097   {
00098     os << (*it) << endl;
00099   }
00100   return os;
00101 }
00102 
00103 int main (int argc, char *argv[])
00104 {
00105   gengetopt_args_info args_info;
00106   
00107   if (cmdline_parser (argc, argv, &args_info) != 0)
00108     exit(1) ;
00109 
00110   if ( argc == 1 )
00111   {
00112     cmdline_parser_print_help();
00113     exit(1);
00114   }
00115 
00116   if ( args_info.statement_req_given || args_info.accountinfo_req_given )
00117   {
00118   if ( (args_info.inputs_num > 0) )
00119   {
00120     cout << "file " << args_info.inputs[0] << endl;
00121   }
00122   else
00123   {
00124     cerr << "ERROR: You must specify an output file" << endl;
00125   }
00126   }
00127   else if ( args_info.bank_fipid_given || args_info.bank_services_given )
00128   {
00129   if ( (args_info.inputs_num > 0) )
00130   {
00131     cout << "bank " << args_info.inputs[0] << endl;
00132   }
00133   else
00134   {
00135     cerr << "ERROR: You must specify an bank" << endl;
00136   }
00137   }
00138  
00139   OfxFiLogin fi;
00140   memset(&fi,0,sizeof(OfxFiLogin));
00141   bool ok = true;
00142   string url;
00143  
00144   if ( args_info.statement_req_given || args_info.accountinfo_req_given || args_info.payment_req_given || args_info.paymentinquiry_req_given )
00145   {
00146   // Get the FI Login information
00147   // 
00148  
00149   if ( args_info.fipid_given )
00150   {
00151     cerr << "fipid " <<  args_info.fipid_arg << endl;  
00152     cerr << "contacting partner server..." << endl;
00153     OfxFiServiceInfo svcinfo = OfxPartner::ServiceInfo(args_info.fipid_arg);
00154     cout << "fid " << svcinfo.fid << endl;
00155     strncpy(fi.fid,svcinfo.fid,OFX_FID_LENGTH-1);
00156     cout << "org " << svcinfo.org << endl;
00157     strncpy(fi.org,svcinfo.org,OFX_ORG_LENGTH-1);
00158     cout << "url " << svcinfo.url << endl;
00159     url = svcinfo.url;
00160   }
00161   if ( args_info.fid_given )
00162   {
00163     cerr << "fid " <<  args_info.fid_arg << endl;  
00164     strncpy(fi.fid,args_info.fid_arg,OFX_FID_LENGTH-1);
00165   }
00166   else if ( ! args_info.fipid_given )
00167   {
00168     cerr << "ERROR: --fid is required" << endl;
00169     ok = false;
00170   }
00171   
00172   if ( args_info.org_given )
00173   {
00174     cerr << "org " << args_info.org_arg << endl;  
00175     strncpy(fi.org,args_info.org_arg,OFX_ORG_LENGTH-1);
00176   }
00177   else if ( ! args_info.fipid_given )
00178   {
00179     cerr << "ERROR: --org is required" << endl;
00180     ok = false;
00181   }
00182 
00183   if ( args_info.user_given )
00184   {
00185     cerr << "user " << args_info.user_arg << endl;  
00186     strncpy(fi.userid,args_info.user_arg,OFX_USERID_LENGTH-1);
00187   }
00188   else
00189   {
00190     cerr << "ERROR: --user is required" << endl;
00191     ok = false;
00192   }
00193   
00194   if ( args_info.pass_given )
00195   {
00196     cerr << "pass " << args_info.pass_arg << endl;  
00197     strncpy(fi.userpass,args_info.pass_arg,OFX_USERPASS_LENGTH-1);
00198   }
00199   else
00200   {
00201     cerr << "ERROR: --pass is required" << endl;
00202     ok = false;
00203   }
00204   
00205   if ( args_info.url_given )
00206     url = args_info.url_arg;
00207   }
00208   
00209   if ( args_info.statement_req_given )
00210   {
00211     cerr << "Statement request" << endl;
00212     
00213     OfxAccountInfo account;
00214     memset(&account,0,sizeof(OfxAccountInfo));
00215     
00216     if ( args_info.bank_given )
00217     {
00218       cerr << "bank " << args_info.bank_arg << endl;  
00219       strncpy(account.bankid,args_info.bank_arg,OFX_BANKID_LENGTH-1);
00220     }
00221     else    
00222     {
00223       if ( args_info.type_given && args_info.type_arg == 1 )
00224       {
00225         cerr << "ERROR: --bank is required for a bank request" << endl;
00226         ok = false;
00227       }
00228     }
00229     
00230     if ( args_info.broker_given )
00231     {
00232       cerr << "broker " << args_info.broker_arg << endl;  
00233       strncpy(account.brokerid,args_info.broker_arg,OFX_BROKERID_LENGTH-1);
00234     }
00235     else
00236     {
00237       if ( args_info.type_given && args_info.type_arg == 2 )
00238       {
00239         cerr << "ERROR: --broker is required for an investment statement request" << endl;
00240         ok = false;
00241       }
00242     }
00243     
00244     if ( args_info.acct_given )
00245     {
00246       cerr << "acct " << args_info.acct_arg << endl;  
00247       strncpy(account.accountid,args_info.acct_arg,OFX_ACCOUNT_ID_LENGTH-1);
00248     }
00249     else
00250     {
00251       cerr << "ERROR: --acct is required for a statement request" << endl;
00252       ok = false;
00253     }
00254     
00255     if ( args_info.type_given )
00256     {
00257       cerr << "type " << args_info.type_arg << endl;  
00258       account.type = static_cast<AccountType>(args_info.type_arg);
00259     }
00260     else
00261     {
00262       cerr << "ERROR: --type is required for a statement request" << endl;
00263       ok = false;
00264     }
00265     
00266     if ( args_info.past_given )
00267     {
00268       cerr << "past " << args_info.past_arg << endl;  
00269     }
00270     else
00271     {
00272       cerr << "ERROR: --past is required for a statement request" << endl;
00273       ok = false;
00274     }
00275     
00276     if ( ok )
00277     {
00278       char* request = libofx_request_statement( &fi, &account, time(NULL) - args_info.past_arg * 86400L );
00279     
00280       if ( url.length() ) 
00281         post(request,url.c_str(),args_info.inputs[0]);
00282       else
00283         cout << request;
00284       
00285       free(request);
00286     }
00287   }
00288 
00289   if ( args_info.paymentinquiry_req_given )
00290   {
00291     char tridstr[33];
00292     memset(tridstr,0,33);
00293 
00294     bool ok = true;
00295 
00296     if ( args_info.trid_given )
00297     {
00298       cerr << "trid " << args_info.trid_arg << endl;  
00299       snprintf(tridstr,32,"%i",args_info.trid_arg);
00300     }
00301     else
00302     {
00303       cerr << "ERROR: --trid is required for a payment inquiry request" << endl;
00304       ok = false;
00305     }
00306  
00307     if ( ok )
00308     {
00309       char* request = libofx_request_payment_status( &fi, tridstr );
00310  
00311       filebuf fb;
00312       fb.open ("query",ios::out);
00313       ostream os(&fb);
00314       os << request;
00315       fb.close();
00316       
00317       if ( url.length() ) 
00318         post(request,url.c_str(),args_info.inputs[0]);
00319       else
00320         cout << request;
00321     
00322       free(request);
00323     }
00324   }
00325   
00326   if ( args_info.payment_req_given )
00327   {
00328     OfxAccountInfo account;
00329     memset(&account,0,sizeof(OfxAccountInfo));
00330     OfxPayee payee;
00331     memset(&payee,0,sizeof(OfxPayee));
00332     OfxPayment payment;
00333     memset(&payment,0,sizeof(OfxPayment));
00334 
00335     strcpy(payee.name,"MARTIN PREUSS");
00336     strcpy(payee.address1,"1 LAUREL ST");
00337     strcpy(payee.city,"SAN CARLOS");
00338     strcpy(payee.state,"CA");
00339     strcpy(payee.postalcode,"94070");
00340     strcpy(payee.phone,"866-555-1212");
00341         
00342     strcpy(payment.amount,"200.00");
00343     strcpy(payment.account,"1234");
00344     strcpy(payment.datedue,"20060301");
00345     strcpy(payment.memo,"This is a test");
00346 
00347     bool ok = true;
00348 
00349     if ( args_info.bank_given )
00350     {
00351       cerr << "bank " << args_info.bank_arg << endl;  
00352       strncpy(account.bankid,args_info.bank_arg,OFX_BANKID_LENGTH-1);
00353     }
00354     else    
00355     {
00356       if ( args_info.type_given && args_info.type_arg == 1 )
00357       {
00358         cerr << "ERROR: --bank is required for a bank request" << endl;
00359         ok = false;
00360       }
00361     }
00362     
00363     if ( args_info.broker_given )
00364     {
00365       cerr << "broker " << args_info.broker_arg << endl;  
00366       strncpy(account.brokerid,args_info.broker_arg,OFX_BROKERID_LENGTH-1);
00367     }
00368     else
00369     {
00370       if ( args_info.type_given && args_info.type_arg == 2 )
00371       {
00372         cerr << "ERROR: --broker is required for an investment statement request" << endl;
00373         ok = false;
00374       }
00375     }
00376     
00377     if ( args_info.acct_given )
00378     {
00379       cerr << "acct " << args_info.acct_arg << endl;  
00380       strncpy(account.accountid,args_info.acct_arg,OFX_ACCOUNT_ID_LENGTH-1);
00381     }
00382     else
00383     {
00384       cerr << "ERROR: --acct is required for a statement request" << endl;
00385       ok = false;
00386     }
00387     
00388     if ( args_info.type_given )
00389     {
00390       cerr << "type " << args_info.type_arg << endl;  
00391       account.type = static_cast<AccountType>(args_info.type_arg);
00392     }
00393     else
00394     {
00395       cerr << "ERROR: --type is required for a statement request" << endl;
00396       ok = false;
00397     }
00398     
00399     if ( ok )
00400     {
00401       char* request = libofx_request_payment( &fi, &account, &payee, &payment );
00402     
00403       filebuf fb;
00404       fb.open ("query",ios::out);
00405       ostream os(&fb);
00406       os << request;
00407       fb.close();
00408       
00409       if ( url.length() ) 
00410         post(request,url.c_str(),args_info.inputs[0]);
00411       else
00412         cout << request;
00413     
00414       free(request);
00415     }
00416         
00417   }
00418   
00419   if ( args_info.accountinfo_req_given )
00420   {
00421     if ( ok )
00422     {
00423       char* request = libofx_request_accountinfo( &fi );
00424     
00425       if ( url.length() ) 
00426         post(request,url.c_str(),args_info.inputs[0]);
00427       else
00428         cout << request;
00429     
00430       free(request);
00431     }
00432   }
00433         
00434   if ( args_info.bank_list_given )
00435   {
00436     cout << OfxPartner::BankNames();
00437   }
00438   
00439   if ( args_info.bank_fipid_given )
00440   {
00441     cout << OfxPartner::FipidForBank(args_info.inputs[0]);
00442   }
00443   
00444   if ( args_info.bank_services_given )
00445   {
00446     OfxFiServiceInfo svcinfo = OfxPartner::ServiceInfo(args_info.inputs[0]);
00447     cout << "Account List? " << (svcinfo.accountlist?"Yes":"No") << endl;
00448     cout << "Statements? " << (svcinfo.statements?"Yes":"No") << endl;
00449     cout << "Billpay? " << (svcinfo.billpay?"Yes":"No") << endl;
00450     cout << "Investments? " << (svcinfo.investments?"Yes":"No") << endl;
00451   }
00452  
00453   if ( args_info.allsupport_given )
00454   {
00455     vector<string> banks = OfxPartner::BankNames();
00456     vector<string>::const_iterator it_bank = banks.begin();
00457     while ( it_bank != banks.end() )
00458     {
00459       vector<string> fipids = OfxPartner::FipidForBank(*it_bank);
00460       vector<string>::const_iterator it_fipid = fipids.begin();
00461       while ( it_fipid != fipids.end() )
00462       {
00463         if ( OfxPartner::ServiceInfo(*it_fipid).accountlist )
00464           cout << *it_bank << endl;
00465         ++it_fipid;
00466       }
00467       ++it_bank;
00468     }
00469   }
00470   
00471   return 0;
00472 }
00473 
00474 
00475 // vim:cin:si:ai:et:ts=2:sw=2:
00476 

Generated on Mon Jan 8 22:35:46 2007 for LibOFX by  doxygen 1.4.7