/[debian]/bti/branches/upstream/current/bti.c
ViewVC logotype

Diff of /bti/branches/upstream/current/bti.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2232 by gregoa, Wed May 19 19:21:49 2010 UTC revision 2233 by gregoa, Wed Aug 18 15:33:14 2010 UTC
# Line 39  Line 39 
39  #include <pcre.h>  #include <pcre.h>
40  #include <termios.h>  #include <termios.h>
41  #include <dlfcn.h>  #include <dlfcn.h>
42    #include <oauth.h>
43    
44    
45  #define zalloc(size)    calloc(size, 1)  #define zalloc(size)    calloc(size, 1)
# Line 73  enum action { Line 74  enum action {
74  struct session {  struct session {
75          char *password;          char *password;
76          char *account;          char *account;
77            char *consumer_key;
78            char *consumer_secret;
79            char *access_token_key;
80            char *access_token_secret;
81          char *tweet;          char *tweet;
82          char *proxy;          char *proxy;
83          char *time;          char *time;
# Line 83  struct session { Line 88  struct session {
88          char *hosturl;          char *hosturl;
89          char *hostname;          char *hostname;
90          char *configfile;          char *configfile;
91            char *replyto;
92          int bash;          int bash;
93          int interactive;          int interactive;
94          int shrink_urls;          int shrink_urls;
95          int dry_run;          int dry_run;
96          int page;          int page;
97            int no_oauth;
98          enum host host;          enum host host;
99          enum action action;          enum action action;
100          void *readline_handle;          void *readline_handle;
# Line 118  static void display_help(void) Line 125  static void display_help(void)
125          fprintf(stdout, "  --host HOST\n");          fprintf(stdout, "  --host HOST\n");
126          fprintf(stdout, "  --logfile logfile\n");          fprintf(stdout, "  --logfile logfile\n");
127          fprintf(stdout, "  --config configfile\n");          fprintf(stdout, "  --config configfile\n");
128            fprintf(stdout, "  --replyto ID\n");
129          fprintf(stdout, "  --shrink-urls\n");          fprintf(stdout, "  --shrink-urls\n");
130          fprintf(stdout, "  --page PAGENUMBER\n");          fprintf(stdout, "  --page PAGENUMBER\n");
131          fprintf(stdout, "  --bash\n");          fprintf(stdout, "  --bash\n");
# Line 243  static void session_free(struct session Line 251  static void session_free(struct session
251  {  {
252          if (!session)          if (!session)
253                  return;                  return;
254            free(session->replyto);
255          free(session->password);          free(session->password);
256          free(session->account);          free(session->account);
257            free(session->consumer_key);
258            free(session->consumer_secret);
259            free(session->access_token_key);
260            free(session->access_token_secret);
261          free(session->tweet);          free(session->tweet);
262          free(session->proxy);          free(session->proxy);
263          free(session->time);          free(session->time);
# Line 285  static void bti_curl_buffer_free(struct Line 298  static void bti_curl_buffer_free(struct
298          free(buffer);          free(buffer);
299  }  }
300    
301  static const char *twitter_host  = "https://twitter.com/statuses";  static const char *twitter_host  = "http://api.twitter.com/1/statuses";
302  static const char *identica_host = "https://identi.ca/api/statuses";  static const char *identica_host = "https://identi.ca/api/statuses";
303  static const char *twitter_name  = "twitter";  static const char *twitter_name  = "twitter";
304  static const char *identica_name = "identi.ca";  static const char *identica_name = "identi.ca";
305    
306  static const char *user_uri    = "/user_timeline/";  static const char *twitter_request_token_uri  = "http://twitter.com/oauth/request_token";
307  static const char *update_uri  = "/update.xml";  static const char *twitter_access_token_uri   = "http://twitter.com/oauth/access_token";
308  static const char *public_uri  = "/public_timeline.xml";  static const char *twitter_authorize_uri      = "http://twitter.com/oauth/authorize?oauth_token=";
309  static const char *friends_uri = "/friends_timeline.xml";  static const char *identica_request_token_uri = "http://identi.ca/api/oauth/request_token";
310  static const char *replies_uri = "/replies.xml";  static const char *identica_access_token_uri  = "http://identi.ca/api/oauth/access_token";
311  static const char *group_uri = "/../laconica/groups/timeline/";  static const char *identica_authorize_uri     = "http://identi.ca/api/oauth/authorize?oauth_token=";
312    
313    static const char *user_uri     = "/user_timeline/";
314    static const char *update_uri   = "/update.xml";
315    static const char *public_uri   = "/public_timeline.xml";
316    static const char *friends_uri  = "/friends_timeline.xml";
317    static const char *mentions_uri = "/mentions.xml";
318    static const char *replies_uri  = "/replies.xml";
319    static const char *group_uri    = "/../statusnet/groups/timeline/";
320    
321  static CURL *curl_init(void)  static CURL *curl_init(void)
322  {  {
# Line 317  static void parse_statuses(xmlDocPtr doc Line 338  static void parse_statuses(xmlDocPtr doc
338          xmlChar *text = NULL;          xmlChar *text = NULL;
339          xmlChar *user = NULL;          xmlChar *user = NULL;
340          xmlChar *created = NULL;          xmlChar *created = NULL;
341            xmlChar *id = NULL;
342          xmlNodePtr userinfo;          xmlNodePtr userinfo;
343    
344          current = current->xmlChildrenNode;          current = current->xmlChildrenNode;
# Line 326  static void parse_statuses(xmlDocPtr doc Line 348  static void parse_statuses(xmlDocPtr doc
348                                  created = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);                                  created = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
349                          if (!xmlStrcmp(current->name, (const xmlChar *)"text"))                          if (!xmlStrcmp(current->name, (const xmlChar *)"text"))
350                                  text = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);                                  text = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
351                            if (!xmlStrcmp(current->name, (const xmlChar *)"id"))
352                                    id = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
353                          if (!xmlStrcmp(current->name, (const xmlChar *)"user")) {                          if (!xmlStrcmp(current->name, (const xmlChar *)"user")) {
354                                  userinfo = current->xmlChildrenNode;                                  userinfo = current->xmlChildrenNode;
355                                  while (userinfo != NULL) {                                  while (userinfo != NULL) {
# Line 338  static void parse_statuses(xmlDocPtr doc Line 362  static void parse_statuses(xmlDocPtr doc
362                                  }                                  }
363                          }                          }
364    
365                          if (user && text && created) {                          if (user && text && created && id) {
366                                  if (verbose)                                  if (verbose)
367                                          printf("[%s] (%.16s) %s\n",                                          printf("[%s] {%s} (%.16s) %s\n",
368                                                  user, created, text);                                                  user, id, created, text);
369                                  else                                  else
370                                          printf("[%s] %s\n",                                          printf("[%s] %s\n",
371                                                  user, text);                                                  user, text);
372                                  xmlFree(user);                                  xmlFree(user);
373                                  xmlFree(text);                                  xmlFree(text);
374                                  xmlFree(created);                                  xmlFree(created);
375                                    xmlFree(id);
376                                  user = NULL;                                  user = NULL;
377                                  text = NULL;                                  text = NULL;
378                                  created = NULL;                                  created = NULL;
379                                    id = NULL;
380                          }                          }
381                  }                  }
382                  current = current->next;                  current = current->next;
# Line 421  static size_t curl_callback(void *buffer Line 447  static size_t curl_callback(void *buffer
447          return buffer_size;          return buffer_size;
448  }  }
449    
450    static int parse_osp_reply(const char *reply, char **token, char **secret)
451    {
452            int rc;
453            int retval = 1;
454            char **rv = NULL;
455            rc = oauth_split_url_parameters(reply, &rv);
456            qsort(rv, rc, sizeof(char *), oauth_cmpstringp);
457            if (rc == 2 || rc == 4) {
458                    if (!strncmp(rv[0],"oauth_token=",11) && !strncmp(rv[1],"oauth_token_secret=",18)) {
459                            if (token)
460                                    *token =strdup(&(rv[0][12]));
461                            if (secret)
462                                    *secret=strdup(&(rv[1][19]));
463    
464                            retval = 0;
465                    }
466            } else if (rc == 3) {
467                    if (!strncmp(rv[1],"oauth_token=",11) && !strncmp(rv[2],"oauth_token_secret=",18)) {
468                            if (token)
469                                    *token =strdup(&(rv[1][12]));
470                            if (secret)
471                                    *secret=strdup(&(rv[2][19]));
472    
473                            retval = 0;
474                    }
475            }
476    
477            dbg("token: %s\n", *token);
478            dbg("secret: %s\n", *secret);
479    
480            if (rv)
481                    free(rv);
482    
483            return retval;
484    }
485            
486    
487    static int request_access_token(struct session *session)
488    {
489            char *post_params = NULL;
490            char *request_url = NULL;
491            char *reply    = NULL;
492            char *at_key      = NULL;
493            char *at_secret   = NULL;
494            char *verifier    = NULL;
495            char at_uri[90];
496    
497            if (!session)
498                    return -EINVAL;
499    
500            if (session->host == HOST_TWITTER)
501                    request_url = oauth_sign_url2(
502                                    twitter_request_token_uri, NULL,
503                                    OA_HMAC, NULL, session->consumer_key,
504                                    session->consumer_secret, NULL, NULL);
505            else if (session->host == HOST_IDENTICA)
506                    request_url = oauth_sign_url2(
507                                    identica_request_token_uri, NULL,
508                                    OA_HMAC, NULL, session->consumer_key,
509                                    session->consumer_secret, NULL, NULL);
510            reply = oauth_http_get(request_url, post_params);
511    
512            if (request_url)
513                    free(request_url);
514    
515            if (post_params)
516                    free(post_params);
517    
518            if (!reply)
519                    return 1;
520    
521            if (parse_osp_reply(reply, &at_key, &at_secret))
522                    return 1;
523    
524            free(reply);
525    
526            fprintf(stdout, "Please open the following link in your browser, and ");
527            fprintf(stdout, "allow 'bti' to access your account. Then paste ");
528            fprintf(stdout, "back the provided PIN in here.\n");
529            if (session->host == HOST_TWITTER) {
530                    fprintf(stdout, "%s%s\nPIN: ", twitter_authorize_uri, at_key);
531                    verifier = session->readline(NULL);
532                    sprintf(at_uri, "%s?oauth_verifier=%s", twitter_access_token_uri, verifier);
533            } else if (session->host == HOST_IDENTICA) {
534                    fprintf(stdout, "%s%s\nPIN: ", identica_authorize_uri, at_key);
535                    verifier = session->readline(NULL);
536                    sprintf(at_uri, "%s?oauth_verifier=%s", identica_access_token_uri, verifier);
537            }
538            request_url = oauth_sign_url2(at_uri, NULL, OA_HMAC, NULL,
539                            session->consumer_key, session->consumer_secret, at_key,
540                            at_secret);
541            reply = oauth_http_get(request_url, post_params);
542    
543            if (!reply)
544                    return 1;
545    
546            if (parse_osp_reply(reply, &at_key, &at_secret))
547                    return 1;
548    
549            free(reply);
550    
551            fprintf(stdout, "Please put these two lines in your bti configuration ");
552            fprintf(stdout, "file (~/.bti):\n");
553            fprintf(stdout, "access_token_key=%s\n", at_key);
554            fprintf(stdout, "access_token_secret=%s\n", at_secret);
555    
556            return 0;
557    }
558    
559  static int send_request(struct session *session)  static int send_request(struct session *session)
560  {  {
561          char endpoint[100];          char endpoint[500];
562          char user_password[500];          char user_password[500];
563          char data[500];          char data[500];
564          struct bti_curl_buffer *curl_buf;          struct bti_curl_buffer *curl_buf;
# Line 432  static int send_request(struct session * Line 567  static int send_request(struct session *
567          struct curl_httppost *formpost = NULL;          struct curl_httppost *formpost = NULL;
568          struct curl_httppost *lastptr = NULL;          struct curl_httppost *lastptr = NULL;
569          struct curl_slist *slist = NULL;          struct curl_slist *slist = NULL;
570            char *req_url = NULL;
571            char *reply = NULL;
572            char *postarg = NULL;
573            char *escaped_tweet = NULL;
574            int is_post = 0;
575    
576          if (!session)          if (!session)
577                  return -EINVAL;                  return -EINVAL;
578    
         curl_buf = bti_curl_buffer_alloc(session->action);  
         if (!curl_buf)  
                 return -ENOMEM;  
   
         curl = curl_init();  
         if (!curl)  
                 return -EINVAL;  
   
579          if (!session->hosturl)          if (!session->hosturl)
580                  session->hosturl = strdup(twitter_host);                  session->hosturl = strdup(twitter_host);
581    
582          switch (session->action) {          if (session->no_oauth) {
583          case ACTION_UPDATE:                  curl_buf = bti_curl_buffer_alloc(session->action);
584                  snprintf(user_password, sizeof(user_password), "%s:%s",                  if (!curl_buf)
585                           session->account, session->password);                          return -ENOMEM;
                 snprintf(data, sizeof(data), "status=\"%s\"", session->tweet);  
                 curl_formadd(&formpost, &lastptr,  
                              CURLFORM_COPYNAME, "status",  
                              CURLFORM_COPYCONTENTS, session->tweet,  
                              CURLFORM_END);  
   
                 curl_formadd(&formpost, &lastptr,  
                              CURLFORM_COPYNAME, "source",  
                              CURLFORM_COPYCONTENTS, "bti",  
                              CURLFORM_END);  
   
                 curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);  
                 slist = curl_slist_append(slist, "Expect:");  
                 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);  
   
                 sprintf(endpoint, "%s%s", session->hosturl, update_uri);  
                 curl_easy_setopt(curl, CURLOPT_URL, endpoint);  
                 curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);  
586    
587                  break;                  curl = curl_init();
588          case ACTION_FRIENDS:                  if (!curl)
589                  snprintf(user_password, sizeof(user_password), "%s:%s",                          return -EINVAL;
                          session->account, session->password);  
                 sprintf(endpoint, "%s%s?page=%d", session->hosturl,  
                         friends_uri, session->page);  
                 curl_easy_setopt(curl, CURLOPT_URL, endpoint);  
                 curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);  
590    
591                  break;                  if (!session->hosturl)
592          case ACTION_USER:                          session->hosturl = strdup(twitter_host);
                 sprintf(endpoint, "%s%s%s.xml?page=%d", session->hosturl,  
                         user_uri, session->user, session->page);  
                 curl_easy_setopt(curl, CURLOPT_URL, endpoint);  
593    
594                  break;                  switch (session->action) {
595          case ACTION_REPLIES:                          case ACTION_UPDATE:
596                  snprintf(user_password, sizeof(user_password), "%s:%s",                                  snprintf(user_password, sizeof(user_password), "%s:%s",
597                           session->account, session->password);                                                  session->account, session->password);
598                  sprintf(endpoint, "%s%s?page=%d", session->hosturl, replies_uri,                                  snprintf(data, sizeof(data), "status=\"%s\"", session->tweet);
599                          session->page);                                  curl_formadd(&formpost, &lastptr,
600                  curl_easy_setopt(curl, CURLOPT_URL, endpoint);                                                  CURLFORM_COPYNAME, "status",
601                  curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);                                                  CURLFORM_COPYCONTENTS, session->tweet,
602                                                    CURLFORM_END);
603    
604                                    curl_formadd(&formpost, &lastptr,
605                                                    CURLFORM_COPYNAME, "source",
606                                                    CURLFORM_COPYCONTENTS, "bti",
607                                                    CURLFORM_END);
608    
609                                    if (session->replyto)
610                                            curl_formadd(&formpost, &lastptr,
611                                                         CURLFORM_COPYNAME, "in_reply_to_status_id",
612                                                         CURLFORM_COPYCONTENTS, session->replyto,
613                                                         CURLFORM_END);
614    
615                                    curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
616                                    slist = curl_slist_append(slist, "Expect:");
617                                    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
618    
619                                    sprintf(endpoint, "%s%s", session->hosturl, update_uri);
620                                    curl_easy_setopt(curl, CURLOPT_URL, endpoint);
621                                    curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
622                                    break;
623                            case ACTION_FRIENDS:
624                                    snprintf(user_password, sizeof(user_password), "%s:%s",
625                                                    session->account, session->password);
626                                    sprintf(endpoint, "%s%s?page=%d", session->hosturl,
627                                                    friends_uri, session->page);
628                                    curl_easy_setopt(curl, CURLOPT_URL, endpoint);
629                                    curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
630    
631                                    break;
632                            case ACTION_USER:
633                                    sprintf(endpoint, "%s%s%s.xml?page=%d", session->hosturl,
634                                                    user_uri, session->user, session->page);
635                                    curl_easy_setopt(curl, CURLOPT_URL, endpoint);
636    
637                                    break;
638                            case ACTION_REPLIES:
639                                    snprintf(user_password, sizeof(user_password), "%s:%s",
640                                                    session->account, session->password);
641                                    sprintf(endpoint, "%s%s?page=%d", session->hosturl, replies_uri,
642                                                    session->page);
643                                    curl_easy_setopt(curl, CURLOPT_URL, endpoint);
644                                    curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
645    
646                                    break;
647                            case ACTION_PUBLIC:
648                                    sprintf(endpoint, "%s%s?page=%d", session->hosturl, public_uri,
649                                                    session->page);
650                                    curl_easy_setopt(curl, CURLOPT_URL, endpoint);
651    
652                                    break;
653                            case ACTION_GROUP:
654                                    sprintf(endpoint, "%s%s%s.xml?page=%d", session->hosturl,
655                                                    group_uri, session->group, session->page);
656                                    curl_easy_setopt(curl, CURLOPT_URL, endpoint);
657    
658                                    break;
659                            default:
660                                    break;
661                    }
662    
663                  break;                  if (session->proxy)
664          case ACTION_PUBLIC:                          curl_easy_setopt(curl, CURLOPT_PROXY, session->proxy);
                 sprintf(endpoint, "%s%s?page=%d", session->hosturl, public_uri,  
                         session->page);  
                 curl_easy_setopt(curl, CURLOPT_URL, endpoint);  
665    
666                  break;                  if (debug)
667          case ACTION_GROUP:                          curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
                 sprintf(endpoint, "%s%s%s.xml?page=%d", session->hosturl,  
                                 group_uri, session->group, session->page);  
                 curl_easy_setopt(curl, CURLOPT_URL, endpoint);  
668    
669                  break;                  dbg("user_password = %s\n", user_password);
670          default:                  dbg("data = %s\n", data);
671                  break;                  dbg("proxy = %s\n", session->proxy);
672          }  
673                    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_callback);
674          if (session->proxy)                  curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl_buf);
675                  curl_easy_setopt(curl, CURLOPT_PROXY, session->proxy);                  if (!session->dry_run) {
676                            res = curl_easy_perform(curl);
677                            if (res && !session->bash) {
678                                    fprintf(stderr, "error(%d) trying to perform "
679                                                    "operation\n", res);
680                                    return -EINVAL;
681                            }
682                    }
683    
684          if (debug)                  curl_easy_cleanup(curl);
685                  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);                  if (session->action == ACTION_UPDATE)
686                            curl_formfree(formpost);
687                    bti_curl_buffer_free(curl_buf);
688            } else {
689                    switch (session->action) {
690                            case ACTION_UPDATE:
691                                    escaped_tweet = oauth_url_escape(session->tweet);
692                                    sprintf(endpoint,
693                                                    "%s%s?status=%s",
694                                                    session->hosturl, update_uri, escaped_tweet);
695                                    is_post = 1;
696                                    break;
697                            case ACTION_USER:
698                                    sprintf(endpoint, "%s%s%s.xml?page=%d",
699                                                    session->hosturl, user_uri,
700                                                    session->user, session->page);
701                                    break;
702                            case ACTION_REPLIES:
703                                    sprintf(endpoint, "%s%s?page=%d",
704                                                    session->hosturl, mentions_uri, session->page);
705                                    break;
706                            case ACTION_PUBLIC:
707                                    sprintf(endpoint, "%s%s?page=%d",
708                                                    session->hosturl, public_uri, session->page);
709                                    break;
710                            case ACTION_GROUP:
711                                    sprintf(endpoint, "%s%s%s.xml?page=%d",
712                                                    session->hosturl, group_uri,
713                                                    session->group, session->page);
714                                    break;
715                            case ACTION_FRIENDS:
716                                    sprintf(endpoint, "%s%s?page=%d",
717                                                    session->hosturl, friends_uri, session->page);
718                                    break;
719                            default:
720                                    break;
721                    }
722    
723          dbg("user_password = %s\n", user_password);                  if (is_post) {
724          dbg("data = %s\n", data);                          req_url = oauth_sign_url2(
725          dbg("proxy = %s\n", session->proxy);                                          endpoint, &postarg, OA_HMAC, NULL,
726                                            session->consumer_key, session->consumer_secret,
727          curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_callback);                                          session->access_token_key, session->access_token_secret
728          curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl_buf);                                          );
729          if (!session->dry_run) {                          reply = oauth_http_post(req_url, postarg);
730                  res = curl_easy_perform(curl);                  } else {
731                  if (res && !session->bash) {                          req_url = oauth_sign_url2(
732                          fprintf(stderr, "error(%d) trying to perform "                                          endpoint, NULL, OA_HMAC, NULL,
733                                  "operation\n", res);                                          session->consumer_key, session->consumer_secret,
734                          return -EINVAL;                                          session->access_token_key, session->access_token_secret
735                                            );
736                            reply = oauth_http_get(req_url, postarg);
737                  }                  }
         }  
738    
739          curl_easy_cleanup(curl);                  dbg("%s\n", req_url);
740          if (session->action == ACTION_UPDATE)                  dbg("%s\n", reply);
741                  curl_formfree(formpost);                  if (req_url)
742          bti_curl_buffer_free(curl_buf);                          free(req_url);
743    
744                    if (session->action != ACTION_UPDATE)
745                            parse_timeline(reply);
746            }
747          return 0;          return 0;
748  }  }
749    
# Line 546  static void parse_configfile(struct sess Line 754  static void parse_configfile(struct sess
754          size_t len = 0;          size_t len = 0;
755          char *account = NULL;          char *account = NULL;
756          char *password = NULL;          char *password = NULL;
757            char *consumer_key = NULL;
758            char *consumer_secret = NULL;
759            char *access_token_key = NULL;
760            char *access_token_secret = NULL;
761          char *host = NULL;          char *host = NULL;
762          char *proxy = NULL;          char *proxy = NULL;
763          char *logfile = NULL;          char *logfile = NULL;
764          char *action = NULL;          char *action = NULL;
765          char *user = NULL;          char *user = NULL;
766          char *file;          char *replyto = NULL;
767          int shrink_urls = 0;          int shrink_urls = 0;
768    
769          config_file = fopen(session->configfile, "r");          config_file = fopen(session->configfile, "r");
# Line 588  static void parse_configfile(struct sess Line 800  static void parse_configfile(struct sess
800                          c += 9;                          c += 9;
801                          if (c[0] != '\0')                          if (c[0] != '\0')
802                                  password = strdup(c);                                  password = strdup(c);
803                    } else if (!strncasecmp(c, "consumer_key", 12) &&
804                               (c[12] == '=')) {
805                            c += 13;
806                            if (c[0] != '\0')
807                                    consumer_key = strdup(c);
808                    } else if (!strncasecmp(c, "consumer_secret", 15) &&
809                               (c[15] == '=')) {
810                            c += 16;
811                            if (c[0] != '\0')
812                                    consumer_secret = strdup(c);
813                    } else if (!strncasecmp(c, "access_token_key", 16) &&
814                               (c[16] == '=')) {
815                            c += 17;
816                            if (c[0] != '\0')
817                                    access_token_key = strdup(c);
818                    } else if (!strncasecmp(c, "access_token_secret", 19) &&
819                               (c[19] == '=')) {
820                            c += 20;
821                            if (c[0] != '\0')
822                                    access_token_secret = strdup(c);
823                  } else if (!strncasecmp(c, "host", 4) &&                  } else if (!strncasecmp(c, "host", 4) &&
824                             (c[4] == '=')) {                             (c[4] == '=')) {
825                          c += 5;                          c += 5;
# Line 603  static void parse_configfile(struct sess Line 835  static void parse_configfile(struct sess
835                          c += 8;                          c += 8;
836                          if (c[0] != '\0')                          if (c[0] != '\0')
837                                  logfile = strdup(c);                                  logfile = strdup(c);
838                    } else if (!strncasecmp(c, "replyto", 7) &&
839                               (c[7] == '=')) {
840                            c += 8;
841                            if (c[0] != '\0')
842                                    replyto = strdup(c);
843                  } else if (!strncasecmp(c, "action", 6) &&                  } else if (!strncasecmp(c, "action", 6) &&
844                             (c[6] == '=')) {                             (c[6] == '=')) {
845                          c += 7;                          c += 7;
# Line 632  static void parse_configfile(struct sess Line 869  static void parse_configfile(struct sess
869                  session->password = password;                  session->password = password;
870          if (account)          if (account)
871                  session->account = account;                  session->account = account;
872            if (consumer_key)
873                    session->consumer_key = consumer_key;
874            if (consumer_secret)
875                    session->consumer_secret = consumer_secret;
876            if (access_token_key)
877                    session->access_token_key = access_token_key;
878            if (access_token_secret)
879                    session->access_token_secret = access_token_secret;
880          if (host) {          if (host) {
881                  if (strcasecmp(host, "twitter") == 0) {                  if (strcasecmp(host, "twitter") == 0) {
882                          session->host = HOST_TWITTER;                          session->host = HOST_TWITTER;
# Line 655  static void parse_configfile(struct sess Line 900  static void parse_configfile(struct sess
900          }          }
901          if (logfile)          if (logfile)
902                  session->logfile = logfile;                  session->logfile = logfile;
903            if (replyto)
904                    session->replyto = replyto;
905          if (action) {          if (action) {
906                  if (strcasecmp(action, "update") == 0)                  if (strcasecmp(action, "update") == 0)
907                          session->action = ACTION_UPDATE;                          session->action = ACTION_UPDATE;
# Line 1061  int main(int argc, char *argv[], char *e Line 1308  int main(int argc, char *argv[], char *e
1308                  { "page", 1, NULL, 'g' },                  { "page", 1, NULL, 'g' },
1309                  { "version", 0, NULL, 'v' },                  { "version", 0, NULL, 'v' },
1310                  { "config", 1, NULL, 'c' },                  { "config", 1, NULL, 'c' },
1311                    { "replyto", 1, NULL, 'r' },
1312                  { }                  { }
1313          };          };
1314          struct session *session;          struct session *session;
# Line 1094  int main(int argc, char *argv[], char *e Line 1342  int main(int argc, char *argv[], char *e
1342          session->configfile = zalloc(strlen(session->homedir) + 7);          session->configfile = zalloc(strlen(session->homedir) + 7);
1343          sprintf(session->configfile, "%s/.bti", session->homedir);          sprintf(session->configfile, "%s/.bti", session->homedir);
1344    
         curl_global_init(CURL_GLOBAL_ALL);  
   
1345          /* Set environment variables first, before reading command line options          /* Set environment variables first, before reading command line options
1346           * or config file values. */           * or config file values. */
1347          http_proxy = getenv("http_proxy");          http_proxy = getenv("http_proxy");
# Line 1109  int main(int argc, char *argv[], char *e Line 1355  int main(int argc, char *argv[], char *e
1355          parse_configfile(session);          parse_configfile(session);
1356    
1357          while (1) {          while (1) {
1358                  option = getopt_long_only(argc, argv, "dp:P:H:a:A:u:c:hg:G:snVv",                  option = getopt_long_only(argc, argv, "dp:P:H:a:A:u:c:hg:G:sr:nVv",
1359                                            options, NULL);                                            options, NULL);
1360                  if (option == -1)                  if (option == -1)
1361                          break;                          break;
# Line 1131  int main(int argc, char *argv[], char *e Line 1377  int main(int argc, char *argv[], char *e
1377                          dbg("page = %d\n", page_nr);                          dbg("page = %d\n", page_nr);
1378                          session->page = page_nr;                          session->page = page_nr;
1379                          break;                          break;
1380                    case 'r':
1381                            session->replyto = strdup(optarg);
1382                            dbg("in_reply_to_status_id = %s\n", session->replyto);
1383                            break;
1384                  case 'p':                  case 'p':
1385                          if (session->password)                          if (session->password)
1386                                  free(session->password);                                  free(session->password);
# Line 1240  int main(int argc, char *argv[], char *e Line 1490  int main(int argc, char *argv[], char *e
1490          if (debug)          if (debug)
1491                  display_version();                  display_version();
1492    
1493            if (session->host == HOST_TWITTER) {
1494                    if (!session->consumer_key || !session->consumer_secret) {
1495                            fprintf(stderr, "Twitter no longer supuports HTTP basic authentication.\n");
1496                            fprintf(stderr, "Both consumer key, and consumer secret are required");
1497                            fprintf(stderr, " for bti in order to behave as an OAuth consumer.\n");
1498                            goto exit;
1499                    }
1500                    if (session->action == ACTION_GROUP) {
1501                            fprintf(stderr, "Groups only work in Identi.ca.\n");
1502                            goto exit;
1503                    }
1504            } else {
1505                    if (!session->consumer_key || !session->consumer_secret) {
1506                            session->no_oauth = 1;
1507                    }
1508            }
1509            
1510            if (session->no_oauth) {
1511                    if (!session->account) {
1512                            fprintf(stdout, "Enter account for %s: ", session->hostname);
1513                            session->account = session->readline(NULL);
1514                    }
1515                    if (!session->password) {
1516                            read_password(password, sizeof(password), session->hostname);
1517                            session->password = strdup(password);
1518                    }
1519            } else {
1520                    if (!session->access_token_key || !session->access_token_secret) {
1521                            request_access_token(session);
1522                            goto exit;
1523                    }
1524            }
1525    
1526          if (session->action == ACTION_UNKNOWN) {          if (session->action == ACTION_UNKNOWN) {
1527                  fprintf(stderr, "Unknown action, valid actions are:\n");                  fprintf(stderr, "Unknown action, valid actions are:\n");
1528                  fprintf(stderr, "'update', 'friends', 'public', "                  fprintf(stderr, "'update', 'friends', 'public', "
# Line 1247  int main(int argc, char *argv[], char *e Line 1530  int main(int argc, char *argv[], char *e
1530                  goto exit;                  goto exit;
1531          }          }
1532    
         if (session->host == HOST_TWITTER && session->action == ACTION_GROUP) {  
                 fprintf(stderr, "Groups only work in Identi.ca.\n");  
                 goto exit;  
         }  
   
1533          if (session->action == ACTION_GROUP && !session->group) {          if (session->action == ACTION_GROUP && !session->group) {
1534                  fprintf(stdout, "Enter group name: ");                  fprintf(stdout, "Enter group name: ");
1535                  session->group = session->readline(NULL);                  session->group = session->readline(NULL);
1536          }          }
1537    
         if (!session->account) {  
                 fprintf(stdout, "Enter account for %s: ", session->hostname);  
                 session->account = session->readline(NULL);  
         }  
   
         if (!session->password) {  
                 read_password(password, sizeof(password), session->hostname);  
                 session->password = strdup(password);  
         }  
   
1538          if (session->action == ACTION_UPDATE) {          if (session->action == ACTION_UPDATE) {
1539                  if (session->bash || !session->interactive)                  if (session->bash || !session->interactive)
1540                          tweet = get_string_from_stdin();                          tweet = get_string_from_stdin();
# Line 1291  int main(int argc, char *argv[], char *e Line 1559  int main(int argc, char *argv[], char *e
1559                  dbg("tweet = %s\n", session->tweet);                  dbg("tweet = %s\n", session->tweet);
1560          }          }
1561    
         if (!session->user)  
                 session->user = strdup(session->account);  
   
1562          if (session->page == 0)          if (session->page == 0)
1563                  session->page = 1;                  session->page = 1;
1564          dbg("config file = %s\n", session->configfile);          dbg("config file = %s\n", session->configfile);
         dbg("account = %s\n", session->account);  
         dbg("password = %s\n", session->password);  
1565          dbg("host = %d\n", session->host);          dbg("host = %d\n", session->host);
1566          dbg("action = %d\n", session->action);          dbg("action = %d\n", session->action);
1567    

Legend:
Removed from v.2232  
changed lines
  Added in v.2233

  ViewVC Help
Powered by ViewVC 1.1.26