view ie-docker.c @ 20:c908e2c7315d

WIP: run command
author atton
date Tue, 24 Nov 2015 17:31:55 +0900
parents fe7095c365cf
children 8a086917cf1a
line wrap: on
line source

#include <stdlib.h>
#include <unistd.h>

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

#include <sys/types.h>
#include <regex.h>

#include "ie-docker.h"


void
get_port_number(const char *user_name, char const *project_name, char *port_number)
{
    FILE *fp = NULL;
    if ((fp = fopen(portlist_file, "r")) == NULL) {
        printf("[!] file open error\n");
    }

    // file format: portnumber,username,projectname
    char buff[BUFF_SIZE];
    char *port;
    int user_name_flag = 1;
    int project_name_flag = 1;
    while (fgets(buff, BUFF_SIZE, fp) != NULL) {
        buff[strlen(buff) - 1] = '\0';

        port = strtok(buff, ",");

        char *ret = strtok(NULL, ",");
        if (ret == NULL) continue;
        user_name_flag = strncmp(user_name, ret, BUFF_SIZE);

        ret = strtok(NULL, ",");
        if (ret == NULL) continue;
        project_name_flag = strncmp(project_name, ret, BUFF_SIZE);
        printf("project :%s\n", project_name);

        if (user_name_flag == 0 && project_name_flag == 0) {
            printf("port :%s\n", port);
            strncpy(port_number, port, PORT_LENGTH);
            break;
        }
    }
    fclose(fp);
    if (user_name_flag == 1 || project_name_flag == 1) {
        printf("[!] can't get port number for %s\n", user_name);
        exit(1);
    }
}

void
parse_exec_command(const int argc, char **argv, exec_command_opt *opt)
{
    int i = 2;
    int parse_ps_flag = 0;
    for (i = 2; i < argc; i++) {
        if (argv[i][0] == '-') {
            if (argv[i][1] == 't') {
                opt->tty = TRUE;
            } else if (argv[i][1] == 'i') {
                opt->interactive = TRUE;
            } else if (argv[i][1] == 'd') {
                opt->dettach = TRUE;
            }
        } else if (parse_ps_flag) {
            strncpy(opt->exec_ps_command, argv[i], 64);
        } else { // image name
            parse_ps_flag = 1;
            strncpy(opt->ps_name, argv[i], 16);
        }
    }
}

void
parse_run_command(const int argc, char **argv, run_command_opt *opt)
{
    int i = 2;
    int parse_image_flag = 0;
    for (i = 2; i < argc; i++) {
        if(strncmp(argv[i], "--name", 6) == 0) { // process name
            strncpy(opt->ps_name, argv[i + 1], 16);
            i++;
        } else if (argv[i][0] == '-') {
            if (argv[i][1] == 't') {
                opt->tty = TRUE;
            } else if (argv[i][1] == 'i') {
                opt->interactive = TRUE;
            } else if (argv[i][1] == 'd') {
                opt->dettach = TRUE;
            } else if (argv[i][1] == 'v') {
                strncpy(opt->volume, argv[i + 1], 128);
                i++;
            } else if (argv[i][1] == 'p') {
                strncpy(opt->innerport, argv[i + 1], 16);
                i++;
            }
        } else if (parse_image_flag) { // image name
            strncpy(opt->exec_ps_command, argv[i], 64);
        } else { // image name
            parse_image_flag = 1;
            strncpy(opt->image_name, argv[i], 16);
        }
    }
    /*
    printf("run command opt ::memory-%s innerport-%s outerport-%s tty-%d dettach-%d interactive-%d ps_name-%s exec_ps_command-%s volume-%s image-name-%s\n",
            opt->memory,
            opt->innerport,
            opt->outerport,
            opt->tty,
            opt->dettach,
            opt->interactive,
            opt->ps_name,
            opt->exec_ps_command,
            opt->volume,
            opt->image_name);
    */
}

PSLISTPTR
get_pslist(regex_t *list_pattern)
{
    PSLISTPTR list = NEW(PSLIST);
    PSLISTPTR p = list;
    p->name[0] = 0;
    p->next = 0;
    FILE *fp = popen(ps_command,"r");
    while(fgets(p->name,PSNAME_MAX,fp)!=NULL) {
        if (regexec(list_pattern, p->name, (size_t) 0, NULL, 0)) continue;
        p->next = NEW(PSLIST);
        p = p->next;
    }
    p->name[0] = 0;
    pclose(fp);

    return list;
}

void
print_pslist(PSLISTPTR list)
{
    for(;list && list->name[0]; list = list->next) {
        fprintf(stdout, "   %s\n",list->name);
    }
}

int
check_pslist_name(PSLISTPTR list, char *arg)
{
    for(;list && list->name[0]; list = list->next) {
        if (strstr(list->name,arg)!=0) return 1;
    }

    return 0;
}

int
check_name(const char *p)
{
    if (!p) return  1;
    for(;*p;p++) {
        char c = *p;
        if (c<=' ') return 1;
        if (('a'<=c && c<='z') ||
                ('0'<=c && c<='9') ||
                ('_'==c ) ||
                ('-'==c )) continue;
        return 1;
        printf("%c", c);
    }
    return 0;
}

void
bind_name(char *name, const char *first,  const char *second)
{
    strncat(name, first, PS_NAME_LENGTH);
    strncat(name, delimiter, PS_NAME_LENGTH);
    strncat(name, second, PS_NAME_LENGTH);
    strncat(name, delimiter, PS_NAME_LENGTH);
    return;
}

void
make_ps_name(char *ps_name, const int account_type, const char *account_name, const char *vm_num)
{
    switch(account_type) {
        case STUDENTS:
            strncat(ps_name, students_sym, PS_NAME_LENGTH);
            strncat(ps_name, delimiter, PS_NAME_LENGTH);
            strncat(ps_name, account_name, 3);
            strncat(ps_name, delimiter, PS_NAME_LENGTH);
            strncat(ps_name, account_name, PS_NAME_LENGTH);
            strncat(ps_name, delimiter, PS_NAME_LENGTH);
            break;
        case GUESTS:
            bind_name(ps_name, guests_sym, account_name);
            break;
        case MANAGERS:
            bind_name(ps_name, managers_sym, account_name);
            break;
        default :
            fprintf(stderr, "[!] Error: no registered type name.");
            return;
    }

    strncat(ps_name, vm_num, PS_NAME_LENGTH);
}

void
usage()
{
    printf("Usage: ie-docker\n");
    printf("\trun:    run process\n");
    printf("\tbuild:  build docker process from Dockerfile\n");
    printf("\tattach: attach process\n");
    printf("\tdettach: dettach process\n");
    printf("\timages: list images\n");
    printf("\tcommit: \n");
}

void
run_usage()
{
    printf("Usage:\tie-docker run\n");
    printf("\tie-docker [option] --name [ps_name] {image name}:{tag} [execute command] [argument]");
}

int
command_is_matched(const char const * arg, const char const * command)
{
    return strcmp(arg, command) == 0;
}

/* main(int argc, char **argv) - main process loop */

int
main(int argc, char **argv)
{
    int gid;
    int uid;

    /* Set euid and egid to actual user */

    char *name = getlogin();
    uid = getuid();
    gid = getgid();
    printf("uid %d gid %d name %s\n", uid,gid,name);
    setegid(getgid());
    seteuid(getuid());

    regex_t *pattern = NEW(regex_t);
    if (regcomp(pattern, name, 0) != 0) {
        exit(0);
    }

    /* Confirm user is in GROUP(999) group */

    /*
       if ( gid != 999 ) {
       printf("User Not Authorized!  Exiting...\n");
       exit(1);
       }
     */

    /* Set uid, gid, euid and egid to root */

    setegid(0);
    seteuid(0);
    setgid(0);
    setuid(0);

    if (argc < 2) {
        usage();
        exit(0);
    }

    /*
     * Check argv for proper arguments and run
     * the corresponding script, if invoked.
     */
    char *execl_command = malloc(sizeof(char) * 1024);

    if (command_is_matched(argv[1], ps_command)) {
        PSLISTPTR pslist = get_pslist(pattern);
        print_pslist(pslist); // TODO check work correctly
    } else if (command_is_matched(argv[1], run_command)) {
        sprintf(execl_command, "%s %s %s --name %s %s %s",
                base_exec_command, run_command, "-it -u 2015 ", name, "java-centos", "zsh");    //FIXME
        printf(execl_command); // TODO
    } else if (command_is_matched(argv[1], start_command)) {
        printf("start"); // TODO
    } else if (command_is_matched(argv[1], stop_command)) {
        printf("stop"); // TODO
    } else if (command_is_matched(argv[1], attach_command)) {
        printf("attach"); // TODO
    } else if (command_is_matched(argv[1], rm_command)) {
        printf("rm"); // TODO
    } else if (command_is_matched(argv[1], cp_command)) {
        printf("cp"); // TODO
    } else {
        usage();
        return 0;
    }
    free(execl_command);
    return 0;
}

/* end */