/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>

#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>

#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>

static void usage(char *progname);
static int do_monitor(int sock, int stop_after_cmd);
static int do_cmd(int sock, int argc, char **argv);

int main(int argc, char **argv) {
    int sock;
    int cmdOffset = 0;

    if (argc < 2)
        usage(argv[0]);

    // try interpreting the first arg as the socket name - if it fails go back to netd

    if ((sock = socket_local_client(argv[1],
                                     ANDROID_SOCKET_NAMESPACE_RESERVED,
                                     SOCK_STREAM)) < 0) {
        if ((sock = socket_local_client("netd",
                                         ANDROID_SOCKET_NAMESPACE_RESERVED,
                                         SOCK_STREAM)) < 0) {
            fprintf(stderr, "Error connecting (%s)\n", strerror(errno));
            exit(4);
        }
    } else {
        if (argc < 3) usage(argv[0]);
        printf("Using alt socket %s\n", argv[1]);
        cmdOffset = 1;
    }

    if (!strcmp(argv[1+cmdOffset], "monitor"))
        exit(do_monitor(sock, 0));
    exit(do_cmd(sock, argc-cmdOffset, &(argv[cmdOffset])));
}

static int do_cmd(int sock, int argc, char **argv) {
    char *final_cmd;
    char *conv_ptr;
    int i;

    /* Check if 1st arg is cmd sequence number */ 
    strtol(argv[1], &conv_ptr, 10);
    if (conv_ptr == argv[1]) {
        final_cmd = strdup("0 ");
    } else {
        final_cmd = strdup("");
    }
    if (final_cmd == NULL) {
        int res = errno;
        perror("strdup failed");
        return res;
    }

    for (i = 1; i < argc; i++) {
        if (index(argv[i], '"')) {
            perror("argument with embedded quotes not allowed");
            free(final_cmd);
            return 1;
        }
        bool needs_quoting = index(argv[i], ' ');
        const char *format = needs_quoting ? "%s\"%s\"%s" : "%s%s%s";
        char *tmp_final_cmd;

        if (asprintf(&tmp_final_cmd, format, final_cmd, argv[i],
                     (i == (argc - 1)) ? "" : " ") < 0) {
            int res = errno;
            perror("failed asprintf");
            free(final_cmd);
            return res;
        }
        free(final_cmd);
        final_cmd = tmp_final_cmd;
    }

    if (write(sock, final_cmd, strlen(final_cmd) + 1) < 0) {
        int res = errno;
        perror("write");
        free(final_cmd);
        return res;
    }
    free(final_cmd);

    return do_monitor(sock, 1);
}

static int do_monitor(int sock, int stop_after_cmd) {
    char *buffer = malloc(4096);

    if (!stop_after_cmd)
        printf("[Connected to Netd]\n");

    while(1) {
        fd_set read_fds;
        struct timeval to;
        int rc = 0;

        to.tv_sec = 10;
        to.tv_usec = 0;

        FD_ZERO(&read_fds);
        FD_SET(sock, &read_fds);

        if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) {
            int res = errno;
            fprintf(stderr, "Error in select (%s)\n", strerror(errno));
            free(buffer);
            return res;
        } else if (!rc) {
            continue;
            fprintf(stderr, "[TIMEOUT]\n");
            return ETIMEDOUT;
        } else if (FD_ISSET(sock, &read_fds)) {
            memset(buffer, 0, 4096);
            if ((rc = read(sock, buffer, 4096)) <= 0) {
                int res = errno;
                if (rc == 0)
                    fprintf(stderr, "Lost connection to Netd - did it crash?\n");
                else
                    fprintf(stderr, "Error reading data (%s)\n", strerror(errno));
                free(buffer);
                if (rc == 0)
                    return ECONNRESET;
                return res;
            }

            int offset = 0;
            int i = 0;

            for (i = 0; i < rc; i++) {
                if (buffer[i] == '\0') {
                    int code;
                    char tmp[4];

                    strncpy(tmp, buffer + offset, 3);
                    tmp[3] = '\0';
                    code = atoi(tmp);

                    printf("%s\n", buffer + offset);
                    if (stop_after_cmd) {
                        if (code >= 200 && code < 600)
                            return 0;
                    }
                    offset = i + 1;
                }
            }
        }
    }
    free(buffer);
    return 0;
}

static void usage(char *progname) {
    fprintf(stderr, "Usage: %s [<sockname>] ([monitor] | ([<cmd_seq_num>] <cmd> [arg ...]))\n", progname);
    exit(1);
}
