コード例 #1
0
ファイル: file.c プロジェクト: emiddleton/sky
// Recursively copies a directory.
//
// src  - The path of the file or directory to copy.
// dest - The path where the copy should be placed.
//
// Returns 0 if successful, otherwise returns -1.
int sky_file_cp_r(bstring src, bstring dest)
{
    int rc;
    bstring ent_src = NULL;
    bstring ent_dest = NULL;
    check(src != NULL, "Source path required");
    check(dest != NULL, "Destination path required");
    check(sky_file_exists(src), "Source file does not exist");

    // If this is a directory then create a new dest directory and copy the
    // contents.
    if(sky_file_is_dir(src)) {
        // Create destination directory if it doesn't exist.
        if(!sky_file_exists(dest)) {
            struct stat st;
            rc = stat(bdata(src), &st);
            check(rc == 0, "Unable to stat source directory: %s", bdata(src));
            rc = mkdir(bdata(dest), st.st_mode);
            check(rc == 0, "Unable to create directory: %s", bdata(dest));
        }
        
        // Open directory.
        DIR *dir = opendir(bdata(src));
        check(dir != NULL, "Unable to open directory: %s", bdata(src));
        
        // Copy over contents of directory.
        struct dirent *ent;
        while((ent = readdir(dir))) {
            if(strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0) {
                ent_src  = bformat("%s/%s", bdata(src), ent->d_name); check_mem(ent_src);
                ent_dest = bformat("%s/%s", bdata(dest), ent->d_name); check_mem(ent_dest);

                rc = sky_file_cp_r(ent_src, ent_dest);
                check(rc == 0, "Unable to copy: %s", bdata(ent_src));

                bdestroy(ent_src);
                bdestroy(ent_dest);
            }
        }
        
        // Close directory.
        closedir(dir);
    }
    // If this is a file then copy its contents.
    else {
        rc = sky_file_cp(src, dest);
        check(rc == 0, "Unable to copy file: %s", bdata(src));
    }
    
    return 0;

error:
    bdestroy(ent_src);
    bdestroy(ent_dest);
    return -1;
}
コード例 #2
0
ファイル: delete_table_message.c プロジェクト: fxstein/sky
// Deletes a table to the server. This function is synchronous and does not use
// a worker.
//
// server - The server.
// header - The message header.
// table  - The table the message is working against
// input  - The input file stream.
// output - The output file stream.
//
// Returns 0 if successful, otherwise returns -1.
int sky_delete_table_message_process(sky_server *server,
                                     sky_message_header *header,
                                     sky_table *_table, FILE *input, FILE *output)
{
    int rc = 0;
    size_t sz;
    sky_delete_table_message *message = NULL;
    sky_table *table = NULL;
    bstring path = NULL;
    check(server != NULL, "Server required");
    check(header != NULL, "Message header required");
    check(input != NULL, "Input stream required");
    check(output != NULL, "Output stream required");
    (void)_table;
    
    struct tagbstring status_str = bsStatic("status");
    struct tagbstring ok_str = bsStatic("ok");

    // Parse message.
    message = sky_delete_table_message_create(); check_mem(message);
    rc = sky_delete_table_message_unpack(message, input);
    check(rc == 0, "Unable to parse 'delete_table' message");

    // Retrieve table reference from server.
    rc = sky_server_get_table(server, message->name, &table);
    check(rc == 0, "Unable to find table: %s", bdata(message->name));
    check(table != NULL, "Table does not exist: %s", bdata(message->name));

    // Detach table first.
    path = bstrcpy(table->path); check_mem(path);
    rc = sky_server_close_table(server, table);
    check(rc == 0, "Unable to close table before deletion");

    // If the table exists then delete it.
    if(sky_file_exists(path)) {
        rc = sky_file_rm_r(path);
        check(rc == 0, "Unable to delete table: %s", bdata(path));
    }
    
    // Return.
    //   {status:"OK"}
    minipack_fwrite_map(output, 1, &sz);
    check(sz > 0, "Unable to write output");
    check(sky_minipack_fwrite_bstring(output, &status_str) == 0, "Unable to write status key");
    check(sky_minipack_fwrite_bstring(output, &ok_str) == 0, "Unable to write status value");

    fclose(input);
    fclose(output);
    bdestroy(path);
    sky_delete_table_message_free(message);
    
    return 0;

error:
    if(input) fclose(input);
    if(output) fclose(output);
    bdestroy(path);
    sky_delete_table_message_free(message);
    return -1;
}
コード例 #3
0
ファイル: table_tests.c プロジェクト: emiddleton/sky
int test_sky_table_open() {
    struct tagbstring lock_file_path = bsStatic("tmp/.skylock");
    struct tagbstring data_file_path = bsStatic("tmp/0/data");
    struct tagbstring header_file_path = bsStatic("tmp/0/header");
    cleantmp();
    
    int rc;
    sky_table *table = sky_table_create();
    table->path = bfromcstr("tmp");
    
    // Open table.
    rc = sky_table_open(table);
    mu_assert_int_equals(rc, 0);
    mu_assert(sky_file_exists(&lock_file_path), "");
    mu_assert(sky_file_exists(&data_file_path), "");
    mu_assert(sky_file_exists(&header_file_path), "");
    
    // Close table.
    rc = sky_table_close(table);
    mu_assert_int_equals(rc, 0);
    mu_assert(!sky_file_exists(&lock_file_path), "");
    mu_assert(sky_file_exists(&data_file_path), "");
    mu_assert(sky_file_exists(&header_file_path), "");

    sky_table_free(table);
    return 0;
}
コード例 #4
0
int test_sky_create_table_message_process() {
    cleantmp();
    sky_server *server = sky_server_create(NULL);
    server->path = bfromcstr("tmp");
    sky_message_header *header = sky_message_header_create();

    FILE *input = fopen("tests/fixtures/create_table_message/1/input", "r");
    FILE *output = fopen("tmp/output", "w");
    int rc = sky_create_table_message_process(server, header, NULL, input, output);
    mu_assert_int_equals(rc, 0);
    
    struct tagbstring foo_db_path = bsStatic("tmp/foo");
    struct tagbstring foo_db_0_path = bsStatic("tmp/foo/0");
    struct tagbstring foo_db_9_path = bsStatic("tmp/foo/9");
    mu_assert_bool(sky_file_exists(&foo_db_path));
    mu_assert_bool(sky_file_exists(&foo_db_0_path));
    mu_assert_bool(sky_file_exists(&foo_db_9_path));
    mu_assert_file("tmp/output", "tests/fixtures/create_table_message/1/output");

    sky_message_header_free(header);
    sky_server_free(server);
    return 0;
}
コード例 #5
0
ファイル: file.c プロジェクト: emiddleton/sky
// Deletes a single file.
//
// path - The path of the file to delete.
//
// Returns 0 if successful, otherwise returns -1.
int sky_file_rm(bstring path)
{
    int rc;
    check(path != NULL, "Path required");
    check(!sky_file_is_dir(path), "File cannot be a directory");

    if(sky_file_exists(path)) {
        rc = remove(bdata(path));
        check(rc == 0, "Unable to delete file");
    }

    return 0;

error:
    return -1;
}
コード例 #6
0
ファイル: file.c プロジェクト: emiddleton/sky
// Recursively deletes a file or directory.
//
// path  - The path of the file or directory to delete.
//
// Returns 0 if successful, otherwise returns -1.
int sky_file_rm_r(bstring path)
{
    int rc;
    bstring ent_path = NULL;
    check(path != NULL, "Path required");
    
    // If path doesn't exist then just ignore it.
    if(sky_file_exists(path)) {
        // If the file is a directory then delete its contents first and then
        // delete it.
        if(sky_file_is_dir(path)) {
            // Open directory.
            DIR *dir = opendir(bdata(path));
            check(dir != NULL, "Unable to open directory: %s", bdata(path));

            // Remove each file inside directory.
            struct dirent *ent;
            while((ent = readdir(dir))) {
                if(strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0) {
                    ent_path  = bformat("%s/%s", bdata(path), ent->d_name); check_mem(ent_path);
                    rc = sky_file_rm_r(ent_path);
                    check(rc == 0, "Unable to delete: %s", bdata(ent_path));
                    bdestroy(ent_path);
                }
            }

            // Close directory.
            closedir(dir);

            // Remove directory.
            remove(bdata(path));
        }
        // If this is a file then delete it.
        else {
            rc = sky_file_rm(path);
            check(rc == 0, "Unable to delete file: %s", bdata(path));
        }
    }
    
    return 0;

error:
    bdestroy(ent_path);
    return -1;
}
コード例 #7
0
ファイル: server.c プロジェクト: gitaccount2/sky
// Opens a table and attaches it to the server.
//
// server - The server.
// name   - The table name.
// path   - The table path.
// ret    - A pointer to where the table reference should be returned.
//
// Returns 0 if successful, otherwise returns -1.
int sky_server_open_table(sky_server *server, bstring name, bstring path,
                          sky_table **ret)
{
    int rc;
    sky_table *table = NULL;
    assert(server != NULL);
    assert(ret != NULL);
    check(blength(path) > 0, "Table path required");
    
    // Initialize return values.
    *ret = NULL;
    
    // Only open the table if it exists already.
    if(sky_file_exists(path)) {
        // Create the table.
        table = sky_table_create(); check_mem(table);
        table->name = bstrcpy(name); check_mem(table->name);
        rc = sky_table_set_path(table, path);
        check(rc == 0, "Unable to set table path");

        // Open the table.
        rc = sky_table_open(table);
        check(rc == 0, "Unable to open table");
    
        // Append the table to the list of open tables.
        server->table_count++;
        server->tables = realloc(server->tables, server->table_count * sizeof(*server->tables));
        check_mem(server->tables);
        server->tables[server->table_count-1] = table;

        // Open servlets for the table's tablets.
        rc = sky_server_create_servlets(server, table);
        check(rc == 0, "Unable to create servlets for table");

        // Return table.
        *ret = table;
    }

    return 0;

error:
    sky_table_free(table);
    if(ret) *ret = NULL;
    return -1;
}
コード例 #8
0
ファイル: file.c プロジェクト: emiddleton/sky
// Copies a single file from the source path to the destination path.
//
// src  - The path of the file to copy.
// dest - The path where the copy should be placed.
//
// Returns 0 if successful, otherwise returns -1.
int sky_file_cp(bstring src, bstring dest)
{
    int rc;
    check(src != NULL, "Source path required");
    check(dest != NULL, "Destination path required");
    check(sky_file_exists(src), "Source file does not exist");
    check(!sky_file_is_dir(src), "Source file cannot be a directory");

    // Open source files.
    FILE *src_file = fopen(bdata(src), "r");
    check(src_file != NULL, "Unable to open source file for reading");

    // Open destination file.
    FILE *dest_file = fopen(bdata(dest), "w");
    check(dest_file != NULL, "Unable to open destination file for writing");
    
    // Read from source and write to destination until done.
    while(!feof(src_file)) {
        int buffer_size = 1024;
        char *buffer[buffer_size];
        
        size_t sz = fread(buffer, sizeof(char), buffer_size, src_file);
        fwrite(buffer, sizeof(char), sz, dest_file);
    }
    
    // Close files.
    fclose(src_file);
    fclose(dest_file);
    
    // Copy permissions to destination file.
    struct stat st;
    stat(bdata(src), &st);
    rc = chmod(bdata(dest), st.st_mode);
    check(rc == 0, "Unable to copy permissions");
    
    return 0;

error:
    return -1;
}
コード例 #9
0
ファイル: table.c プロジェクト: hongfei1988/sky
// Initializes and opens the data file on the table.
//
// table - The table to initialize the data file for.
//
// Returns 0 if successful, otherwise returns -1.
int sky_table_load_data_file(sky_table *table)
{
    int rc;
    check(table != NULL, "Table required");
    check(table->path != NULL, "Table path required");

    // Unload any existing data file.
    sky_table_unload_data_file(table);

    // Initialize table space (0).
    bstring tablespace_path = bformat("%s/0", bdata(table->path));
    if(!sky_file_exists(tablespace_path)) {
        rc = mkdir(bdata(tablespace_path), S_IRWXU);
        check(rc == 0, "Unable to create tablespace directory: %s", bdata(tablespace_path));
    }
    bdestroy(tablespace_path);

    // Initialize data file.
    table->data_file = sky_data_file_create();
    check_mem(table->data_file);
    table->data_file->path = bformat("%s/0/data", bdata(table->path));
    check_mem(table->data_file->path);
    table->data_file->header_path = bformat("%s/0/header", bdata(table->path));
    check_mem(table->data_file->header_path);

    // Initialize settings on the block.
    if(table->default_block_size > 0) {
        table->data_file->block_size = table->default_block_size;
    }

    // Load data
    rc = sky_data_file_load(table->data_file);
    check(rc == 0, "Unable to load data file");

    return 0;
error:
    bdestroy(tablespace_path);
    sky_table_unload_data_file(table);
    return -1;
}
コード例 #10
0
ファイル: table.c プロジェクト: hongfei1988/sky
// Opens the table for reading and writing events.
//
// table - The table to open.
//
// Returns 0 if successful, otherwise returns -1.
int sky_table_open(sky_table *table)
{
    int rc;
    check(table != NULL, "Table required");
    check(table->path != NULL, "Table path is required");
    check(!table->opened, "Table is already open");

    // Create directory if it doesn't exist.
    if(!sky_file_exists(table->path)) {
        rc = mkdir(bdata(table->path), S_IRWXU);
        check(rc == 0, "Unable to create table directory: %s", bdata(table->path));
    }

    // Obtain a lock.
    rc = sky_table_lock(table);
    check(rc == 0, "Unable to obtain lock");

    // Load data file.
    rc = sky_table_load_data_file(table);
    check(rc == 0, "Unable to load data file");

    // Load action file.
    rc = sky_table_load_action_file(table);
    check(rc == 0, "Unable to load action file");

    // Load property file.
    rc = sky_table_load_property_file(table);
    check(rc == 0, "Unable to load property file");

    // Flag the table as open.
    table->opened = true;

    return 0;

error:
    sky_table_close(table);
    return -1;
}
コード例 #11
0
ファイル: action_file.c プロジェクト: emiddleton/sky
// Loads actions from file.
//
// action_file - The action file to load.
//
// Returns 0 if successful, otherwise returns -1.
int sky_action_file_load(sky_action_file *action_file)
{
    int rc;
    size_t sz;
    uint32_t count = 0;
    FILE *file = NULL;
    sky_action **actions = NULL;
    assert(action_file != NULL);
    check(action_file->path != NULL, "Action file path required");

    // Unload any actions currently in memory.
    rc = sky_action_file_unload(action_file);
    check(rc == 0, "Unable to unload action file");

    // Read in actions file if it exists.
    if(sky_file_exists(action_file->path)) {
        file = fopen(bdata(action_file->path), "r");
        check(file, "Failed to open action file: %s",  bdata(action_file->path));

        // Read action count.
        count = minipack_fread_array(file, &sz);
        check(sz != 0, "Unable to read actions array at byte: %ld", ftell(file));

        // Allocate actions.
        if(count > 0) {
            actions = malloc(sizeof(sky_action*) * count);
            check_mem(actions);
        }

        // Read actions.
        uint32_t i;
        for(i=0; i<count; i++) {
            sky_action *action = sky_action_create();
            check_mem(action);

            // Read action id.
            action->id = (sky_action_id_t)minipack_fread_uint(file, &sz);
            check(sz != 0, "Unable to read action identifier at byte: %ld", ftell(file));

            // Read action name.
            rc = sky_minipack_fread_bstring(file, &action->name);
            check(rc == 0, "Unable to read action name at byte: %ld", ftell(file));

            // Append to array.
            action->action_file = action_file;
            actions[i] = action;
        }

        // Close the file.
        fclose(file);
    }

    // Store action list on action file.
    action_file->actions = actions;
    action_file->action_count = count;

    return 0;

error:
    if(file) fclose(file);
    if(actions) free(actions);
    return -1;
}