#include #include #include #include #include #include #define ERRBUFSIZE 1024 char store[] = "./"; char certificatepath[] = "./cert2.pem"; char passphraseval[] = "password"; char pageurl[] = "https://NN.XXX.com/Upload.asp?Id=[345]"; struct xml_rec { unsigned long batchno; char errbuf[ERRBUFSIZE]; char filename[64]; }; int saveXML(struct xml_rec *xmlrec) { FILE *fp; time_t timenow = time(NULL); struct tm *timestruct; char *filepath; char filenameandpath[256]; char datestring[11]; // first get the file path for saved files filepath = store; if (filepath == NULL) { return (-1); } // now format the filename for this xml. Format is batch_no-YYYYMMDDSS // first get the time timestruct = localtime(&timenow); strftime(datestring, sizeof(datestring), "%Y%m%d%S", timestruct); // now put the filename into the structure snprintf(xmlrec->filename, 64, "%lu-%s.xml", xmlrec->batchno, datestring); snprintf(filenameandpath, sizeof(filenameandpath), "%s/%s", filepath, xmlrec->filename); // now open a file for writing fp = fopen(filenameandpath, "w"); if (!fp) { printf("Could not write XML file [%s]. %s. Aborting\n", strerror(errno), filenameandpath); return (-1); } // opened the file for writing, now put the xml text into it fprintf(fp, "%s\n", xmlstring); fclose(fp); return (0); } /* * writeResponse * * This is the libcurl function handler for text replies to the POSTing of data. Data * is sent to this function and written to the specified file * * The size of data pointed to by ptr is (size X nmemb). N.B. It will NOT be Null terminated * */ size_t writeResponse(void *ptr, size_t size, size_t nmemb, void *stream) { int written = 0; written = fwrite(ptr, size, nmemb, (FILE *)stream); return (written); } int sendToSite(struct xml_rec *xmlrec) { CURL *curl; const char *keyType = "PEM"; FILE *responsefile; FILE *headerfile; char *certificate; char *passphrase; char *url; char filenameandpath[256] = "\0"; char rspfilenameandpath[256] = "\0"; char hdrfilenameandpath[256] = "\0"; char curlerrbuf[CURL_ERROR_SIZE]; struct HttpPost *formpost=NULL; struct HttpPost *lastptr=NULL; CURLcode res; // get the path of the certificate certificate = certificatepath; if (certificate == NULL) { printf("No cretificate\n"); return (-1); } // get the passphrase passphrase = passphraseval; if (passphrase == NULL) { printf("No passphrase\n"); return (-1); } // get the upload url url = pageurl; if (url == NULL) { printf("No URL\n"); return (-1); } // before doing the curl stuff, we save a copy of the XML in a file if (saveXML(xmlrec) != 0) { return (-1); } // now generate the filename snprintf(filenameandpath, sizeof(filenameandpath), "%s/%s", store, xmlrec->filename ); // now set the response file name, same filename as before with .rsp tagged on snprintf(rspfilenameandpath, sizeof(rspfilenameandpath), "%s.rsp", filenameandpath); // now open the response file for writing responsefile = fopen(rspfilenameandpath, "w"); if (responsefile == NULL) { printf("Could not write XML response file [%s]. %s. Aborting", strerror(errno), rspfilenameandpath); return (-1); } // now set the response file name, same filename as before with .rsp tagged on snprintf(hdrfilenameandpath, sizeof(rspfilenameandpath), "%s.hdr", filenameandpath); // now open a header file headerfile = fopen(hdrfilenameandpath, "w"); if (responsefile == NULL) { printf("Could not write XML header file [%s]. %s. Aborting", strerror(errno), hdrfilenameandpath); return (-1); } // now start to setup curl res = curl_global_init(CURL_GLOBAL_DEFAULT); if (res != CURLE_OK) { printf("Could not curl_global_init(%d) [%s]", res, curlerrbuf); return (-1); } /* fill in the form data */ res = curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "File1", CURLFORM_COPYCONTENTS, filenameandpath, CURLFORM_END); if (res != CURLE_OK) { printf("Could not formadd File1(%d) [%s]", res, curlerrbuf); return (-1); } /* fill in the submit field too, even if this is rarely needed */ res = curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "Action", CURLFORM_COPYCONTENTS, "Upload the File", CURLFORM_END); if (res != CURLE_OK) { printf("Could not formadd Action(%d) [%s]", res, curlerrbuf); return (-1); } curl = curl_easy_init(); if (curl) { res = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); // register with curl an errorbuffer res = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curlerrbuf); if (res != CURLE_OK) { printf("Could not set ERRORBUFFER(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // dont want a progress meter res = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); if (res != CURLE_OK) { printf("Could not set NOPROGRESS(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // send all the data we receive to this function res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeResponse); if (res != CURLE_OK) { printf("Could not set WRITEFUNCTION(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // certificate is PEM format res = curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, keyType); if (res != CURLE_OK) { printf("Could not set SSLCERTTYPE(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // set the certificate file res = curl_easy_setopt(curl, CURLOPT_SSLCERT, certificate); if (res != CURLE_OK) { printf("Could not set SSLCERT(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // and the certificate has a passphrase res = curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, passphrase); if (res != CURLE_OK) { printf("Could not set SSLCERTPASSWD(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // set the url we are posting to res = curl_easy_setopt(curl, CURLOPT_URL, url); if (res != CURLE_OK) { printf("Could not set URL(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // set the file that we want to write the return data to res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, responsefile); if (res != CURLE_OK) { printf("Could not set WRITEDATA(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // set the file for the header res = curl_easy_setopt(curl, CURLOPT_WRITEHEADER, headerfile); if (res != CURLE_OK) { printf("Could not set WRITEHEADER(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // set that we want a multipart/formdata POST using our formpost linked list res = curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); if (res != CURLE_OK) { printf("Could not set HTTPPOST(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // do the post! res = curl_easy_perform(curl); if (res != CURLE_OK) { printf("Could not do curl_easy_perform(%d) [%s]", res, curlerrbuf); curl_easy_cleanup(curl); curl_formfree(formpost); curl_global_cleanup(); return (-1); } // cleanup curl_easy_cleanup(curl); // empty the formpost linked list curl_formfree(formpost); } else { // could not get a curl handle printf("Could not get curl handle [%s]", curlerrbuf); return (-1); } curl_global_cleanup(); return (0); } int main() { struct xml_rec xmlrec; int ret; xmlrec.batchno = 3456; sprintf(xmlstring, "THIS IS JUST\n A TEST"); ret = sendToSite(&xmlrec); if (ret == 0) { printf("OK\n"); } else { printf("\n%s\n", xmlrec.errbuf); } return 0; }