1 |
/* |
/* |
2 |
* Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com> |
* Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com> |
3 |
|
* Copyright (C) 2009 Bart Trojanowski <bart@jukie.net> |
4 |
* |
* |
5 |
* This program is free software; you can redistribute it and/or modify it |
* This program is free software; you can redistribute it and/or modify it |
6 |
* under the terms of the GNU General Public License as published by the |
* under the terms of the GNU General Public License as published by the |
27 |
#include <unistd.h> |
#include <unistd.h> |
28 |
#include <time.h> |
#include <time.h> |
29 |
#include <sys/stat.h> |
#include <sys/stat.h> |
30 |
|
#include <sys/types.h> |
31 |
|
#include <sys/wait.h> |
32 |
#include <curl/curl.h> |
#include <curl/curl.h> |
33 |
#include <readline/readline.h> |
#include <readline/readline.h> |
34 |
#include <libxml/xmlmemory.h> |
#include <libxml/xmlmemory.h> |
35 |
#include <libxml/parser.h> |
#include <libxml/parser.h> |
36 |
#include <libxml/tree.h> |
#include <libxml/tree.h> |
37 |
|
#include <pcre.h> |
38 |
#include "bti_version.h" |
#include "bti_version.h" |
39 |
|
|
40 |
|
|
73 |
char *logfile; |
char *logfile; |
74 |
char *user; |
char *user; |
75 |
int bash; |
int bash; |
76 |
|
int shrink_urls; |
77 |
|
int dry_run; |
78 |
|
int page; |
79 |
enum host host; |
enum host host; |
80 |
enum action action; |
enum action action; |
81 |
}; |
}; |
96 |
fprintf(stdout, " --account accountname\n"); |
fprintf(stdout, " --account accountname\n"); |
97 |
fprintf(stdout, " --password password\n"); |
fprintf(stdout, " --password password\n"); |
98 |
fprintf(stdout, " --action action\n"); |
fprintf(stdout, " --action action\n"); |
99 |
fprintf(stdout, " ('update', 'friends', 'public', 'replies' or 'user')\n"); |
fprintf(stdout, " ('update', 'friends', 'public', 'replies' " |
100 |
|
"or 'user')\n"); |
101 |
fprintf(stdout, " --user screenname\n"); |
fprintf(stdout, " --user screenname\n"); |
102 |
fprintf(stdout, " --proxy PROXY:PORT\n"); |
fprintf(stdout, " --proxy PROXY:PORT\n"); |
103 |
fprintf(stdout, " --host HOST\n"); |
fprintf(stdout, " --host HOST\n"); |
104 |
fprintf(stdout, " --logfile logfile\n"); |
fprintf(stdout, " --logfile logfile\n"); |
105 |
|
fprintf(stdout, " --shrink-urls\n"); |
106 |
|
fprintf(stdout, " --page PAGENUMBER\n"); |
107 |
fprintf(stdout, " --bash\n"); |
fprintf(stdout, " --bash\n"); |
108 |
fprintf(stdout, " --debug\n"); |
fprintf(stdout, " --debug\n"); |
109 |
fprintf(stdout, " --version\n"); |
fprintf(stdout, " --version\n"); |
234 |
{ |
{ |
235 |
xmlDocPtr doc; |
xmlDocPtr doc; |
236 |
xmlNodePtr current; |
xmlNodePtr current; |
|
doc = xmlReadMemory(document, strlen(document), "timeline.xml", NULL, XML_PARSE_NOERROR); |
|
237 |
|
|
238 |
|
doc = xmlReadMemory(document, strlen(document), "timeline.xml", |
239 |
|
NULL, XML_PARSE_NOERROR); |
240 |
if (doc == NULL) |
if (doc == NULL) |
241 |
return; |
return; |
242 |
|
|
335 |
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); |
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); |
336 |
switch (session->host) { |
switch (session->host) { |
337 |
case HOST_TWITTER: |
case HOST_TWITTER: |
338 |
curl_easy_setopt(curl, CURLOPT_URL, twitter_update_url); |
curl_easy_setopt(curl, CURLOPT_URL, |
339 |
|
twitter_update_url); |
340 |
break; |
break; |
341 |
case HOST_IDENTICA: |
case HOST_IDENTICA: |
342 |
curl_easy_setopt(curl, CURLOPT_URL, identica_update_url); |
curl_easy_setopt(curl, CURLOPT_URL, |
343 |
|
identica_update_url); |
344 |
break; |
break; |
345 |
} |
} |
346 |
curl_easy_setopt(curl, CURLOPT_USERPWD, user_password); |
curl_easy_setopt(curl, CURLOPT_USERPWD, user_password); |
351 |
session->account, session->password); |
session->account, session->password); |
352 |
switch (session->host) { |
switch (session->host) { |
353 |
case HOST_TWITTER: |
case HOST_TWITTER: |
354 |
curl_easy_setopt(curl, CURLOPT_URL, twitter_friends_url); |
sprintf(user_url, "%s?page=%d", twitter_friends_url, session->page); |
355 |
|
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
356 |
break; |
break; |
357 |
case HOST_IDENTICA: |
case HOST_IDENTICA: |
358 |
curl_easy_setopt(curl, CURLOPT_URL, identica_friends_url); |
sprintf(user_url, "%s?page=%d", identica_friends_url, session->page); |
359 |
|
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
360 |
break; |
break; |
361 |
} |
} |
362 |
curl_easy_setopt(curl, CURLOPT_USERPWD, user_password); |
curl_easy_setopt(curl, CURLOPT_USERPWD, user_password); |
365 |
case ACTION_USER: |
case ACTION_USER: |
366 |
switch (session->host) { |
switch (session->host) { |
367 |
case HOST_TWITTER: |
case HOST_TWITTER: |
368 |
sprintf(user_url, "%s%s.xml", twitter_user_url, session->user); |
sprintf(user_url, "%s%s.xml?page=%d", twitter_user_url, session->user, session->page); |
369 |
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
370 |
break; |
break; |
371 |
case HOST_IDENTICA: |
case HOST_IDENTICA: |
372 |
sprintf(user_url, "%s%s.xml", identica_user_url, session->user); |
sprintf(user_url, "%s%s.xml?page=%d", identica_user_url, session->user, session->page); |
373 |
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
374 |
break; |
break; |
375 |
} |
} |
380 |
session->account, session->password); |
session->account, session->password); |
381 |
switch (session->host) { |
switch (session->host) { |
382 |
case HOST_TWITTER: |
case HOST_TWITTER: |
383 |
curl_easy_setopt(curl, CURLOPT_URL, twitter_replies_url); |
sprintf(user_url, "%s?page=%d", twitter_replies_url, session->page); |
384 |
|
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
385 |
break; |
break; |
386 |
case HOST_IDENTICA: |
case HOST_IDENTICA: |
387 |
curl_easy_setopt(curl, CURLOPT_URL, identica_replies_url); |
sprintf(user_url, "%s?page=%d", identica_replies_url, session->page); |
388 |
|
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
389 |
break; |
break; |
390 |
} |
} |
391 |
curl_easy_setopt(curl, CURLOPT_USERPWD, user_password); |
curl_easy_setopt(curl, CURLOPT_USERPWD, user_password); |
394 |
case ACTION_PUBLIC: |
case ACTION_PUBLIC: |
395 |
switch (session->host) { |
switch (session->host) { |
396 |
case HOST_TWITTER: |
case HOST_TWITTER: |
397 |
curl_easy_setopt(curl, CURLOPT_URL, twitter_public_url); |
sprintf(user_url, "%s?page=%d", twitter_public_url, session->page); |
398 |
|
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
399 |
break; |
break; |
400 |
case HOST_IDENTICA: |
case HOST_IDENTICA: |
401 |
curl_easy_setopt(curl, CURLOPT_URL, identica_public_url); |
sprintf(user_url, "%s?page=%d", identica_public_url, session->page); |
402 |
|
curl_easy_setopt(curl, CURLOPT_URL, user_url); |
403 |
break; |
break; |
404 |
} |
} |
405 |
|
|
420 |
|
|
421 |
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_callback); |
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_callback); |
422 |
curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl_buf); |
curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl_buf); |
423 |
res = curl_easy_perform(curl); |
if (!session->dry_run) { |
424 |
if (res && !session->bash) { |
res = curl_easy_perform(curl); |
425 |
fprintf(stderr, "error(%d) trying to perform operation\n", res); |
if (res && !session->bash) { |
426 |
return -EINVAL; |
fprintf(stderr, "error(%d) trying to perform " |
427 |
|
"operation\n", res); |
428 |
|
return -EINVAL; |
429 |
|
} |
430 |
} |
} |
431 |
|
|
432 |
curl_easy_cleanup(curl); |
curl_easy_cleanup(curl); |
449 |
char *action = NULL; |
char *action = NULL; |
450 |
char *user = NULL; |
char *user = NULL; |
451 |
char *file; |
char *file; |
452 |
|
int shrink_urls = 0; |
453 |
|
|
454 |
/* config file is ~/.bti */ |
/* config file is ~/.bti */ |
455 |
file = alloca(strlen(session->homedir) + 7); |
file = alloca(strlen(session->homedir) + 7); |
515 |
c += 5; |
c += 5; |
516 |
if (c[0] != '\0') |
if (c[0] != '\0') |
517 |
user = strdup(c); |
user = strdup(c); |
518 |
|
} else if (!strncasecmp(c, "shrink-urls", 11) && |
519 |
|
(c[11] == '=')) { |
520 |
|
c += 12; |
521 |
|
if (!strncasecmp(c, "true", 4) || |
522 |
|
!strncasecmp(c, "yes", 3)) |
523 |
|
shrink_urls = 1; |
524 |
} |
} |
525 |
} while (!feof(config_file)); |
} while (!feof(config_file)); |
526 |
|
|
557 |
session->action = ACTION_UNKNOWN; |
session->action = ACTION_UNKNOWN; |
558 |
free(action); |
free(action); |
559 |
} |
} |
560 |
if (user) { |
if (user) |
561 |
session->user = user; |
session->user = user; |
562 |
} |
session->shrink_urls = shrink_urls; |
563 |
|
|
564 |
/* Free buffer and close file. */ |
/* Free buffer and close file. */ |
565 |
free(line); |
free(line); |
644 |
return string; |
return string; |
645 |
} |
} |
646 |
|
|
647 |
|
static int find_urls(const char *tweet, int **pranges) |
648 |
|
{ |
649 |
|
/* |
650 |
|
* magic obtained from |
651 |
|
* http://www.geekpedia.com/KB65_How-to-validate-an-URL-using-RegEx-in-Csharp.html |
652 |
|
*/ |
653 |
|
static const char *re_magic = |
654 |
|
"(([a-zA-Z][0-9a-zA-Z+\\-\\.]*:)/{1,3}" |
655 |
|
"[0-9a-zA-Z;/~?:@&=+$\\.\\-_'()%]+)" |
656 |
|
"(#[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?"; |
657 |
|
pcre *re; |
658 |
|
const char *errptr; |
659 |
|
int erroffset; |
660 |
|
int ovector[10] = {0,}; |
661 |
|
const size_t ovsize = sizeof(ovector)/sizeof(*ovector); |
662 |
|
int startoffset, tweetlen; |
663 |
|
int i, rc; |
664 |
|
int rbound = 10; |
665 |
|
int rcount = 0; |
666 |
|
int *ranges = malloc(sizeof(int) * rbound); |
667 |
|
|
668 |
|
re = pcre_compile(re_magic, |
669 |
|
PCRE_NO_AUTO_CAPTURE, |
670 |
|
&errptr, &erroffset, NULL); |
671 |
|
if (!re) { |
672 |
|
fprintf(stderr, "pcre_compile @%u: %s\n", erroffset, errptr); |
673 |
|
exit(1); |
674 |
|
} |
675 |
|
|
676 |
|
tweetlen = strlen(tweet); |
677 |
|
for (startoffset = 0; startoffset < tweetlen; ) { |
678 |
|
|
679 |
|
rc = pcre_exec(re, NULL, tweet, strlen(tweet), startoffset, 0, |
680 |
|
ovector, ovsize); |
681 |
|
if (rc == PCRE_ERROR_NOMATCH) |
682 |
|
break; |
683 |
|
|
684 |
|
if (rc < 0) { |
685 |
|
fprintf(stderr, "pcre_exec @%u: %s\n", |
686 |
|
erroffset, errptr); |
687 |
|
exit(1); |
688 |
|
} |
689 |
|
|
690 |
|
for (i = 0; i < rc; i += 2) { |
691 |
|
if ((rcount+2) == rbound) { |
692 |
|
rbound *= 2; |
693 |
|
ranges = realloc(ranges, sizeof(int) * rbound); |
694 |
|
} |
695 |
|
|
696 |
|
ranges[rcount++] = ovector[i]; |
697 |
|
ranges[rcount++] = ovector[i+1]; |
698 |
|
} |
699 |
|
|
700 |
|
startoffset = ovector[1]; |
701 |
|
} |
702 |
|
|
703 |
|
pcre_free(re); |
704 |
|
|
705 |
|
*pranges = ranges; |
706 |
|
return rcount; |
707 |
|
} |
708 |
|
|
709 |
|
/** |
710 |
|
* bidirectional popen() call |
711 |
|
* |
712 |
|
* @param rwepipe - int array of size three |
713 |
|
* @param exe - program to run |
714 |
|
* @param argv - argument list |
715 |
|
* @return pid or -1 on error |
716 |
|
* |
717 |
|
* The caller passes in an array of three integers (rwepipe), on successful |
718 |
|
* execution it can then write to element 0 (stdin of exe), and read from |
719 |
|
* element 1 (stdout) and 2 (stderr). |
720 |
|
*/ |
721 |
|
static int popenRWE(int *rwepipe, const char *exe, const char *const argv[]) |
722 |
|
{ |
723 |
|
int in[2]; |
724 |
|
int out[2]; |
725 |
|
int err[2]; |
726 |
|
int pid; |
727 |
|
int rc; |
728 |
|
|
729 |
|
rc = pipe(in); |
730 |
|
if (rc < 0) |
731 |
|
goto error_in; |
732 |
|
|
733 |
|
rc = pipe(out); |
734 |
|
if (rc < 0) |
735 |
|
goto error_out; |
736 |
|
|
737 |
|
rc = pipe(err); |
738 |
|
if (rc < 0) |
739 |
|
goto error_err; |
740 |
|
|
741 |
|
pid = fork(); |
742 |
|
if (pid > 0) { |
743 |
|
/* parent */ |
744 |
|
close(in[0]); |
745 |
|
close(out[1]); |
746 |
|
close(err[1]); |
747 |
|
rwepipe[0] = in[1]; |
748 |
|
rwepipe[1] = out[0]; |
749 |
|
rwepipe[2] = err[0]; |
750 |
|
return pid; |
751 |
|
} else if (pid == 0) { |
752 |
|
/* child */ |
753 |
|
close(in[1]); |
754 |
|
close(out[0]); |
755 |
|
close(err[0]); |
756 |
|
close(0); |
757 |
|
rc = dup(in[0]); |
758 |
|
close(1); |
759 |
|
rc = dup(out[1]); |
760 |
|
close(2); |
761 |
|
rc = dup(err[1]); |
762 |
|
|
763 |
|
execvp(exe, (char **)argv); |
764 |
|
exit(1); |
765 |
|
} else |
766 |
|
goto error_fork; |
767 |
|
|
768 |
|
return pid; |
769 |
|
|
770 |
|
error_fork: |
771 |
|
close(err[0]); |
772 |
|
close(err[1]); |
773 |
|
error_err: |
774 |
|
close(out[0]); |
775 |
|
close(out[1]); |
776 |
|
error_out: |
777 |
|
close(in[0]); |
778 |
|
close(in[1]); |
779 |
|
error_in: |
780 |
|
return -1; |
781 |
|
} |
782 |
|
|
783 |
|
static int pcloseRWE(int pid, int *rwepipe) |
784 |
|
{ |
785 |
|
int rc, status; |
786 |
|
close(rwepipe[0]); |
787 |
|
close(rwepipe[1]); |
788 |
|
close(rwepipe[2]); |
789 |
|
rc = waitpid(pid, &status, 0); |
790 |
|
return status; |
791 |
|
} |
792 |
|
|
793 |
|
static char *shrink_one_url(int *rwepipe, char *big) |
794 |
|
{ |
795 |
|
int biglen = strlen(big); |
796 |
|
char *small; |
797 |
|
int smalllen; |
798 |
|
int rc; |
799 |
|
|
800 |
|
rc = dprintf(rwepipe[0], "%s\n", big); |
801 |
|
if (rc < 0) |
802 |
|
return big; |
803 |
|
|
804 |
|
smalllen = biglen + 128; |
805 |
|
small = malloc(smalllen); |
806 |
|
if (!small) |
807 |
|
return big; |
808 |
|
|
809 |
|
rc = read(rwepipe[1], small, smalllen); |
810 |
|
if (rc < 0 || rc > biglen) |
811 |
|
goto error_free_small; |
812 |
|
|
813 |
|
if (strncmp(small, "http://", 7)) |
814 |
|
goto error_free_small; |
815 |
|
|
816 |
|
smalllen = rc; |
817 |
|
while (smalllen && isspace(small[smalllen-1])) |
818 |
|
small[--smalllen] = 0; |
819 |
|
|
820 |
|
free(big); |
821 |
|
return small; |
822 |
|
|
823 |
|
error_free_small: |
824 |
|
free(small); |
825 |
|
return big; |
826 |
|
} |
827 |
|
|
828 |
|
static char *shrink_urls(char *text) |
829 |
|
{ |
830 |
|
int *ranges; |
831 |
|
int rcount; |
832 |
|
int i; |
833 |
|
int inofs = 0; |
834 |
|
int outofs = 0; |
835 |
|
const char *const shrink_args[] = { |
836 |
|
"bti-shrink-urls", |
837 |
|
NULL |
838 |
|
}; |
839 |
|
int shrink_pid; |
840 |
|
int shrink_pipe[3]; |
841 |
|
int inlen = strlen(text); |
842 |
|
|
843 |
|
dbg("before len=%u\n", inlen); |
844 |
|
|
845 |
|
shrink_pid = popenRWE(shrink_pipe, shrink_args[0], shrink_args); |
846 |
|
if (shrink_pid < 0) |
847 |
|
return text; |
848 |
|
|
849 |
|
rcount = find_urls(text, &ranges); |
850 |
|
if (!rcount) |
851 |
|
return text; |
852 |
|
|
853 |
|
for (i = 0; i < rcount; i += 2) { |
854 |
|
int url_start = ranges[i]; |
855 |
|
int url_end = ranges[i+1]; |
856 |
|
int long_url_len = url_end - url_start; |
857 |
|
char *url = strndup(text + url_start, long_url_len); |
858 |
|
int short_url_len; |
859 |
|
int not_url_len = url_start - inofs; |
860 |
|
|
861 |
|
dbg("long url[%u]: %s\n", long_url_len, url); |
862 |
|
url = shrink_one_url(shrink_pipe, url); |
863 |
|
short_url_len = url ? strlen(url) : 0; |
864 |
|
dbg("short url[%u]: %s\n", short_url_len, url); |
865 |
|
|
866 |
|
if (!url || short_url_len >= long_url_len) { |
867 |
|
/* The short url ended up being too long |
868 |
|
* or unavailable */ |
869 |
|
if (inofs) { |
870 |
|
strncpy(text + outofs, text + inofs, |
871 |
|
not_url_len + long_url_len); |
872 |
|
} |
873 |
|
inofs += not_url_len + long_url_len; |
874 |
|
outofs += not_url_len + long_url_len; |
875 |
|
|
876 |
|
} else { |
877 |
|
/* copy the unmodified block */ |
878 |
|
strncpy(text + outofs, text + inofs, not_url_len); |
879 |
|
inofs += not_url_len; |
880 |
|
outofs += not_url_len; |
881 |
|
|
882 |
|
/* copy the new url */ |
883 |
|
strncpy(text + outofs, url, short_url_len); |
884 |
|
inofs += long_url_len; |
885 |
|
outofs += short_url_len; |
886 |
|
} |
887 |
|
|
888 |
|
free(url); |
889 |
|
} |
890 |
|
|
891 |
|
/* copy the last block after the last match */ |
892 |
|
if (inofs) { |
893 |
|
int tail = inlen - inofs; |
894 |
|
if (tail) { |
895 |
|
strncpy(text + outofs, text + inofs, tail); |
896 |
|
outofs += tail; |
897 |
|
} |
898 |
|
} |
899 |
|
|
900 |
|
free(ranges); |
901 |
|
|
902 |
|
(void)pcloseRWE(shrink_pid, shrink_pipe); |
903 |
|
|
904 |
|
text[outofs] = 0; |
905 |
|
dbg("after len=%u\n", outofs); |
906 |
|
return text; |
907 |
|
} |
908 |
|
|
909 |
int main(int argc, char *argv[], char *envp[]) |
int main(int argc, char *argv[], char *envp[]) |
910 |
{ |
{ |
911 |
static const struct option options[] = { |
static const struct option options[] = { |
917 |
{ "action", 1, NULL, 'A' }, |
{ "action", 1, NULL, 'A' }, |
918 |
{ "user", 1, NULL, 'u' }, |
{ "user", 1, NULL, 'u' }, |
919 |
{ "logfile", 1, NULL, 'L' }, |
{ "logfile", 1, NULL, 'L' }, |
920 |
|
{ "shrink-urls", 0, NULL, 's' }, |
921 |
{ "help", 0, NULL, 'h' }, |
{ "help", 0, NULL, 'h' }, |
922 |
{ "bash", 0, NULL, 'b' }, |
{ "bash", 0, NULL, 'b' }, |
923 |
|
{ "dry-run", 0, NULL, 'n' }, |
924 |
|
{ "page", 1, NULL, 'g' }, |
925 |
{ "version", 0, NULL, 'v' }, |
{ "version", 0, NULL, 'v' }, |
926 |
{ } |
{ } |
927 |
}; |
}; |
932 |
int option; |
int option; |
933 |
char *http_proxy; |
char *http_proxy; |
934 |
time_t t; |
time_t t; |
935 |
|
int page_nr; |
936 |
|
|
937 |
debug = 0; |
debug = 0; |
938 |
rl_bind_key('\t', rl_insert); |
rl_bind_key('\t', rl_insert); |
965 |
parse_configfile(session); |
parse_configfile(session); |
966 |
|
|
967 |
while (1) { |
while (1) { |
968 |
option = getopt_long_only(argc, argv, "dqe:p:P:H:a:A:u:h", |
option = getopt_long_only(argc, argv, "dqe:p:P:H:a:A:u:hg:", |
969 |
options, NULL); |
options, NULL); |
970 |
if (option == -1) |
if (option == -1) |
971 |
break; |
break; |
979 |
session->account = strdup(optarg); |
session->account = strdup(optarg); |
980 |
dbg("account = %s\n", session->account); |
dbg("account = %s\n", session->account); |
981 |
break; |
break; |
982 |
|
case 'g': |
983 |
|
page_nr = atoi(optarg); |
984 |
|
dbg("page = %d\n", page_nr); |
985 |
|
session->page = page_nr; |
986 |
|
break; |
987 |
case 'p': |
case 'p': |
988 |
if (session->password) |
if (session->password) |
989 |
free(session->password); |
free(session->password); |
1023 |
session->logfile = strdup(optarg); |
session->logfile = strdup(optarg); |
1024 |
dbg("logfile = %s\n", session->logfile); |
dbg("logfile = %s\n", session->logfile); |
1025 |
break; |
break; |
1026 |
|
case 's': |
1027 |
|
session->shrink_urls = 1; |
1028 |
|
break; |
1029 |
case 'H': |
case 'H': |
1030 |
if (strcasecmp(optarg, "twitter") == 0) |
if (strcasecmp(optarg, "twitter") == 0) |
1031 |
session->host = HOST_TWITTER; |
session->host = HOST_TWITTER; |
1039 |
case 'h': |
case 'h': |
1040 |
display_help(); |
display_help(); |
1041 |
goto exit; |
goto exit; |
1042 |
|
case 'n': |
1043 |
|
session->dry_run = 1; |
1044 |
|
break; |
1045 |
case 'v': |
case 'v': |
1046 |
display_version(); |
display_version(); |
1047 |
goto exit; |
goto exit; |
1053 |
|
|
1054 |
if (session->action == ACTION_UNKNOWN) { |
if (session->action == ACTION_UNKNOWN) { |
1055 |
fprintf(stderr, "Unknown action, valid actions are:\n"); |
fprintf(stderr, "Unknown action, valid actions are:\n"); |
1056 |
fprintf(stderr, "'update', 'friends', 'public', 'replies' or 'user'.\n"); |
fprintf(stderr, "'update', 'friends', 'public', " |
1057 |
|
"'replies' or 'user'.\n"); |
1058 |
goto exit; |
goto exit; |
1059 |
} |
} |
1060 |
|
|
1078 |
return -1; |
return -1; |
1079 |
} |
} |
1080 |
|
|
1081 |
|
if (session->shrink_urls) |
1082 |
|
tweet = shrink_urls(tweet); |
1083 |
|
|
1084 |
session->tweet = zalloc(strlen(tweet) + 10); |
session->tweet = zalloc(strlen(tweet) + 10); |
1085 |
if (session->bash) |
if (session->bash) |
1086 |
sprintf(session->tweet, "$ %s", tweet); |
sprintf(session->tweet, "$ %s", tweet); |
1094 |
if (!session->user) |
if (!session->user) |
1095 |
session->user = strdup(session->account); |
session->user = strdup(session->account); |
1096 |
|
|
1097 |
|
if (session->page == 0) |
1098 |
|
session->page = 1; |
1099 |
dbg("account = %s\n", session->account); |
dbg("account = %s\n", session->account); |
1100 |
dbg("password = %s\n", session->password); |
dbg("password = %s\n", session->password); |
1101 |
dbg("host = %d\n", session->host); |
dbg("host = %d\n", session->host); |