/[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 1620 by gregoa, Sat Feb 14 17:35:18 2009 UTC revision 1621 by gregoa, Thu Mar 12 15:49:54 2009 UTC
# Line 28  Line 28 
28  #include <sys/stat.h>  #include <sys/stat.h>
29  #include <curl/curl.h>  #include <curl/curl.h>
30  #include <readline/readline.h>  #include <readline/readline.h>
31    #include <libxml/xmlmemory.h>
32    #include <libxml/parser.h>
33    #include <libxml/tree.h>
34  #include "bti_version.h"  #include "bti_version.h"
35    
36    
# Line 47  enum host { Line 50  enum host {
50          HOST_IDENTICA = 1,          HOST_IDENTICA = 1,
51  };  };
52    
53    enum action {
54            ACTION_UPDATE = 0,
55            ACTION_FRIENDS = 1,
56            ACTION_USER = 2,
57            ACTION_REPLIES = 4,
58            ACTION_PUBLIC = 8,
59            ACTION_UNKNOWN = 16
60    };
61    
62  struct session {  struct session {
63          char *password;          char *password;
64          char *account;          char *account;
# Line 55  struct session { Line 67  struct session {
67          char *time;          char *time;
68          char *homedir;          char *homedir;
69          char *logfile;          char *logfile;
70            char *user;
71          int bash;          int bash;
72          enum host host;          enum host host;
73            enum action action;
74  };  };
75    
76  struct bti_curl_buffer {  struct bti_curl_buffer {
77          char *data;          char *data;
78            enum action action;
79          int length;          int length;
80  };  };
81    
82  static void display_help(void)  static void display_help(void)
83  {  {
84          fprintf(stdout, "bti - send tweet to twitter\n");          fprintf(stdout, "bti - send tweet to twitter or identi.ca\n");
85          fprintf(stdout, "Version: " BTI_VERSION "\n");          fprintf(stdout, "Version: " BTI_VERSION "\n");
86          fprintf(stdout, "Usage:\n");          fprintf(stdout, "Usage:\n");
87          fprintf(stdout, "  bti [options]\n");          fprintf(stdout, "  bti [options]\n");
88          fprintf(stdout, "options are:\n");          fprintf(stdout, "options are:\n");
89          fprintf(stdout, "  --account accountname\n");          fprintf(stdout, "  --account accountname\n");
90          fprintf(stdout, "  --password password\n");          fprintf(stdout, "  --password password\n");
91            fprintf(stdout, "  --action action\n");
92            fprintf(stdout, "    ('update', 'friends', 'public', 'replies' or 'user')\n");
93            fprintf(stdout, "  --user screenname\n");
94          fprintf(stdout, "  --proxy PROXY:PORT\n");          fprintf(stdout, "  --proxy PROXY:PORT\n");
95          fprintf(stdout, "  --host HOST\n");          fprintf(stdout, "  --host HOST\n");
96          fprintf(stdout, "  --logfile logfile\n");          fprintf(stdout, "  --logfile logfile\n");
# Line 107  static void session_free(struct session Line 125  static void session_free(struct session
125          free(session->proxy);          free(session->proxy);
126          free(session->time);          free(session->time);
127          free(session->homedir);          free(session->homedir);
128            free(session->user);
129          free(session);          free(session);
130  }  }
131    
132  static struct bti_curl_buffer *bti_curl_buffer_alloc(void)  static struct bti_curl_buffer *bti_curl_buffer_alloc(enum action action)
133  {  {
134          struct bti_curl_buffer *buffer;          struct bti_curl_buffer *buffer;
135    
# Line 126  static struct bti_curl_buffer *bti_curl_ Line 145  static struct bti_curl_buffer *bti_curl_
145                  return NULL;                  return NULL;
146          }          }
147          buffer->length = 0;          buffer->length = 0;
148            buffer->action = action;
149          return buffer;          return buffer;
150  }  }
151    
# Line 137  static void bti_curl_buffer_free(struct Line 157  static void bti_curl_buffer_free(struct
157          free(buffer);          free(buffer);
158  }  }
159    
160  static const char *twitter_url = "https://twitter.com/statuses/update.xml";  static const char *twitter_user_url    = "http://twitter.com/statuses/user_timeline/";
161  static const char *identica_url = "http://identi.ca/api/statuses/update.xml";  static const char *twitter_update_url  = "https://twitter.com/statuses/update.xml";
162    static const char *twitter_public_url  = "http://twitter.com/statuses/public_timeline.xml";
163    static const char *twitter_friends_url = "https://twitter.com/statuses/friends_timeline.xml";
164    static const char *twitter_replies_url = "http://twitter.com/statuses/replies.xml";
165    
166    static const char *identica_user_url    = "http://identi.ca/api/statuses/user_timeline/";
167    static const char *identica_update_url  = "http://identi.ca/api/statuses/update.xml";
168    static const char *identica_public_url  = "http://identi.ca/api/statuses/public_timeline.xml";
169    static const char *identica_friends_url = "http://identi.ca/api/statuses/friends_timeline.xml";
170    static const char *identica_replies_url = "http://identi.ca/api/statuses/replies.xml";
171    
172  static CURL *curl_init(void)  static CURL *curl_init(void)
173  {  {
# Line 155  static CURL *curl_init(void) Line 184  static CURL *curl_init(void)
184          return curl;          return curl;
185  }  }
186    
187    void parse_statuses(xmlDocPtr doc, xmlNodePtr current)
188    {
189            xmlChar *text = NULL;
190            xmlChar *user = NULL;
191            xmlNodePtr userinfo;
192    
193            current = current->xmlChildrenNode;
194            while (current != NULL) {
195                    if (current->type == XML_ELEMENT_NODE) {
196                            if (!xmlStrcmp(current->name, (const xmlChar *)"text"))
197                                    text = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
198                            if (!xmlStrcmp(current->name, (const xmlChar *)"user")) {
199                                    userinfo = current->xmlChildrenNode;
200                                    while (userinfo != NULL) {
201                                            if ((!xmlStrcmp(userinfo->name, (const xmlChar *)"screen_name"))) {
202                                                    if (user)
203                                                            xmlFree(user);
204                                                    user = xmlNodeListGetString(doc, userinfo->xmlChildrenNode, 1);
205                                            }
206                                            userinfo = userinfo->next;
207                                    }
208                            }
209                            if (user && text) {
210                                    printf("[%s] %s\n", user, text);
211                                    xmlFree(user);
212                                    xmlFree(text);
213                                    user = NULL;
214                                    text = NULL;
215                            }
216                    }
217                    current = current->next;
218            }
219    
220            return;
221    }
222    
223    static void parse_timeline(char *document)
224    {
225            xmlDocPtr doc;
226            xmlNodePtr current;
227            doc = xmlReadMemory(document, strlen(document), "timeline.xml", NULL, XML_PARSE_NOERROR);
228    
229            if (doc == NULL)
230                    return;
231    
232            current = xmlDocGetRootElement(doc);
233            if (current == NULL) {
234                    fprintf(stderr, "empty document\n");
235                    xmlFreeDoc(doc);
236                    return;
237            }
238    
239            if (xmlStrcmp(current->name, (const xmlChar *) "statuses")) {
240                    fprintf(stderr, "unexpected document type\n");
241                    xmlFreeDoc(doc);
242                    return;
243            }
244    
245            current = current->xmlChildrenNode;
246            while (current != NULL) {
247                    if ((!xmlStrcmp(current->name, (const xmlChar *)"status")))
248                            parse_statuses(doc, current);
249                    current = current->next;
250            }
251            xmlFreeDoc(doc);
252    
253            return;
254    }
255    
256  size_t curl_callback(void *buffer, size_t size, size_t nmemb, void *userp)  size_t curl_callback(void *buffer, size_t size, size_t nmemb, void *userp)
257  {  {
258          struct bti_curl_buffer *curl_buf = userp;          struct bti_curl_buffer *curl_buf = userp;
# Line 174  size_t curl_callback(void *buffer, size_ Line 272  size_t curl_callback(void *buffer, size_
272          curl_buf->data = temp;          curl_buf->data = temp;
273          memcpy(&curl_buf->data[curl_buf->length], (char *)buffer, buffer_size);          memcpy(&curl_buf->data[curl_buf->length], (char *)buffer, buffer_size);
274          curl_buf->length += buffer_size;          curl_buf->length += buffer_size;
275            if (curl_buf->action)
276                    parse_timeline(curl_buf->data);
277    
278          dbg("%s\n", curl_buf->data);          dbg("%s\n", curl_buf->data);
279    
280          return buffer_size;          return buffer_size;
281  }  }
282    
283  static int send_tweet(struct session *session)  static int send_request(struct session *session)
284  {  {
285          char user_password[500];          char user_password[500];
286          char data[500];          char data[500];
287            /* is there usernames longer than 22 chars? */
288            char user_url[70];
289          struct bti_curl_buffer *curl_buf;          struct bti_curl_buffer *curl_buf;
290          CURL *curl = NULL;          CURL *curl = NULL;
291          CURLcode res;          CURLcode res;
# Line 194  static int send_tweet(struct session *se Line 296  static int send_tweet(struct session *se
296          if (!session)          if (!session)
297                  return -EINVAL;                  return -EINVAL;
298    
299          curl_buf = bti_curl_buffer_alloc();          curl_buf = bti_curl_buffer_alloc(session->action);
300          if (!curl_buf)          if (!curl_buf)
301                  return -ENOMEM;                  return -ENOMEM;
302    
         snprintf(user_password, sizeof(user_password), "%s:%s",  
                  session->account, session->password);  
         snprintf(data, sizeof(data), "status=\"%s\"", session->tweet);  
   
303          curl = curl_init();          curl = curl_init();
304          if (!curl)          if (!curl)
305                  return -EINVAL;                  return -EINVAL;
306    
307          curl_formadd(&formpost, &lastptr,          switch (session->action) {
308                       CURLFORM_COPYNAME, "status",          case ACTION_UPDATE:
309                       CURLFORM_COPYCONTENTS, session->tweet,                  snprintf(user_password, sizeof(user_password), "%s:%s",
310                       CURLFORM_END);                           session->account, session->password);
311                    snprintf(data, sizeof(data), "status=\"%s\"", session->tweet);
312          curl_formadd(&formpost, &lastptr,                  curl_formadd(&formpost, &lastptr,
313                       CURLFORM_COPYNAME, "source",                               CURLFORM_COPYNAME, "status",
314                       CURLFORM_COPYCONTENTS, "bti",                               CURLFORM_COPYCONTENTS, session->tweet,
315                       CURLFORM_END);                               CURLFORM_END);
316    
317          curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);                  curl_formadd(&formpost, &lastptr,
318                                 CURLFORM_COPYNAME, "source",
319                                 CURLFORM_COPYCONTENTS, "bti",
320                                 CURLFORM_END);
321    
322          switch (session->host) {                  curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
         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.  
                  */  
323                  slist = curl_slist_append(slist, "Expect:");                  slist = curl_slist_append(slist, "Expect:");
324                  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);                  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
325                    switch (session->host) {
326                    case HOST_TWITTER:
327                            curl_easy_setopt(curl, CURLOPT_URL, twitter_update_url);
328                            break;
329                    case HOST_IDENTICA:
330                            curl_easy_setopt(curl, CURLOPT_URL, identica_update_url);
331                            break;
332                    }
333                    curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
334    
335                  break;                  break;
336          case HOST_IDENTICA:          case ACTION_FRIENDS:
337                  curl_easy_setopt(curl, CURLOPT_URL, identica_url);                  snprintf(user_password, sizeof(user_password), "%s:%s",
338                             session->account, session->password);
339                    switch (session->host) {
340                    case HOST_TWITTER:
341                            curl_easy_setopt(curl, CURLOPT_URL, twitter_friends_url);
342                            break;
343                    case HOST_IDENTICA:
344                            curl_easy_setopt(curl, CURLOPT_URL, identica_friends_url);
345                            break;
346                    }
347                    curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
348    
349                    break;
350            case ACTION_USER:
351                    switch (session->host) {
352                    case HOST_TWITTER:
353                            sprintf(user_url, "%s%s.xml", twitter_user_url, session->user);
354                            curl_easy_setopt(curl, CURLOPT_URL, user_url);
355                            break;
356                    case HOST_IDENTICA:
357                            sprintf(user_url, "%s%s.xml", identica_user_url, session->user);
358                            curl_easy_setopt(curl, CURLOPT_URL, user_url);
359                            break;
360                    }
361    
362                    break;
363            case ACTION_REPLIES:
364                    snprintf(user_password, sizeof(user_password), "%s:%s",
365                             session->account, session->password);
366                    switch (session->host) {
367                    case HOST_TWITTER:
368                            curl_easy_setopt(curl, CURLOPT_URL, twitter_replies_url);
369                            break;
370                    case HOST_IDENTICA:
371                            curl_easy_setopt(curl, CURLOPT_URL, identica_replies_url);
372                            break;
373                    }
374                    curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);
375    
376                    break;
377            case ACTION_PUBLIC:
378                    switch (session->host) {
379                    case HOST_TWITTER:
380                            curl_easy_setopt(curl, CURLOPT_URL, twitter_public_url);
381                            break;
382                    case HOST_IDENTICA:
383                            curl_easy_setopt(curl, CURLOPT_URL, identica_public_url);
384                            break;
385                    }
386    
387                    break;
388            default:
389                  break;                  break;
390          }          }
391    
# Line 238  static int send_tweet(struct session *se Line 394  static int send_tweet(struct session *se
394    
395          if (debug)          if (debug)
396                  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);                  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
         curl_easy_setopt(curl, CURLOPT_USERPWD, user_password);  
397    
398          dbg("user_password = %s\n", user_password);          dbg("user_password = %s\n", user_password);
399          dbg("data = %s\n", data);          dbg("data = %s\n", data);
# Line 248  static int send_tweet(struct session *se Line 403  static int send_tweet(struct session *se
403          curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl_buf);          curl_easy_setopt(curl, CURLOPT_WRITEDATA, curl_buf);
404          res = curl_easy_perform(curl);          res = curl_easy_perform(curl);
405          if (res && !session->bash) {          if (res && !session->bash) {
406                  fprintf(stderr, "error(%d) trying to send tweet\n", res);                  fprintf(stderr, "error(%d) trying to perform operation\n", res);
407                  return -EINVAL;                  return -EINVAL;
408          }          }
409    
410          curl_easy_cleanup(curl);          curl_easy_cleanup(curl);
411          curl_formfree(formpost);          if (session->action == ACTION_UPDATE)
412                    curl_formfree(formpost);
413          bti_curl_buffer_free(curl_buf);          bti_curl_buffer_free(curl_buf);
414          return 0;          return 0;
415  }  }
# Line 268  static void parse_configfile(struct sess Line 424  static void parse_configfile(struct sess
424          char *host = NULL;          char *host = NULL;
425          char *proxy = NULL;          char *proxy = NULL;
426          char *logfile = NULL;          char *logfile = NULL;
427            char *action = NULL;
428            char *user = NULL;
429          char *file;          char *file;
430    
431          /* config file is ~/.bti  */          /* config file is ~/.bti  */
# Line 324  static void parse_configfile(struct sess Line 482  static void parse_configfile(struct sess
482                          c += 8;                          c += 8;
483                          if (c[0] != '\0')                          if (c[0] != '\0')
484                                  logfile = strdup(c);                                  logfile = strdup(c);
485                    } else if (!strncasecmp(c, "action", 6) &&
486                               (c[6] == '=')) {
487                            c += 7;
488                            if (c[0] != '\0')
489                                    action = strdup(c);
490                    } else if (!strncasecmp(c, "user", 4) &&
491                                    (c[4] == '=')) {
492                            c += 5;
493                            if (c[0] != '\0')
494                                    user = strdup(c);
495                  }                  }
496          } while (!feof(config_file));          } while (!feof(config_file));
497    
# Line 345  static void parse_configfile(struct sess Line 513  static void parse_configfile(struct sess
513          }          }
514          if (logfile)          if (logfile)
515                  session->logfile = logfile;                  session->logfile = logfile;
516            if (action) {
517                    if (strcasecmp(action, "update") == 0)
518                            session->action = ACTION_UPDATE;
519                    else if (strcasecmp(action, "friends") == 0)
520                            session->action = ACTION_FRIENDS;
521                    else if (strcasecmp(action, "user") == 0)
522                            session->action = ACTION_USER;
523                    else if (strcasecmp(action, "replies") == 0)
524                            session->action = ACTION_REPLIES;
525                    else if (strcasecmp(action, "public") == 0)
526                            session->action = ACTION_PUBLIC;
527                    else
528                            session->action = ACTION_UNKNOWN;
529                    free(action);
530            }
531            if (user) {
532                    session->user = user;
533            }
534    
535          /* Free buffer and close file.  */          /* Free buffer and close file.  */
536          free(line);          free(line);
# Line 381  static void log_session(struct session * Line 567  static void log_session(struct session *
567                  break;                  break;
568          }          }
569    
570          if (retval)          switch (session->action) {
571                  fprintf(log_file, "%s: host=%s tweet failed\n",          case ACTION_UPDATE:
572                    if (retval)
573                            fprintf(log_file, "%s: host=%s tweet failed\n",
574                                    session->time, host);
575                    else
576                            fprintf(log_file, "%s: host=%s tweet=%s\n",
577                                    session->time, host, session->tweet);
578                    break;
579            case ACTION_FRIENDS:
580                    fprintf(log_file, "%s: host=%s retrieving friends timeline\n",
581                            session->time, host);
582                    break;
583            case ACTION_USER:
584                    fprintf(log_file, "%s: host=%s retrieving %s's timeline\n",
585                            session->time, host, session->user);
586                    break;
587            case ACTION_REPLIES:
588                    fprintf(log_file, "%s: host=%s retrieving replies\n",
589                            session->time, host);
590                    break;
591            case ACTION_PUBLIC:
592                    fprintf(log_file, "%s: host=%s retrieving public timeline\n",
593                          session->time, host);                          session->time, host);
594          else                  break;
595                  fprintf(log_file, "%s: host=%s tweet=%s\n",          default:
596                          session->time, host, session->tweet);                  break;
597            }
598    
599          fclose(log_file);          fclose(log_file);
600  }  }
601    
602    static char *get_string_from_stdin(void)
603    {
604            char *temp;
605            char *string;
606    
607            string = zalloc(1000);
608            if (!string)
609                    return NULL;
610    
611            if (!fgets(string, 999, stdin))
612                    return NULL;
613            temp = strchr(string, '\n');
614            *temp = '\0';
615            return string;
616    }
617    
618  int main(int argc, char *argv[], char *envp[])  int main(int argc, char *argv[], char *envp[])
619  {  {
620          static const struct option options[] = {          static const struct option options[] = {
# Line 399  int main(int argc, char *argv[], char *e Line 623  int main(int argc, char *argv[], char *e
623                  { "password", 1, NULL, 'p' },                  { "password", 1, NULL, 'p' },
624                  { "host", 1, NULL, 'H' },                  { "host", 1, NULL, 'H' },
625                  { "proxy", 1, NULL, 'P' },                  { "proxy", 1, NULL, 'P' },
626                    { "action", 1, NULL, 'A' },
627                    { "user", 1, NULL, 'u' },
628                  { "logfile", 1, NULL, 'L' },                  { "logfile", 1, NULL, 'L' },
629                  { "help", 0, NULL, 'h' },                  { "help", 0, NULL, 'h' },
630                  { "bash", 0, NULL, 'b' },                  { "bash", 0, NULL, 'b' },
# Line 444  int main(int argc, char *argv[], char *e Line 670  int main(int argc, char *argv[], char *e
670          parse_configfile(session);          parse_configfile(session);
671    
672          while (1) {          while (1) {
673                  option = getopt_long_only(argc, argv, "dqe:p:P:H:a:h",                  option = getopt_long_only(argc, argv, "dqe:p:P:H:a:A:u:h",
674                                            options, NULL);                                            options, NULL);
675                  if (option == -1)                  if (option == -1)
676                          break;                          break;
# Line 470  int main(int argc, char *argv[], char *e Line 696  int main(int argc, char *argv[], char *e
696                          session->proxy = strdup(optarg);                          session->proxy = strdup(optarg);
697                          dbg("proxy = %s\n", session->proxy);                          dbg("proxy = %s\n", session->proxy);
698                          break;                          break;
699                    case 'A':
700                            if (strcasecmp(optarg, "update") == 0)
701                                    session->action = ACTION_UPDATE;
702                            else if (strcasecmp(optarg, "friends") == 0)
703                                    session->action = ACTION_FRIENDS;
704                            else if (strcasecmp(optarg, "user") == 0)
705                                    session->action = ACTION_USER;
706                            else if (strcasecmp(optarg, "replies") == 0)
707                                    session->action = ACTION_REPLIES;
708                            else if (strcasecmp(optarg, "public") == 0)
709                                    session->action = ACTION_PUBLIC;
710                            else
711                                    session->action = ACTION_UNKNOWN;
712                            dbg("action = %d\n", session->action);
713                            break;
714                    case 'u':
715                            if (session->user)
716                                    free(session->user);
717                            session->user = strdup(optarg);
718                            dbg("user = %s\n", session->user);
719                            break;
720                  case 'L':                  case 'L':
721                          if (session->logfile)                          if (session->logfile)
722                                  free(session->logfile);                                  free(session->logfile);
# Line 498  int main(int argc, char *argv[], char *e Line 745  int main(int argc, char *argv[], char *e
745                  }                  }
746          }          }
747    
748            if (session->action == ACTION_UNKNOWN) {
749                    fprintf(stderr, "Unknown action, valid actions are:\n");
750                    fprintf(stderr, "'update', 'friends', 'public', 'replies' or 'user'.\n");
751                    goto exit;
752            }
753    
754          if (!session->account) {          if (!session->account) {
755                  fprintf(stdout, "Enter twitter account: ");                  fprintf(stdout, "Enter twitter account: ");
756                  session->account = readline(NULL);                  session->account = readline(NULL);
# Line 508  int main(int argc, char *argv[], char *e Line 761  int main(int argc, char *argv[], char *e
761                  session->password = readline(NULL);                  session->password = readline(NULL);
762          }          }
763    
764          if (session->bash)          if (session->action == ACTION_UPDATE) {
765                  tweet = readline(NULL);                  if (session->bash)
766          else                          tweet = get_string_from_stdin();
767                  tweet = readline("tweet: ");                  else
768          if (!tweet || strlen(tweet) == 0) {                          tweet = readline("tweet: ");
769                  dbg("no tweet?\n");                  if (!tweet || strlen(tweet) == 0) {
770                  return -1;                          dbg("no tweet?\n");
771          }                          return -1;
772                    }
773    
774          session->tweet = zalloc(strlen(tweet) + 10);                  session->tweet = zalloc(strlen(tweet) + 10);
775                    if (session->bash)
776                            sprintf(session->tweet, "$ %s", tweet);
777                    else
778                            sprintf(session->tweet, "%s", tweet);
779    
780                    free(tweet);
781                    dbg("tweet = %s\n", session->tweet);
782            }
783    
784          /* if --bash is specified, add the "PWD $ " to          if (!session->user)
785           * the start of the tweet. */                  session->user = strdup(session->account);
         if (session->bash)  
                 sprintf(session->tweet, "$ %s", tweet);  
         else  
                 sprintf(session->tweet, "%s", tweet);  
         free(tweet);  
786    
787          dbg("account = %s\n", session->account);          dbg("account = %s\n", session->account);
788          dbg("password = %s\n", session->password);          dbg("password = %s\n", session->password);
         dbg("tweet = %s\n", session->tweet);  
789          dbg("host = %d\n", session->host);          dbg("host = %d\n", session->host);
790            dbg("action = %d\n", session->action);
791    
792          /* fork ourself so that the main shell can get on          /* fork ourself so that the main shell can get on
793           * with it's life as we try to connect and handle everything           * with it's life as we try to connect and handle everything
794           */           */
795          if (session->bash) {          if (session->bash) {
796                  child = fork();                  child = fork();
797                          if (child) {                  if (child) {
798                          dbg("child is %d\n", child);                          dbg("child is %d\n", child);
799                          exit(0);                          exit(0);
800                  }                  }
801          }          }
802    
803          retval = send_tweet(session);          retval = send_request(session);
804          if (retval && !session->bash)          if (retval && !session->bash)
805                  fprintf(stderr, "tweet failed\n");                  fprintf(stderr, "operation failed\n");
806    
807          log_session(session, retval);          log_session(session, retval);
808  exit:  exit:

Legend:
Removed from v.1620  
changed lines
  Added in v.1621

  ViewVC Help
Powered by ViewVC 1.1.26