device: Combine two if statements with identical outcome
[framework/connectivity/connman.git] / tools / wispr.c
index 4b083cf..122bea5 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  Connection Manager
  *
- *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2007-2012  Intel Corporation. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
@@ -23,6 +23,7 @@
 #include <config.h>
 #endif
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -30,6 +31,7 @@
 #include <string.h>
 #include <signal.h>
 #include <termios.h>
+#include <netdb.h>
 
 #include <gweb/gweb.h>
 
@@ -103,6 +105,7 @@ struct wispr_msg {
        int message_type;
        int response_code;
        char *login_url;
+       char *abort_login_url;
        char *logoff_url;
        char *access_procedure;
        char *access_location;
@@ -120,6 +123,9 @@ static inline void wispr_msg_init(struct wispr_msg *msg)
        g_free(msg->login_url);
        msg->login_url = NULL;
 
+       g_free(msg->abort_login_url);
+       msg->abort_login_url = NULL;
+
        g_free(msg->logoff_url);
        msg->logoff_url = NULL;
 
@@ -144,7 +150,7 @@ struct wispr_session {
        char *formdata;
 };
 
-static void execute_login(struct wispr_session *wispr);
+static gboolean execute_login(gpointer user_data);
 
 static struct {
        const char *str;
@@ -219,9 +225,11 @@ static void text_handler(GMarkupParseContext *context,
                case WISPR_ELEMENT_ACCESS_PROCEDURE:
                        g_free(msg->access_procedure);
                        msg->access_procedure = g_strdup(text);
+                       break;
                case WISPR_ELEMENT_ACCESS_LOCATION:
                        g_free(msg->access_location);
                        msg->access_location = g_strdup(text);
+                       break;
                case WISPR_ELEMENT_LOCATION_NAME:
                        g_free(msg->location_name);
                        msg->location_name = g_strdup(text);
@@ -231,6 +239,8 @@ static void text_handler(GMarkupParseContext *context,
                        msg->login_url = g_strdup(text);
                        break;
                case WISPR_ELEMENT_ABORT_LOGIN_URL:
+                       g_free(msg->abort_login_url);
+                       msg->abort_login_url = g_strdup(text);
                        break;
                case WISPR_ELEMENT_MESSAGE_TYPE:
                        msg->message_type = atoi(text);
@@ -280,7 +290,7 @@ static void parser_callback(const char *str, gpointer user_data)
 
        result = g_markup_parse_context_parse(context, str, strlen(str), NULL);
        if (result == TRUE)
-               result = g_markup_parse_context_end_parse(context, NULL);
+               g_markup_parse_context_end_parse(context, NULL);
 
        g_markup_parse_context_free(context);
 }
@@ -299,10 +309,14 @@ struct user_input_data {
 static void user_callback(struct user_input_data *data)
 {
        char *value;
-       int len;
 
-       if (data->hidden == TRUE)
+       if (data->hidden == TRUE) {
+               ssize_t len;
+
                len = write(data->fd, "\n", 1);
+               if (len < 0)
+                       return;
+       }
 
        tcsetattr(data->fd, TCSADRAIN, &data->saved_termios);
 
@@ -350,7 +364,7 @@ static gboolean user_input(const char *label, gboolean hidden,
        struct termios new_termios;
        GIOChannel *channel;
        guint watch;
-       int len;
+       ssize_t len;
 
        data = g_try_new0(struct user_input_data, 1);
        if (data == NULL)
@@ -361,7 +375,7 @@ static gboolean user_input(const char *label, gboolean hidden,
        data->user_data = user_data;
        data->hidden = hidden;
 
-       data->fd = open("/dev/tty", O_RDWR | O_NOCTTY);
+       data->fd = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
        if (data->fd < 0)
                goto error;
 
@@ -390,7 +404,12 @@ static gboolean user_input(const char *label, gboolean hidden,
                goto error;
 
        len = write(data->fd, label, strlen(label));
+       if (len < 0)
+               goto error;
+
        len = write(data->fd, ": ", 2);
+       if (len < 0)
+               goto error;
 
        return TRUE;
 
@@ -457,6 +476,24 @@ static gboolean wispr_input(const guint8 **data, gsize *length,
        return FALSE;
 }
 
+static gboolean wispr_route(const char *addr, int ai_family, int if_index,
+               gpointer user_data)
+{
+       char *family = "unknown";
+
+       if (ai_family == AF_INET)
+               family = "IPv4";
+       else if (ai_family == AF_INET6)
+               family = "IPv6";
+
+       printf("Route request: %s %s index %d\n", family, addr, if_index);
+
+       if (ai_family != AF_INET && ai_family != AF_INET6)
+               return FALSE;
+
+       return TRUE;
+}
+
 static gboolean wispr_result(GWebResult *result, gpointer user_data)
 {
        struct wispr_session *wispr = user_data;
@@ -483,8 +520,24 @@ static gboolean wispr_result(GWebResult *result, gpointer user_data)
 
        g_print("elapse: %f seconds\n", elapsed);
 
-       if (wispr->msg.message_type < 0)
-               goto done;
+       if (wispr->msg.message_type < 0) {
+               const char *redirect;
+
+               if (status != 302)
+                       goto done;
+
+               if (g_web_result_get_header(result, "Location",
+                                                       &redirect) == FALSE)
+                       goto done;
+
+               printf("Redirect URL: %s\n", redirect);
+               printf("\n");
+
+               wispr->request = g_web_request_get(wispr->web, redirect,
+                               wispr_result, wispr_route, wispr);
+
+               return FALSE;
+       }
 
        printf("Message type: %s (%d)\n",
                        message_type_to_string(wispr->msg.message_type),
@@ -500,11 +553,16 @@ static gboolean wispr_result(GWebResult *result, gpointer user_data)
                printf("Location name: %s\n", wispr->msg.location_name);
        if (wispr->msg.login_url != NULL)
                printf("Login URL: %s\n", wispr->msg.login_url);
+       if (wispr->msg.abort_login_url != NULL)
+               printf("Abort login URL: %s\n", wispr->msg.abort_login_url);
        if (wispr->msg.logoff_url != NULL)
                printf("Logoff URL: %s\n", wispr->msg.logoff_url);
        printf("\n");
 
-       if (status == 302 && wispr->msg.message_type == 100) {
+       if (status != 200 && status != 302 && status != 404)
+               goto done;
+
+       if (wispr->msg.message_type == 100) {
                if (wispr->username == NULL) {
                        user_input("Username", FALSE, username_callback, wispr);
                        return FALSE;
@@ -515,27 +573,49 @@ static gboolean wispr_result(GWebResult *result, gpointer user_data)
                        return FALSE;
                }
 
-               execute_login(wispr);
+               g_idle_add(execute_login, wispr);
                return FALSE;
-       } else if (status == 200 && wispr->msg.message_type == 120) {
+       } else if (wispr->msg.message_type == 120 ||
+                                       wispr->msg.message_type == 140) {
                int code = wispr->msg.response_code;
                printf("Login process: %s\n",
                                        code == 50 ? "SUCCESS" : "FAILURE");
        }
 
+       if (status == 302) {
+               const char *redirect;
+
+               if (g_web_result_get_header(result, "Location",
+                                                       &redirect) == FALSE)
+                       goto done;
+
+               printf("\n");
+               printf("Redirect URL: %s\n", redirect);
+               printf("\n");
+
+               wispr->request = g_web_request_get(wispr->web, redirect,
+                               wispr_result, NULL, wispr);
+
+               return FALSE;
+       }
+
 done:
        g_main_loop_quit(main_loop);
 
        return FALSE;
 }
 
-static void execute_login(struct wispr_session *wispr)
+static gboolean execute_login(gpointer user_data)
 {
+       struct wispr_session *wispr = user_data;
+
        wispr->request = g_web_request_post(wispr->web, wispr->msg.login_url,
                                        "application/x-www-form-urlencoded",
                                        wispr_input, wispr_result, wispr);
 
        wispr_msg_init(&wispr->msg);
+
+       return FALSE;
 }
 
 static gboolean option_debug = FALSE;
@@ -617,7 +697,7 @@ int main(int argc, char *argv[])
                                                parser_callback, &wispr);
 
        wispr.request = g_web_request_get(wispr.web, option_url,
-                                                       wispr_result, &wispr);
+                       wispr_result, wispr_route, &wispr);
 
        if (wispr.request == 0) {
                fprintf(stderr, "Failed to start request\n");