view ie-docker.c @ 11:5e2df576a42d

add new command 'create' to ie-docker, create is make new repository for ie-docker.
author taira
date Mon, 26 Jan 2015 13:20:35 +0900
parents 9d6fb0a1aa53
children 1730494d9ecc
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>

/* Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License */

#define command "/usr/bin/docker"
#define ps_command "/usr/bin/docker ps -a"
#define run_command "run"
#define build_command "build"
#define attach_command "attach"
#define dettach_command "dettach"
// #define pull_command "pull" /* download docker image command */
#define images_command "images" /* list images command */
#define commit_command "commit" /* make image command */
#define rm_command "rm" /* remove container command */
#define rmi_command "rmi" /* remove image command */
#define start_command "start" 
#define stop_command "stop" 
#define exec_command "exec"

#define create_command "create"

static char bad_name[] = "Bad process name. Try students_e11_e115711_01 or teachers_kono_02\n";

const char *guests[] = {"mata"};
const char *managers[] = {"taira"};
const char students_sym[] = "students";
const char managers_sym[] = "managers";
const char guests_sym[] = "guests";
const char delimiter[] = "_";

enum { 
    NAME_LENGTH = 50,
    PS_NAME_LENGTH = 50
};

enum { 
    STUDENTS,
    GUESTS,
    MANAGERS
};

#define PSNAME_MAX (512)

typedef struct pslist {
    char name[PSNAME_MAX];
    struct pslist *next;
} PSLIST, *PSLISTPTR;

#define NEW(type)  ((type*)malloc(sizeof(type)))

/* Define global variables */

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 [process_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);
    ps_name[0] = '\0';
    if (strncmp(argv[1], "ps", 4) != 0) {
        if (strncmp(argv[1], "run", 3) == 0) {
            make_ps_name(ps_name, account_type, name, argv[4]);
        } else {
            make_ps_name(ps_name, account_type, name, argv[2]);
        }
        printf("%s", ps_name);
    }

    if (argc >= 3) {
        if (strncmp(argv[1], run_command, 6) == 0 ) {
            if (strncmp(argv[3], "--name", 6) != 0) {
                run_usage();
                exit(0);
            }

            if (check_name(argv[4])) {
                fprintf(stderr, bad_name);
                exit(0);
            }
        }
    }

    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) {
        if (execl(command, command, run_command, argv[2], argv[3], ps_name, argv[5], argv[6], argv[7], NULL) < 0) {
            perror("Execl:");
        }
    } else if (strncmp(argv[1], start_command, 5) == 0) {
        if (execl(command, command, start_command, argv[2], 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, argv[2], 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, NULL) < 0) {
            perror("Execl:");
        }
    } else if ( strncmp(argv[1], dettach_command, 8) == 0 ) {
        if (execl(command, command, dettach_command, argv[2], 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();
        exit(1);
    }
    exit(0);
}

/* end */