Index: Makefile
===================================================================
--- Makefile	(revision 1769)
+++ Makefile	(working copy)
@@ -77,6 +77,8 @@
 STRIP_ARGS = -s
 endif
 
+LIBS += -lcurl
+
 # Determine the destination OS.
 # IMPORTANT: The following line must be placed before TARGET_OS is ever used
 # (of course), but should come after any lines setting CC because the line
Index: cli_classic.c
===================================================================
--- cli_classic.c	(revision 1769)
+++ cli_classic.c	(working copy)
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <getopt.h>
+#include <curl/curl.h>
 #include "flash.h"
 #include "flashchips.h"
 #include "programmer.h"
@@ -42,7 +43,7 @@
 #endif
 	       "-p <programmername>[:<parameters>] [-c <chipname>]\n"
 	       "[-E|(-r|-w|-v) <file>] [-l <layoutfile> [-i <imagename>]...] [-n] [-f]]\n"
-	       "[-V[V[V]]] [-o <logfile>]\n\n", name);
+	       "[-V[V[V]]] [-o <logfile> [-u]]\n\n", name);
 
 	printf(" -h | --help                        print this help text\n"
 	       " -R | --version                     print version (release)\n"
@@ -61,7 +62,8 @@
 #if CONFIG_PRINT_WIKI == 1
 	       " -z | --list-supported-wiki         print supported devices in wiki syntax\n"
 #endif
-	       " -p | --programmer <name>[:<param>] specify the programmer device. One of\n");
+	       " -p | --programmer <name>[:<param>] specify the programmer device. One of\n"
+	       " -u | --upload                      auto-upload program output to pastebin\n");
 	list_programmers_linebreak(4, 80, 0);
 	printf(".\n\nYou can specify one of -h, -R, -L, "
 #if CONFIG_PRINT_WIKI == 1
@@ -104,10 +106,11 @@
 #endif
 	int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
 	int dont_verify_it = 0, list_supported = 0, operation_specified = 0;
+	int upload_log = 0;
 	enum programmer prog = PROGRAMMER_INVALID;
 	int ret = 0;
 
-	static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzho:";
+	static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzho:u";
 	static const struct option long_options[] = {
 		{"read",		1, NULL, 'r'},
 		{"write",		1, NULL, 'w'},
@@ -125,6 +128,7 @@
 		{"help",		0, NULL, 'h'},
 		{"version",		0, NULL, 'R'},
 		{"output",		1, NULL, 'o'},
+        {"upload",		0, NULL, 'u'},
 		{NULL,			0, NULL, 0},
 	};
 
@@ -316,6 +320,9 @@
 			}
 #endif /* STANDALONE */
 			break;
+		case 'u':
+			upload_log = 1;
+			break;
 		default:
 			cli_classic_abort_usage();
 			break;
@@ -334,10 +341,16 @@
 		cli_classic_abort_usage();
 	}
 
+	if (upload_log && !logfile)
+	{
+		fprintf(stderr, "Log file must be created (-o) for pastebin upload.\n");
+		cli_classic_abort_usage();
+	}
+
 #ifndef STANDALONE
 	if (logfile && check_filename(logfile, "log"))
 		cli_classic_abort_usage();
-	if (logfile && open_logfile(logfile))
+	if (logfile && open_logfile(logfile, upload_log))
 		return 1;
 	free(logfile);
 #endif /* !STANDALONE */
@@ -539,7 +552,7 @@
 	free((char *)chip_to_probe); /* Silence! Freeing is not modifying contents. */
 	chip_to_probe = NULL;
 #ifndef STANDALONE
-	ret |= close_logfile();
+	ret |= close_logfile(upload_log);
 #endif /* !STANDALONE */
 	return ret;
 }
Index: cli_output.c
===================================================================
--- cli_output.c	(revision 1769)
+++ cli_output.c	(working copy)
@@ -23,27 +23,145 @@
 #include <stdarg.h>
 #include <string.h>
 #include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <curl/curl.h>
 #include "flash.h"
 
 #ifndef STANDALONE
+static char *fname = NULL;
 static FILE *logfile = NULL;
+#define FLASHROM_PASTE_URL "http://paste.flashrom.org/"
 
-int close_logfile(void)
+struct memstruct {
+	char *memory;
+	size_t size;
+};
+
+static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp)
 {
+	size_t realsize = size * nmemb;
+	struct memstruct *mem = (struct memstruct *)userp;
+
+	mem->memory = realloc(mem->memory, mem->size + realsize + 1);
+	if (mem->memory == NULL) {
+		msg_gerr("realloc() failed in curl write callback: %s", strerror(errno));
+		return 0;
+	}
+
+	memcpy(&(mem->memory[mem->size]), contents, realsize);
+	mem->size += realsize;
+	mem->memory[mem->size] = 0;
+
+	return realsize;
+}
+
+int close_logfile(int upload_log)
+{
 	if (!logfile)
 		return 0;
 	/* No need to call fflush() explicitly, fclose() already does that. */
 	if (fclose(logfile)) {
 		/* fclose returned an error. Stop writing to be safe. */
 		logfile = NULL;
-		msg_perr("Closing the log file returned error %s\n", strerror(errno));
+		msg_gerr("Closing the log file returned error %s\n", strerror(errno));
 		return 1;
 	}
 	logfile = NULL;
+
+	if (upload_log) {
+		char username[33];
+		CURL *curl;
+		static CURLcode res;
+		struct curl_httppost *formpost = NULL;
+		struct curl_httppost *lastptr = NULL;
+
+		msg_ginfo("Uploading log file, please wait...\n");
+
+		/* Grab the current username as the nick */
+		if ( getlogin_r(username, 33) != 0 )
+			strcpy(username, "flashrom user");
+
+		curl_global_init(CURL_GLOBAL_ALL);
+
+		curl_formadd(&formpost,
+					 &lastptr,
+					 CURLFORM_COPYNAME, "pasta",
+					 CURLFORM_FILECONTENT, fname,
+					 CURLFORM_END);
+
+		curl_formadd(&formpost,
+					 &lastptr,
+					 CURLFORM_COPYNAME, "nick",
+					 CURLFORM_COPYCONTENTS, username,
+					 CURLFORM_END);
+
+		curl = curl_easy_init();
+		if (curl) {
+			struct memstruct chunk;
+			char *str1, *str2, *str3, *url;
+			int url_size = 0;
+
+			chunk.memory = malloc(1);
+			chunk.size = 0;
+
+			if (chunk.memory == NULL) {
+				msg_gerr("Failed to allocate initial buf for curl write callback: %s\n", strerror(errno));
+				return 1;
+			}
+
+			curl_easy_setopt(curl, CURLOPT_URL, FLASHROM_PASTE_URL);
+			curl_easy_setopt(curl, CURLOPT_POST, 1);
+			curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
+			curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
+			curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk);
+
+			res = curl_easy_perform(curl);
+			if (res != CURLE_OK)
+			{
+				fprintf(stderr, "Failed to upload program log to %s: %s\n", FLASHROM_PASTE_URL, curl_easy_strerror(res));
+				return 1;
+			}
+
+			curl_easy_cleanup(curl);
+
+			curl_formfree(formpost);
+
+			/* Parse HTML output to grab paste URL */
+
+			str1 = strstr(chunk.memory, "Your paste can be seen at ");
+			if (str1) {
+				str2 = strstr(str1, "\">");
+				if (str2) {
+					str2 += 2; // skip past ">
+					str3 = strstr(str2, "</a><br>");
+					if (str3) {
+						url_size = (unsigned long)str3 - (unsigned long)str2;
+					}
+				}
+			}
+
+			if (url_size) {
+				url = malloc(url_size + 1);
+				if (url == NULL) {
+					msg_gerr("Failed to allocate URL string: %s\n", strerror(errno));
+					return 1;
+				}
+
+				memcpy(url, str2, url_size);
+				url[url_size] = 0;
+
+				msg_ginfo("Uploaded program log to: %s\n", url);
+			} else {
+				msg_gerr("Failed to find uploaded paste ID, please check the site manually: %s\n", FLASHROM_PASTE_URL);
+			}
+		}
+	}
+
 	return 0;
 }
 
-int open_logfile(const char * const filename)
+int open_logfile(const char * const filename, int upload_log)
 {
 	if (!filename) {
 		msg_gerr("No logfile name specified.\n");
@@ -53,6 +171,16 @@
 		msg_gerr("Error: opening log file \"%s\" failed: %s\n", filename, strerror(errno));
 		return 1;
 	}
+
+	if (upload_log) {
+		fname = strdup(filename);
+		if (fname == NULL)
+		{
+			msg_gerr("strdup() failed to allocate fname string: %s", strerror(errno));
+			return 1;
+		}
+	}
+
 	return 0;
 }
 
Index: flash.h
===================================================================
--- flash.h	(revision 1769)
+++ flash.h	(working copy)
@@ -285,8 +285,8 @@
 
 /* cli_output.c */
 #ifndef STANDALONE
-int open_logfile(const char * const filename);
-int close_logfile(void);
+int open_logfile(const char * const filename, int upload_log);
+int close_logfile(int upload_log);
 void start_logging(void);
 #endif
 enum msglevel {
