27 #include <curl/curl.h>    48 bool post(
const string& request, 
const string& url, 
const string& filename);
    50 const string kBankFilename = 
"ofx-bank-index.xml";
    51 const string kCcFilename = 
"ofx-cc-index.xml";
    52 const string kInvFilename = 
"ofx-inv-index.xml";
    54 void ValidateIndexCache(
void)
    58   struct stat filestats;
    59   if ( stat( kBankFilename.c_str(), &filestats ) || difftime(time(0), filestats.st_mtime) > 7.0 * 24.0 * 60.0 * 60.0 )
    60     post(
"T=1&S=*&R=1&O=0&TEST=0", 
"http://moneycentral.msn.com/money/2005/mnynet/service/ols/filist.aspx?SKU=3&VER=6", kBankFilename);
    61   if ( stat( kCcFilename.c_str(), &filestats ) || difftime(time(0), filestats.st_mtime) > 7.0 * 24.0 * 60.0 * 60.0 )
    62     post(
"T=2&S=*&R=1&O=0&TEST=0", 
"http://moneycentral.msn.com/money/2005/mnynet/service/ols/filist.aspx?SKU=3&VER=6", kCcFilename);
    63   if ( stat( kInvFilename.c_str(), &filestats ) || difftime(time(0), filestats.st_mtime) > 7.0 * 24.0 * 60.0 * 60.0 )
    64     post(
"T=3&S=*&R=1&O=0&TEST=0", 
"http://moneycentral.msn.com/money/2005/mnynet/service/ols/filist.aspx?SKU=3&VER=6", kInvFilename);
    67 vector<string> BankNames(
void)
    69   vector<string> result;
    74   xmlpp::DomParser parser;
    75   parser.set_substitute_entities();
    76   parser.parse_file(kBankFilename);
    79     vector<string> names = 
NodeParser(parser).Path(
"fi/prov/name").Text();
    80     result.insert(result.end(), names.begin(), names.end());
    82   parser.parse_file(kCcFilename);
    85     vector<string> names = 
NodeParser(parser).Path(
"fi/prov/name").Text();
    86     result.insert(result.end(), names.begin(), names.end());
    88   parser.parse_file(kInvFilename);
    91     vector<string> names = 
NodeParser(parser).Path(
"fi/prov/name").Text();
    92     result.insert(result.end(), names.begin(), names.end());
    96   result.push_back(
"Innovision");
    99   sort(result.begin(), result.end());
   100   result.erase(unique(result.begin(), result.end()), result.end());
   104 vector<string> FipidForBank(
const string& bank)
   106   vector<string> result;
   108   xmlpp::DomParser parser;
   109   parser.set_substitute_entities();
   110   parser.parse_file(kBankFilename);
   113     vector<string> fipids = 
NodeParser(parser).Path(
"fi/prov").Select(
"name", bank).Path(
"guid").Text();
   114     if ( ! fipids.back().empty() )
   115       result.insert(result.end(), fipids.begin(), fipids.end());
   117   parser.parse_file(kCcFilename);
   120     vector<string> fipids = 
NodeParser(parser).Path(
"fi/prov").Select(
"name", bank).Path(
"guid").Text();
   121     if ( ! fipids.back().empty() )
   122       result.insert(result.end(), fipids.begin(), fipids.end());
   124   parser.parse_file(kInvFilename);
   127     vector<string> fipids = 
NodeParser(parser).Path(
"fi/prov").Select(
"name", bank).Path(
"guid").Text();
   128     if ( ! fipids.back().empty() )
   129       result.insert(result.end(), fipids.begin(), fipids.end());
   133   if ( bank == 
"Innovision" )
   134     result.push_back(
"1");
   136   sort(result.begin(), result.end());
   137   result.erase(unique(result.begin(), result.end()), result.end());
   150     strncpy(result.fid, 
"00000", OFX_FID_LENGTH - 1);
   151     strncpy(result.org, 
"ReferenceFI", OFX_ORG_LENGTH - 1);
   152     strncpy(result.url, 
"http://ofx.innovision.com", OFX_URL_LENGTH - 1);
   161   string url = 
"http://moneycentral.msn.com/money/2005/mnynet/service/olsvcupd/OnlSvcBrandInfo.aspx?MSNGUID=&GUID=%1&SKU=3&VER=6";
   162   url.replace(url.find(
"%1"), 2, fipid);
   165   string guidfile = 
"fipid-%1.xml";
   166   guidfile.replace(guidfile.find(
"%1"), 2, fipid);
   168   struct stat filestats;
   169   if ( stat( guidfile.c_str(), &filestats ) || difftime(time(0), filestats.st_mtime) > 7.0 * 24.0 * 60.0 * 60.0 )
   170     post(
"", url.c_str(), guidfile.c_str());
   173   xmlpp::DomParser parser;
   174   parser.set_substitute_entities();
   175   parser.parse_file(guidfile);
   180     strncpy(result.fid, nodes.Path(
"ProviderSettings/FID").Text().back().c_str(), OFX_FID_LENGTH - 1);
   181     strncpy(result.org, nodes.Path(
"ProviderSettings/Org").Text().back().c_str(), OFX_ORG_LENGTH - 1);
   182     strncpy(result.url, nodes.Path(
"ProviderSettings/ProviderURL").Text().back().c_str(), OFX_URL_LENGTH - 1);
   183     result.
accountlist = (nodes.Path(
"ProviderSettings/AcctListAvail").Text().back() == 
"1");
   184     result.
statements = (nodes.Path(
"BankingCapabilities/Bank").Text().back() == 
"1");
   185     result.
billpay = (nodes.Path(
"BillPayCapabilities/Pay").Text().back() == 
"1");
   186     result.
investments = (nodes.Path(
"InvestmentCapabilities/BrkStmt").Text().back() == 
"1");
   191 bool post(
const string& request, 
const string& url, 
const string& filename)
   193 #if 1 //#ifdef HAVE_LIBCURL   194   CURL *curl = curl_easy_init();
   198   remove(filename.c_str());
   199   FILE* file = fopen(filename.c_str(), 
"wb");
   202     curl_easy_cleanup(curl);
   206   curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
   207   if ( request.length() )
   208     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.c_str());
   209   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
   210   curl_easy_setopt(curl, CURLOPT_WRITEDATA, (
void *)file);
   213   curl_easy_perform(curl);
   215   curl_easy_cleanup(curl);
   224   cerr << 
"ERROR: libox must be configured with libcurl to post this request" << endl;
 
Methods for connecting to the OFX partner server to retrieve OFX server information. 
Information returned by the OFX Partner Server about a financial institution. 
Declaration of nodeparser object, which facilitiates searching for nodes in an XML file using a notat...