view ie-docker.c @ 27:3e6cf8f3aa62

Init file_path
author innparusu
date Tue, 05 Dec 2017 14:03:34 +0900
parents 8cabc269c3d6
children
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_exec_command,"r");

    /* get header */
    fgets(p->name,PSNAME_MAX,fp);
    p->next = NEW(PSLIST);
    p = p->next;

    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("  ps:        show running containers\n");
    printf("  run:       create new container\n");
    printf("  start:     start created container\n");
    printf("  stop:      stop running container\n");
    printf("  attach:    attach running container\n");
    printf("  cp <file>: copy file into container (/tmp) \n");
    printf("  rm:        delete container\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 *execv_args[16];
    char file_path[128] = "";

    if (command_is_matched(argv[1], ps_command)) {
        PSLISTPTR pslist = get_pslist(pattern);
        print_pslist(pslist); // TODO check work correctly
        return 0;
    } else if (command_is_matched(argv[1], run_command)) {
        execv_args[0] = base_exec_command;
        execv_args[1]  = run_command;
        execv_args[2]  = "-it";
        execv_args[3]  = "-u";
        execv_args[4]  = "2015";
        execv_args[5]  = "--name";
        execv_args[6]  = name;
        execv_args[7]  = "--ulimit";
        execv_args[8]  = "nproc=1024";
        execv_args[9]  = "--ulimit";
        execv_args[10] = "fsize=17179869184";
        execv_args[11] = base_image_name;
        execv_args[12] = run_shell;
        execv_args[13] = NULL;
    } else if (command_is_matched(argv[1], start_command)) {
        execv_args[0] = base_exec_command;
        execv_args[1] = start_command;
        execv_args[2] = name;
        execv_args[3] = NULL;
    } else if (command_is_matched(argv[1], stop_command)) {
        execv_args[0] = base_exec_command;
        execv_args[1] = stop_command;
        execv_args[2] = name;
        execv_args[3] = NULL;
    } else if (command_is_matched(argv[1], attach_command)) {
        execv_args[0] = base_exec_command;
        execv_args[1] = attach_command;
        execv_args[2] = name;
        execv_args[3] = NULL;
    } else if (command_is_matched(argv[1], rm_command)) {
        execv_args[0] = base_exec_command;
        execv_args[1] = rm_command;
        execv_args[2] = name;
        execv_args[3] = NULL;
    } else if (command_is_matched(argv[1], cp_command)) {
        if (argc<3) {
            printf("cp command requires file path\n");
            return 0;
        }
        execv_args[0] = base_exec_command;
        execv_args[1] = cp_command;
        execv_args[2] = argv[2];
        strcat(file_path, name);
        strcat(file_path, ":");
        strcat(file_path, cp_file_path);
        execv_args[3] = file_path;
        execv_args[4] = NULL;
    } else {
        usage();
        return 0;
    }

    int i;
    for (i = 0; execv_args[i] != NULL; i++) {
        printf("%s", execv_args[i]);
        printf(execv_args[i+1] != NULL ? " " : "\n");
    }
    execv(base_exec_command, execv_args);
    return 0;
}

/* end */