view ie-cloud.c @ 0:61bc8410d480

add files
author taiki
date Wed, 11 Feb 2015 20:23:09 +0900
parents
children 8de3ca550e8f
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-cloud.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); 

        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", user_name);
        exit(1);
    }
}


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;
}

int
check_user_name(const char *account_name)
{
    const char *regex = "[ek]([0-9]{6})";

    regex_t *pattern = NEW(regex_t);
    int ret = 1;

    if (regcomp(pattern, regex, REG_EXTENDED|REG_NEWLINE) != 0) {
        exit(0);
    }

    ret = regexec(pattern, account_name, (size_t) 0, NULL, 0);
    regfree(pattern);

    if (!ret) {
        return STUDENTS;
    }

    ret = regexec(pattern, account_name, (size_t) 0, NULL, 0);
    regfree(pattern);

    const int managers_num = sizeof(managers) / sizeof(managers[0]);
    int i = 0;

    for (; i< managers_num; i++) {
        if (strncmp(account_name, managers[i], NAME_LENGTH) == 0) {
            return MANAGERS;
        }
    }

    const int guests_num = sizeof(guests) / sizeof(guests[0]);
    int j = 0;

    for (; j< guests_num; j++) {
        if (strncmp(account_name, guests[j], NAME_LENGTH) == 0) {
            return GUESTS;
        }
    }

    return -1;
}

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]");
}

/* 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());

    int account_type = check_user_name(name);
    if (account_type < 0) {
        fprintf(stderr, "[!] Permission denied. :%s\n", name);
    }

    /* 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 */

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

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

    if (strncmp(argv[1], create_command, 6) == 0) {
        char exec[512];
        sprintf(exec, "/usr/local/bin/create.py %s", argv[2]);
        system(exec);
        exit(1);
    }

    char *ps_name = (char *)malloc(sizeof(char) * PS_NAME_LENGTH);
    if (ps_name == NULL) {
        printf("[!] malloc error.");
    }
    ps_name[0] = '\0';

    run_command_opt *opt = (run_command_opt *)malloc(sizeof(run_command_opt));
    if (opt == NULL) {
        printf("[!] malloc error.");
    }
    opt->tty = FALSE;
    opt->dettach = FALSE;
    opt->interactive = FALSE;

    if (strncmp(argv[1], "ps", 4) != 0) {
        if (strncmp(argv[1], "run", 3) == 0) {
            parse_run_command(argc, argv, opt);
            if (check_name(opt->ps_name)) {
                fprintf(stderr, bad_name);
                exit(0);
            }
            get_port_number(name, opt->ps_name, opt->outerport);
            strncpy(ps_name, opt->ps_name, 64);
            opt->ps_name[0] = '\0';
            make_ps_name(opt->ps_name, account_type, name, ps_name);
        } else {
            make_ps_name(ps_name, account_type, name, argv[2]);
        }
        printf("process name : %s\n", opt->ps_name);
    }

    PSLISTPTR pslist = get_pslist(pattern);

    /* 
     * Check argv for proper arguments and run 
     * the corresponding script, if invoked.
     */

    if (argv[1]==0 || strncmp(argv[1], "ps", 4) == 0 ) {
        print_pslist(pslist);
    } else if (strncmp(argv[1], run_command, 5) == 0) {

        char *args[16];
        int i = 0;

        args[i++] = command;
        args[i++] = run_command;
        if (opt->dettach) args[i++] = "-d";
        if (opt->tty) args[i++] = "-t";
        if (opt->interactive) args[i++] = "-i";
        args[i++] = "-m";
        args[i++] = "512m";
        args[i++] = "-v";
        args[i++] = opt->volume;
        args[i++] = "-p";
        char port[32];
        sprintf(port, "%s:%s", opt->outerport, opt->innerport);
        args[i++] = port;
        args[i++] = "--name";
        args[i++] = opt->ps_name;
        args[i++] = opt->image_name;
        args[i++] = opt->exec_ps_command;
        args[i++] = NULL;
	/*
    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);

*/
        if (execv(args[0], args) < 0) {
            perror("[!] Execv:");
        }
    } else if (strncmp(argv[1], start_command, 5) == 0) {
        if (execl(command, command, start_command, ps_name,  NULL) < 0) {
            perror("[!] Execl:");
        }
    } else if (strncmp(argv[1], exec_command, 5) == 0) {
        if (execl(command, command, exec_command, argv[2], argv[3], argv[4], NULL) < 0) {
            perror("[!] Execl:");
        }
    } else if ( strncmp(argv[1], stop_command, 4) == 0 ) {
        if (execl(command, command, stop_command, ps_name, NULL) < 0) {
            perror("[!] Execl:");
        }
    } else if ( strncmp(argv[1], build_command, 8) == 0 ) {
        if (execl(command, command, build_command, argv[2], NULL) < 0) {
            perror("[!] Execl:");
        }
    } else if (strncmp(argv[1], attach_command, 6) == 0 ) {
        if (execl(command, command, attach_command, ps_name, NULL) < 0) {
            perror("[!] Execl:");
        }
    } else if ( strncmp(argv[1], rm_command, 2) == 0 ) {
        if (execl(command, command, rm_command, ps_name, NULL) < 0) {
            perror("[!] Execl:");
        }
    } else {
        usage();
    }
    free(ps_name);
    free(opt);
    exit(0);
}

/* end */