]> ToastFreeware Gitweb - gregoa/bti.git/blobdiff - bti.c
Support for replying to notices
[gregoa/bti.git] / bti.c
diff --git a/bti.c b/bti.c
index 285fdfadc7471063a1d6bfd7a2135c47edefb065..ae32c377d89d97f6398d8c434ef9aa0f12cbd3da 100644 (file)
--- a/bti.c
+++ b/bti.c
@@ -82,7 +82,10 @@ struct session {
        char *group;
        char *hosturl;
        char *hostname;
        char *group;
        char *hosturl;
        char *hostname;
+       char *configfile;
+       char *replyto;
        int bash;
        int bash;
+       int interactive;
        int shrink_urls;
        int dry_run;
        int page;
        int shrink_urls;
        int dry_run;
        int page;
@@ -115,6 +118,8 @@ static void display_help(void)
        fprintf(stdout, "  --proxy PROXY:PORT\n");
        fprintf(stdout, "  --host HOST\n");
        fprintf(stdout, "  --logfile logfile\n");
        fprintf(stdout, "  --proxy PROXY:PORT\n");
        fprintf(stdout, "  --host HOST\n");
        fprintf(stdout, "  --logfile logfile\n");
+       fprintf(stdout, "  --config configfile\n");
+       fprintf(stdout, "  --replyto ID\n");
        fprintf(stdout, "  --shrink-urls\n");
        fprintf(stdout, "  --page PAGENUMBER\n");
        fprintf(stdout, "  --bash\n");
        fprintf(stdout, "  --shrink-urls\n");
        fprintf(stdout, "  --page PAGENUMBER\n");
        fprintf(stdout, "  --bash\n");
@@ -143,7 +148,8 @@ static char *get_string(const char *name)
        if (!fgets(string, 999, stdin))
                return NULL;
        temp = strchr(string, '\n');
        if (!fgets(string, 999, stdin))
                return NULL;
        temp = strchr(string, '\n');
-       *temp = '\0';
+       if (temp)
+               *temp = '\0';
        return string;
 }
 
        return string;
 }
 
@@ -172,8 +178,11 @@ static void session_readline_init(struct session *session)
        int (*bind_key)(int, void *);
        void (*insert)(void);
 
        int (*bind_key)(int, void *);
        void (*insert)(void);
 
-       /* default to internal function if we can't find anything */
+       /* default to internal function if we can't or won't find anything */
        session->readline = get_string;
        session->readline = get_string;
+       if (!isatty(0))
+               return;
+       session->interactive = 1;
 
        tmp = malloc(strlen(libpath)+1);
        if (!tmp)
 
        tmp = malloc(strlen(libpath)+1);
        if (!tmp)
@@ -185,7 +194,8 @@ static void session_readline_init(struct session *session)
                        *next++ = 0;
                if (*cp == 0)
                        continue;
                        *next++ = 0;
                if (*cp == 0)
                        continue;
-               if ((handle = dlopen(cp, RTLD_NOW))) {
+               handle = dlopen(cp, RTLD_NOW);
+               if (handle) {
                        dbg("Using %s for readline library\n", cp);
                        break;
                }
                        dbg("Using %s for readline library\n", cp);
                        break;
                }
@@ -228,7 +238,6 @@ static struct session *session_alloc(void)
        session = zalloc(sizeof(*session));
        if (!session)
                return NULL;
        session = zalloc(sizeof(*session));
        if (!session)
                return NULL;
-       session_readline_init(session);
        return session;
 }
 
        return session;
 }
 
@@ -236,7 +245,7 @@ static void session_free(struct session *session)
 {
        if (!session)
                return;
 {
        if (!session)
                return;
-       session_readline_cleanup(session);
+       free(session->replyto);
        free(session->password);
        free(session->account);
        free(session->tweet);
        free(session->password);
        free(session->account);
        free(session->tweet);
@@ -247,6 +256,7 @@ static void session_free(struct session *session)
        free(session->group);
        free(session->hosturl);
        free(session->hostname);
        free(session->group);
        free(session->hosturl);
        free(session->hostname);
+       free(session->configfile);
        free(session);
 }
 
        free(session);
 }
 
@@ -310,6 +320,7 @@ static void parse_statuses(xmlDocPtr doc, xmlNodePtr current)
        xmlChar *text = NULL;
        xmlChar *user = NULL;
        xmlChar *created = NULL;
        xmlChar *text = NULL;
        xmlChar *user = NULL;
        xmlChar *created = NULL;
+       xmlChar *id = NULL;
        xmlNodePtr userinfo;
 
        current = current->xmlChildrenNode;
        xmlNodePtr userinfo;
 
        current = current->xmlChildrenNode;
@@ -319,6 +330,8 @@ static void parse_statuses(xmlDocPtr doc, xmlNodePtr current)
                                created = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
                        if (!xmlStrcmp(current->name, (const xmlChar *)"text"))
                                text = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
                                created = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
                        if (!xmlStrcmp(current->name, (const xmlChar *)"text"))
                                text = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
+                       if (!xmlStrcmp(current->name, (const xmlChar *)"id"))
+                               id = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
                        if (!xmlStrcmp(current->name, (const xmlChar *)"user")) {
                                userinfo = current->xmlChildrenNode;
                                while (userinfo != NULL) {
                        if (!xmlStrcmp(current->name, (const xmlChar *)"user")) {
                                userinfo = current->xmlChildrenNode;
                                while (userinfo != NULL) {
@@ -331,19 +344,21 @@ static void parse_statuses(xmlDocPtr doc, xmlNodePtr current)
                                }
                        }
 
                                }
                        }
 
-                       if (user && text && created) {
+                       if (user && text && created && id) {
                                if (verbose)
                                if (verbose)
-                                       printf("[%s] (%.16s) %s\n",
-                                               user, created, text);
+                                       printf("[%s] {%s} (%.16s) %s\n",
+                                               user, id, created, text);
                                else
                                        printf("[%s] %s\n",
                                                user, text);
                                xmlFree(user);
                                xmlFree(text);
                                xmlFree(created);
                                else
                                        printf("[%s] %s\n",
                                                user, text);
                                xmlFree(user);
                                xmlFree(text);
                                xmlFree(created);
+                               xmlFree(id);
                                user = NULL;
                                text = NULL;
                                created = NULL;
                                user = NULL;
                                text = NULL;
                                created = NULL;
+                               id = NULL;
                        }
                }
                current = current->next;
                        }
                }
                current = current->next;
@@ -455,6 +470,12 @@ static int send_request(struct session *session)
                             CURLFORM_COPYCONTENTS, "bti",
                             CURLFORM_END);
 
                             CURLFORM_COPYCONTENTS, "bti",
                             CURLFORM_END);
 
+               if (session->replyto)
+                       curl_formadd(&formpost, &lastptr,
+                                    CURLFORM_COPYNAME, "in_reply_to_status_id",
+                                    CURLFORM_COPYCONTENTS, session->replyto,
+                                    CURLFORM_END);
+
                curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
                slist = curl_slist_append(slist, "Expect:");
                curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
                curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
                slist = curl_slist_append(slist, "Expect:");
                curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
@@ -547,12 +568,7 @@ static void parse_configfile(struct session *session)
        char *file;
        int shrink_urls = 0;
 
        char *file;
        int shrink_urls = 0;
 
-       /* config file is ~/.bti  */
-       file = alloca(strlen(session->homedir) + 7);
-
-       sprintf(file, "%s/.bti", session->homedir);
-
-       config_file = fopen(file, "r");
+       config_file = fopen(session->configfile, "r");
 
        /* No error if file does not exist or is unreadable.  */
        if (config_file == NULL)
 
        /* No error if file does not exist or is unreadable.  */
        if (config_file == NULL)
@@ -704,7 +720,8 @@ static void log_session(struct session *session, int retval)
                                session->time, session->hostname);
                else
                        fprintf(log_file, "%s: host=%s tweet=%s\n",
                                session->time, session->hostname);
                else
                        fprintf(log_file, "%s: host=%s tweet=%s\n",
-                               session->time, session->hostname, session->tweet);
+                               session->time, session->hostname,
+                               session->tweet);
                break;
        case ACTION_FRIENDS:
                fprintf(log_file, "%s: host=%s retrieving friends timeline\n",
                break;
        case ACTION_FRIENDS:
                fprintf(log_file, "%s: host=%s retrieving friends timeline\n",
@@ -745,7 +762,8 @@ static char *get_string_from_stdin(void)
        if (!fgets(string, 999, stdin))
                return NULL;
        temp = strchr(string, '\n');
        if (!fgets(string, 999, stdin))
                return NULL;
        temp = strchr(string, '\n');
-       *temp = '\0';
+       if (temp)
+               *temp = '\0';
        return string;
 }
 
        return string;
 }
 
@@ -1056,6 +1074,8 @@ int main(int argc, char *argv[], char *envp[])
                { "dry-run", 0, NULL, 'n' },
                { "page", 1, NULL, 'g' },
                { "version", 0, NULL, 'v' },
                { "dry-run", 0, NULL, 'n' },
                { "page", 1, NULL, 'g' },
                { "version", 0, NULL, 'v' },
+               { "config", 1, NULL, 'c' },
+               { "replyto", 1, NULL, 'r' },
                { }
        };
        struct session *session;
                { }
        };
        struct session *session;
@@ -1082,8 +1102,13 @@ int main(int argc, char *argv[], char *envp[])
        session->time = strdup(ctime(&t));
        session->time[strlen(session->time)-1] = 0x00;
 
        session->time = strdup(ctime(&t));
        session->time[strlen(session->time)-1] = 0x00;
 
+       /* Get the home directory so we can try to find a config file */
        session->homedir = strdup(getenv("HOME"));
 
        session->homedir = strdup(getenv("HOME"));
 
+       /* set up a default config file location (traditionally ~/.bti) */
+       session->configfile = zalloc(strlen(session->homedir) + 7);
+       sprintf(session->configfile, "%s/.bti", session->homedir);
+
        curl_global_init(CURL_GLOBAL_ALL);
 
        /* Set environment variables first, before reading command line options
        curl_global_init(CURL_GLOBAL_ALL);
 
        /* Set environment variables first, before reading command line options
@@ -1099,7 +1124,7 @@ int main(int argc, char *argv[], char *envp[])
        parse_configfile(session);
 
        while (1) {
        parse_configfile(session);
 
        while (1) {
-               option = getopt_long_only(argc, argv, "dp:P:H:a:A:u:hg:G:snVv",
+               option = getopt_long_only(argc, argv, "dp:P:H:a:A:u:c:hg:G:sr:nVv",
                                          options, NULL);
                if (option == -1)
                        break;
                                          options, NULL);
                if (option == -1)
                        break;
@@ -1121,6 +1146,10 @@ int main(int argc, char *argv[], char *envp[])
                        dbg("page = %d\n", page_nr);
                        session->page = page_nr;
                        break;
                        dbg("page = %d\n", page_nr);
                        session->page = page_nr;
                        break;
+               case 'r':
+                       session->replyto = strdup(optarg);
+                       dbg("in_reply_to_status_id = %s\n", session->replyto);
+                       break;
                case 'p':
                        if (session->password)
                                free(session->password);
                case 'p':
                        if (session->password)
                                free(session->password);
@@ -1195,6 +1224,18 @@ int main(int argc, char *argv[], char *envp[])
                case 'b':
                        session->bash = 1;
                        break;
                case 'b':
                        session->bash = 1;
                        break;
+               case 'c':
+                       if (session->configfile)
+                               free(session->configfile);
+                       session->configfile = strdup(optarg);
+                       dbg("configfile = %s\n", session->configfile);
+
+                       /*
+                        * read the config file now.  Yes, this could override previously
+                        * set options from the command line, but the user asked for it...
+                        */
+                       parse_configfile(session);
+                       break;
                case 'h':
                        display_help();
                        goto exit;
                case 'h':
                        display_help();
                        goto exit;
@@ -1210,6 +1251,7 @@ int main(int argc, char *argv[], char *envp[])
                }
        }
 
                }
        }
 
+       session_readline_init(session);
        /*
         * Show the version to make it easier to determine what
         * is going on here
        /*
         * Show the version to make it easier to determine what
         * is going on here
@@ -1245,7 +1287,7 @@ int main(int argc, char *argv[], char *envp[])
        }
 
        if (session->action == ACTION_UPDATE) {
        }
 
        if (session->action == ACTION_UPDATE) {
-               if (session->bash)
+               if (session->bash || !session->interactive)
                        tweet = get_string_from_stdin();
                else
                        tweet = session->readline("tweet: ");
                        tweet = get_string_from_stdin();
                else
                        tweet = session->readline("tweet: ");
@@ -1273,6 +1315,7 @@ int main(int argc, char *argv[], char *envp[])
 
        if (session->page == 0)
                session->page = 1;
 
        if (session->page == 0)
                session->page = 1;
+       dbg("config file = %s\n", session->configfile);
        dbg("account = %s\n", session->account);
        dbg("password = %s\n", session->password);
        dbg("host = %d\n", session->host);
        dbg("account = %s\n", session->account);
        dbg("password = %s\n", session->password);
        dbg("host = %d\n", session->host);
@@ -1295,6 +1338,7 @@ int main(int argc, char *argv[], char *envp[])
 
        log_session(session, retval);
 exit:
 
        log_session(session, retval);
 exit:
+       session_readline_cleanup(session);
        session_free(session);
        return retval;;
 }
        session_free(session);
        return retval;;
 }