initial cut at adding http proxy support
[gregoa/bti.git] / bti.c
diff --git a/bti.c b/bti.c
index 1c5a856..f3fc64c 100644 (file)
--- a/bti.c
+++ b/bti.c
 
 static int debug = 0;
 
+enum host {
+       HOST_TWITTER = 0,
+       HOST_IDENTICA = 1,
+};
+
 struct session {
        char *password;
        char *account;
        char *tweet;
-       int quiet;
+       char *proxy;
+       int bash;
+       enum host host;
 };
 
 struct bti_curl_buffer {
@@ -61,22 +68,29 @@ static void display_help(void)
        fprintf(stdout, "options are:\n");
        fprintf(stdout, "  --account accountname\n");
        fprintf(stdout, "  --password password\n");
+       fprintf(stdout, "  --proxy PROXY:PORT\n");
+       fprintf(stdout, "  --host HOST\n");
        fprintf(stdout, "  --bash\n");
-       fprintf(stdout, "  --quiet\n");
        fprintf(stdout, "  --debug\n");
+       fprintf(stdout, "  --version\n");
        fprintf(stdout, "  --help\n");
 }
 
+static void display_version(void)
+{
+       fprintf(stdout, "bti - version %s\n", BTI_VERSION);
+}
+
 static char *get_string_from_stdin(void)
 {
        char *temp;
        char *string;
 
-       string = zalloc(100);
+       string = zalloc(1000);
        if (!string)
                return NULL;
 
-       if (!fgets(string, 99, stdin))
+       if (!fgets(string, 999, stdin))
                return NULL;
        temp = strchr(string, '\n');
        *temp = '\0';
@@ -100,6 +114,7 @@ static void session_free(struct session *session)
        free(session->password);
        free(session->account);
        free(session->tweet);
+       free(session->proxy);
        free(session);
 }
 
@@ -131,6 +146,7 @@ static void bti_curl_buffer_free(struct bti_curl_buffer *buffer)
 }
 
 static const char *twitter_url = "https://twitter.com/statuses/update.xml";
+static const char *identica_url = "http://identi.ca/api/statuses/update.xml";
 
 static CURL *curl_init(void)
 {
@@ -181,6 +197,7 @@ static int send_tweet(struct session *session)
        CURLcode res;
        struct curl_httppost *formpost = NULL;
        struct curl_httppost *lastptr = NULL;
+       struct curl_slist *slist = NULL;
 
        if (!session)
                return -EINVAL;
@@ -203,19 +220,38 @@ static int send_tweet(struct session *session)
                     CURLFORM_END);
 
        curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
-       curl_easy_setopt(curl, CURLOPT_URL, twitter_url);
+
+       switch (session->host) {
+       case HOST_TWITTER:
+               curl_easy_setopt(curl, CURLOPT_URL, twitter_url);
+               /*
+                * twitter doesn't like the "Expect: 100-continue" header
+                * anymore, so turn it off.
+                */
+               slist = curl_slist_append(slist, "Expect:");
+               curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
+               break;
+       case HOST_IDENTICA:
+               curl_easy_setopt(curl, CURLOPT_URL, identica_url);
+               break;
+       }
+
+       if (session->proxy)
+               curl_easy_setopt(curl, CURLOPT_PROXY, session->proxy);
+
        if (debug)
                curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
        curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
 
        dbg("user_password = %s\n", user_password);
        dbg("data = %s\n", data);
+       dbg("proxy = %s\n", session->proxy);
 
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl_buf);
        res = curl_easy_perform(curl);
-       if (res) {
-               printf("error(%d) trying to send tweet\n", res);
+       if (res && !session->bash) {
+               fprintf(stderr, "error(%d) trying to send tweet\n", res);
                return -EINVAL;
        }
 
@@ -232,6 +268,8 @@ static void parse_configfile(struct session *session)
        size_t len = 0;
        char *account = NULL;
        char *password = NULL;
+       char *host = NULL;
+       char *proxy = NULL;
        char *file;
        char *home = getenv("HOME");
 
@@ -274,13 +312,32 @@ static void parse_configfile(struct session *session)
                        c += 9;
                        if (c[0] != '\0')
                                password = strdup(c);
+               } else if (!strncasecmp(c, "host", 4) &&
+                          (c[4] == '=')) {
+                       c += 5;
+                       if (c[0] != '\0')
+                               host = strdup(c);
+               } else if (!strncasecmp(c, "proxy", 5) &&
+                          (c[5] == '=')) {
+                       c += 6;
+                       if (c[0] != '\0')
+                               proxy = strdup(c);
                }
        } while (!feof(config_file));
 
        if (password)
                session->password = password;
        if (account)
-               session->account= account;
+               session->account = account;
+       if (host) {
+               if (strcasecmp(host, "twitter") == 0)
+                       session->host = HOST_TWITTER;
+               if (strcasecmp(host, "identica") == 0)
+                       session->host = HOST_IDENTICA;
+               free(host);
+       }
+       if (proxy)
+               session->proxy = proxy;
 
        /* Free buffer and close file.  */
        free(line);
@@ -293,9 +350,10 @@ int main(int argc, char *argv[], char *envp[])
                { "debug", 0, NULL, 'd' },
                { "account", 1, NULL, 'a' },
                { "password", 1, NULL, 'p' },
-               { "bash", 1, NULL, 'b' },
+               { "host", 1, NULL, 'H' },
                { "help", 0, NULL, 'h' },
-               { "quiet", 0, NULL, 'q' },
+               { "bash", 0, NULL, 'b' },
+               { "version", 0, NULL, 'v' },
                { }
        };
        struct session *session;
@@ -303,10 +361,11 @@ int main(int argc, char *argv[], char *envp[])
        char *tweet;
        int retval;
        int option;
+#if 0
        char *home = getenv("HOME");
        char *pwd = getenv("PWD");
        char *dir;
-
+#endif
        session = session_alloc();
        if (!session) {
                fprintf(stderr, "no more memory...\n");
@@ -317,7 +376,7 @@ int main(int argc, char *argv[], char *envp[])
        parse_configfile(session);
 
        while (1) {
-               option = getopt_long_only(argc, argv, "dqe:p:a:h",
+               option = getopt_long_only(argc, argv, "dqe:p:H:a:h",
                                          options, NULL);
                if (option == -1)
                        break;
@@ -337,12 +396,22 @@ int main(int argc, char *argv[], char *envp[])
                        session->password = strdup(optarg);
                        dbg("password = %s\n", session->password);
                        break;
-               case 'q':
-                       session->quiet = 1;
+               case 'H':
+                       if (strcasecmp(optarg, "twitter") == 0)
+                               session->host = HOST_TWITTER;
+                       if (strcasecmp(optarg, "identica") == 0)
+                               session->host = HOST_IDENTICA;
+                       dbg("host = %d\n", session->host);
+                       break;
+               case 'b':
+                       session->bash= 1;
                        break;
                case 'h':
                        display_help();
                        goto exit;
+               case 'v':
+                       display_version();
+                       goto exit;
                default:
                        display_help();
                        goto exit;
@@ -358,7 +427,8 @@ int main(int argc, char *argv[], char *envp[])
                fprintf(stdout, "Enter twitter password: ");
                session->password = get_string_from_stdin();
        }
-
+#if 0
+       /* get the current working directory basename */
        if (strcmp(pwd, home) == 0)
                dir = "~";
        else {
@@ -368,34 +438,43 @@ int main(int argc, char *argv[], char *envp[])
                else
                        dir = "?";
        }
-
-       /* Add the "PWD $ " to the start of the tweet to show it is
-        * coming from a shell */
+#endif
        tweet = get_string_from_stdin();
-       session->tweet = zalloc(strlen(tweet) + strlen(dir) + 10);
-       sprintf(session->tweet, "%s $ %s", dir, tweet);
-       free(tweet);
-
-       if (strlen(session->tweet) == 0) {
+       if (!tweet || strlen(tweet) == 0) {
                dbg("no tweet?\n");
                return -1;
        }
 
+//     session->tweet = zalloc(strlen(tweet) + strlen(dir) + 10);
+       session->tweet = zalloc(strlen(tweet) + 10);
+
+       /* if --bash is specified, add the "PWD $ " to
+        * the start of the tweet. */
+       if (session->bash)
+//             sprintf(session->tweet, "%s $ %s", dir, tweet);
+               sprintf(session->tweet, "$ %s", tweet);
+       else
+               sprintf(session->tweet, "%s", tweet);
+       free(tweet);
+
        dbg("account = %s\n", session->account);
        dbg("password = %s\n", session->password);
        dbg("tweet = %s\n", session->tweet);
+       dbg("host = %d\n", session->host);
 
        /* fork ourself so that the main shell can get on
         * with it's life as we try to connect and handle everything
         */
-       child = fork();
-       if (child) {
-               dbg("child is %d\n", child);
-               exit(0);
+       if (session->bash) {
+               child = fork();
+                       if (child) {
+                       dbg("child is %d\n", child);
+                       exit(0);
+               }
        }
 
        retval = send_tweet(session);
-       if (retval) {
+       if (retval && !session->bash) {
                fprintf(stderr, "tweet failed\n");
                return -1;
        }