示例#1
0
bool do_uninstall(CURL* curl, bstring name)
{
    bstring modpath = osutil_getmodulepath();
    struct stat buffer;

    // Append the file name.
    bconchar(modpath, '/');
    bconcat(modpath, name);
    bcatcstr(modpath, ".lua");

    // Check to see if the module is installed.
    if (stat(modpath->data, &buffer) == 0)
    {
        if (unlink(modpath->data) == 0)
            printd(LEVEL_DEFAULT, "removed existing %s module.\n", name->data);
        else
        {
            printd(LEVEL_ERROR, "unable to remove existing %s module.\n", name->data);
            return 1;
        }
    }
    else
        printd(LEVEL_WARNING, "module %s is not installed.\n", name->data);

    return 0;
}
示例#2
0
bool do_install(CURL* curl, bstring name)
{
    FILE* fp;
    CURLcode res;
    long httpcode = 0;
    struct stat buffer;
    bstring url = bfromcstr("http://dms.dcputoolcha.in/modules/download?name=");
    bstring modpath = osutil_getmodulepath();

    // Append the file name.
    bconchar(modpath, '/');
    bconcat(modpath, name);
    bcatcstr(modpath, ".lua");
    bconcat(url, name);
    bcatcstr(url, ".lua");

    // Check to see if the module is already installed.
    if (stat(modpath->data, &buffer) == 0)
    {
        if (unlink(modpath->data) == 0)
            printd(LEVEL_WARNING, "removed existing %s module.\n", name->data);
        else
        {
            printd(LEVEL_ERROR, "unable to remove existing %s module.\n", name->data);
            return 1;
        }
    }

    // Open the file and do the cURL transfer.
    printd(LEVEL_DEFAULT, "querying module repository...\n");
    fp = fopen(modpath->data, "wb");
    curl_easy_setopt(curl, CURLOPT_URL, url->data);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
    res = curl_easy_perform(curl);
    curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode);
    if (res != 0 && httpcode != 200)
    {
        bdestroy(url);
        bdestroy(name);
        bdestroy(modpath);
        printd(LEVEL_ERROR, "curl failed with error code %i, HTTP error code %i.\n", res, httpcode);
        return 1;
    }
    fclose(fp);
    printd(LEVEL_DEFAULT, "module %s installed.\n", name->data);

    return 0;
}
示例#3
0
bool do_uninstall_all(CURL* curl)
{
    // define used variables
    DIR* dir;
    bool something_was_removed;
    struct dirent* entry;
    bstring fname, sstr;
    bstring ext = bfromcstr(".lua");
    bstring modpath = osutil_getmodulepath();

    // Attempt to open the modules directory.
    dir = opendir(modpath->data);
    if (dir == NULL)
    {
        printd(LEVEL_ERROR, "unable to query local repository.\n");
        return 1;
    }
    bdestroy(modpath);

    // iterate through the installed modules
    something_was_removed = false;
    while ((entry = readdir(dir)) != NULL)
    {
        fname = bfromcstr(&entry->d_name[0]);
        if (binstr(fname, blength(fname) - 4, ext) == BSTR_ERR)
        {
            bdestroy(fname);
            continue;
        }
        if (entry->d_type != DT_REG)
        {
            bdestroy(fname);
            continue;
        }
        sstr = bmidstr(fname, 0, blength(fname) - 4);
        do_uninstall(curl, bfromcstr(sstr->data));
        something_was_removed = true;
        bdestroy(sstr);
        bdestroy(fname);
    }
    if (!something_was_removed)
        printd(LEVEL_DEFAULT, "No changes were made.\n");

    return 0;
}
示例#4
0
int main(int argc, char* argv[])
{
    CURL* curl;
    bstring command;
    bstring name;
    bstring modpath;
    int all;

    // Define arguments.
    struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
    struct arg_str* cmdopt = arg_str1(NULL, NULL, "<command>", "The command; either 'search', 'install', 'uninstall', 'enable' or 'disable'.");
    struct arg_str* nameopt = arg_str0(NULL, NULL, "<name>", "The name of the module to search for, install, uninstall, enable or disable.");
    struct arg_lit* all_flag = arg_lit0("a", "all", "Apply this command to all available / installed modules.");
    struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity.");
    struct arg_lit* quiet = arg_litn("q", NULL,  0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity.");
    struct arg_end* end = arg_end(20);
    void* argtable[] = { show_help, cmdopt, all_flag, nameopt, verbose, quiet, end };

    // Parse arguments.
    int nerrors = arg_parse(argc, argv, argtable);

    if (nerrors != 0 || show_help->count != 0 || (all_flag->count == 0 && nameopt->count == 0))
    {
        if (all_flag->count == 0 && nameopt->count == 0)
            printd(LEVEL_ERROR, "error: must have either module name or -a.");
        if (show_help->count != 0)
            arg_print_errors(stderr, end, "mm");

        fprintf(stderr, "syntax:\n    dtmm");
        arg_print_syntax(stderr, argtable, "\n");
        fprintf(stderr, "options:\n");
        arg_print_glossary(stderr, argtable, "    %-25s %s\n");
        arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
        return 1;
    }

    // Set verbosity level.
    debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);
    
    // Show version information.
    version_print(bautofree(bfromcstr("Module Manager")));

    // Set argument 0 and convert parameters.
    osutil_setarg0(bautofree(bfromcstr(argv[0])));
    command = bfromcstr(cmdopt->sval[0]);
    name = bfromcstr(nameopt->sval[0]);

    // Initialize curl or exit.
    curl = curl_easy_init();
    if (!curl)
    {
        printd(LEVEL_ERROR, "unable to initialize curl.\n");
        return 1;
    }

    // Ensure module path exists.
    modpath = osutil_getmodulepath();
    if (modpath == NULL)
    {
        printd(LEVEL_ERROR, "module path does not exist (searched TOOLCHAIN_MODULES and modules/).\n");
        return 1;
    }
    bdestroy(modpath);

    // Convert all flag.
    all = (all_flag->count > 0);

    // If all is set, set the name back to "".
    if (all)
        bassigncstr(name, "");

    // If the name is "all" or "*", handle this as the all
    // boolean flag.
    if (biseqcstr(name, "all") || biseqcstr(name, "*"))
    {
        bassigncstr(name, "");
        all = 1;
        printd(LEVEL_WARNING, "treating name as -a (all) flag");
    }

    if (biseqcstrcaseless(command, "search") || biseqcstrcaseless(command, "se"))
        return do_search(curl, name, all);
    else if (biseqcstrcaseless(command, "install") || biseqcstrcaseless(command, "in"))
    {
        if (all)
            return do_install_all(curl);
        else
            return do_install(curl, name);
    }
    else if (biseqcstrcaseless(command, "uninstall") || biseqcstrcaseless(command, "rm"))
    {
        if (all)
            return do_uninstall_all(curl);
        else
            return do_uninstall(curl, name);
    }
    else if (biseqcstrcaseless(command, "enable") || biseqcstrcaseless(command, "en"))
    {
        if (all)
            return do_enable_all(curl);
        else
            return do_enable(curl, name);
    }
    else if (biseqcstrcaseless(command, "disable") || biseqcstrcaseless(command, "di") || biseqcstrcaseless(command, "dis"))
    {
        if (all)
            return do_disable_all(curl);
        else
            return do_disable(curl, name);
    }
    else
    {
        printd(LEVEL_ERROR, "unknown command (must be search, install, uninstall, enable or disable).");
        return 1;
    }

    return 0;
}
示例#5
0
bool do_search(CURL* curl, bstring name, bool all)
{
    DIR* dir;
    bool printed;
    CURLcode res;
    FILE* fp;
    list_t installed;
    struct bStream* stream;
    long httpcode = 0;
    bstring buffer, fname, sstr;
    bstring ext = bfromcstr(".lua");
    bstring url = bfromcstr("http://dms.dcputoolcha.in/modules/search?q=");
    bstring modpath = osutil_getmodulepath();
    struct dirent* entry;
    list_init(&installed);
    list_attributes_copy(&installed, list_meter_string, 1);
    list_attributes_comparator(&installed, list_comparator_string);

    // Attempt to open the modules directory.
    dir = opendir(modpath->data);
    if (dir == NULL)
    {
        printd(LEVEL_ERROR, "unable to query local repository.\n");
        return 1;
    }

    // Append the temporary search file name.
    bcatcstr(modpath, "/.search");
    bconcat(url, name);

    // Open the file and do the cURL transfer.
    printd(LEVEL_DEFAULT, "querying module repository...\n");
    fp = fopen(modpath->data, "wb");
    curl_easy_setopt(curl, CURLOPT_URL, url->data);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
    res = curl_easy_perform(curl);
    curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode);
    if (res != 0 || httpcode != 200)
    {
        bdestroy(url);
        bdestroy(name);
        bdestroy(modpath);
        printd(LEVEL_ERROR, "curl failed with error code %i, HTTP error code %i.\n", res, httpcode);
        return 1;
    }
    fclose(fp);

    // Print the local results.
    if (all)
        printd(LEVEL_DEFAULT, "all modules:\n");
    else
        printd(LEVEL_DEFAULT, "search results for %s:\n", name->data);
    while ((entry = readdir(dir)) != NULL)
    {
        fname = bfromcstr(&entry->d_name[0]);
        if (binstr(fname, blength(fname) - 4, ext) == BSTR_ERR)
        {
            bdestroy(fname);
            continue;
        }
        if (binstr(fname, 0, name) == BSTR_ERR)
        {
            bdestroy(fname);
            continue;
        }
        if (entry->d_type != DT_REG)
        {
            bdestroy(fname);
            continue;
        }
        sstr = bmidstr(fname, 0, blength(fname) - 4);
        printd(LEVEL_DEFAULT, "   %s (installed)\n", sstr->data);
        list_append(&installed, sstr->data);
        bdestroy(sstr);
        bdestroy(fname);
    }

    // Print the online results.
    fp = fopen(modpath->data, "r");
    stream = bsopen(&read_data, fp);
    buffer = bfromcstr("");
    printed = false;
    while (bsreadln(buffer, stream, '\n') != BSTR_ERR)
    {
        btrimws(buffer);
        sstr = bmidstr(buffer, 0, blength(buffer) - 4);
        if (!list_contains(&installed, sstr->data))
            printd(LEVEL_DEFAULT, "  %s\n", sstr->data);
        printed = true;
        bdestroy(sstr);
    }
    if (!printed)
        printd(LEVEL_DEFAULT, "   <no online results>\n");
    bsclose(stream);
    fclose(fp);

    // Clean up.
    curl_easy_cleanup(curl);
    return 0;
}
示例#6
0
bool do_install_all(CURL* curl)
{
    // define used variables
    DIR* dir;
    FILE* fp;
    CURLcode res;
    bool printed;
    bool install_status;
    bool something_errored;
    bool if_something_was_installed;
    list_t installed;
    long httpcode = 0;
    struct dirent* entry;
    struct bStream* stream;
    bstring buffer, fname, sstr;
    bstring modpath = osutil_getmodulepath();
    bstring ext = bfromcstr(".lua");
    bstring url = bfromcstr("http://dms.dcputoolcha.in/modules/list");
    list_init(&installed);
    list_attributes_copy(&installed, list_meter_string, 1);
    list_attributes_comparator(&installed, list_comparator_string);

    // Attempt to open the modules directory.
    dir = opendir(modpath->data);
    if (dir == NULL)
    {
        printd(LEVEL_ERROR, "unable to query local repository.\n");
        return 1;
    }

    // add the filename we wish to query to the modules folder path
    bcatcstr(modpath, "/.all_avail");

    // Open the file and do the cURL transfer.
    printd(LEVEL_DEFAULT, "loading a list of all the modules...\n");
    fp = fopen(modpath->data, "wb");
    curl_easy_setopt(curl, CURLOPT_URL, url->data);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
    res = curl_easy_perform(curl);
    curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode);
    if (res != 0 || httpcode != 200)
    {
        bdestroy(url);
        bdestroy(modpath);
        printd(LEVEL_ERROR, "curl failed with error code %i, HTTP error code %i.\n", res, httpcode);
        return 1;
    }
    fclose(fp);


    // create a list of already installed modules
    while ((entry = readdir(dir)) != NULL)
    {
        fname = bfromcstr(&entry->d_name[0]);
        if (binstr(fname, blength(fname) - 4, ext) == BSTR_ERR)
        {
            bdestroy(fname);
            continue;
        }
        if (entry->d_type != DT_REG)
        {
            bdestroy(fname);
            continue;
        }
        sstr = bmidstr(fname, 0, blength(fname) - 4);
        list_append(&installed, sstr->data);
        bdestroy(sstr);
        bdestroy(fname);
    }

    printd(LEVEL_DEFAULT, "\n");

    // Print the names of the modules, and install them through the do_install function
    fp = fopen(modpath->data, "r");
    stream = bsopen(&read_data, fp);
    buffer = bfromcstr("");
    printed = false;
    if_something_was_installed = false;
    something_errored = false;
    while (bsreadln(buffer, stream, '\n') != BSTR_ERR)
    {
        btrimws(buffer);
        sstr = bmidstr(buffer, 0, blength(buffer) - 4);

        // if the module is not already installed
        if (!list_contains(&installed, sstr->data))
        {
            install_status = do_install(curl, bfromcstr(sstr->data));
            if_something_was_installed = true;
            // check whether the installation was successful
            if (install_status != 0)
            {
                printd(LEVEL_DEFAULT, "  %s failed to install.\n", sstr->data);
                something_errored = true;
            }
            printd(LEVEL_DEFAULT, "\n");
        }

        printed = true;
        bdestroy(sstr);
    }
    if (!printed)
        printd(LEVEL_DEFAULT, "  <no modules available>\n");
    if (something_errored)
        printd(LEVEL_DEFAULT, "errors occured\n");
    if (!if_something_was_installed)
        printd(LEVEL_DEFAULT, "no changes were made\n");
    bsclose(stream);
    fclose(fp);

    // Clean up.
    curl_easy_cleanup(curl);

    return 0;
}
示例#7
0
struct lua_debugst* dbg_lua_load(bstring name)
{
    bstring path, modtype;
    struct lua_debugst* ds;
    int module;

    // Calculate full path to file.
    path = osutil_getmodulepath();
    bconchar(path, '/');
    bconcat(path, name);

    // Create the new lua preprocessor structure.
    ds = malloc(sizeof(struct lua_debugst));
    ds->state = lua_open();
    assert(ds->state != NULL);
    luaL_openlibs(ds->state);
    luaX_loadexpressionlib(ds->state);

    // Load globals.
    dcpu_lua_set_constants(ds->state);

    // Execute the code in the new Lua context.
    if (luaL_dofile(ds->state, path->data) != 0)
    {
        printd(LEVEL_ERROR, "lua error was %s.\n", lua_tostring(ds->state, -1));

        // Return NULL.
        lua_close(ds->state);
        free(ds);
        bdestroy(path);
        return NULL;
    }

    // Load tables.
    lua_getglobal(ds->state, "MODULE");
    module = lua_gettop(ds->state);

    // Ensure module table was provided.
    if (lua_isnoneornil(ds->state, module))
    {
        printd(LEVEL_ERROR, "failed to load debugger module from %s.\n", path->data);

        // Return NULL.
        lua_close(ds->state);
        free(ds);
        bdestroy(path);
        return NULL;
    }

    // Check to see whether the module is
    // a preprocessor module.
    lua_getfield(ds->state, module, "Type");
    modtype = bfromcstr(lua_tostring(ds->state, -1));
    if (!biseqcstrcaseless(modtype, "Debugger"))
    {
        // Return NULL.
        lua_pop(ds->state, 1);
        lua_close(ds->state);
        free(ds);
        bdestroy(modtype);
        bdestroy(path);
        return NULL;
    }
    lua_pop(ds->state, 1);
    bdestroy(modtype);

    // Create the handler tables.
    lua_newtable(ds->state);
    lua_setglobal(ds->state, HANDLER_TABLE_COMMANDS_NAME);
    lua_newtable(ds->state);
    lua_setglobal(ds->state, HANDLER_TABLE_HOOKS_NAME);
    lua_newtable(ds->state);
    lua_setglobal(ds->state, HANDLER_TABLE_SYMBOLS_NAME);

    // Set the global functions.
    lua_pushcfunction(ds->state, &dbg_lua_add_command);
    lua_setglobal(ds->state, "add_command");
    lua_pushcfunction(ds->state, &dbg_lua_add_hook);
    lua_setglobal(ds->state, "add_hook");
    lua_pushcfunction(ds->state, &dbg_lua_add_symbol_hook);
    lua_setglobal(ds->state, "add_symbol_hook");

    // Run the setup function.
    lua_getglobal(ds->state, "setup");
    if (lua_pcall(ds->state, 0, 0, 0) != 0)
    {
        printd(LEVEL_ERROR, "failed to run setup() in debugger module from %s.\n", path->data);
        printd(LEVEL_ERROR, "lua error was %s.\n", lua_tostring(ds->state, -1));
    }

    // Unset the global functions.
    lua_pushnil(ds->state);
    lua_setglobal(ds->state, "add_command");
    lua_pushnil(ds->state);
    lua_setglobal(ds->state, "add_hook");
    lua_pushnil(ds->state);
    lua_setglobal(ds->state, "add_symbol_hook");

    // Pop tables from stack.
    lua_pop(ds->state, 2);

    // Return new debugger module.
    return ds;
}
示例#8
0
void dbg_lua_init()
{
    DIR* dir;
    struct dirent* entry;
    struct lua_debugst* dsm;
    bstring name = NULL;
    bstring modpath = NULL;
    bstring ext = bfromcstr(".lua");

    // Initialize lists.
    list_init(&modules);
    list_attributes_copy(&modules, &lua_debugst_meter, 1);

    // Get the module path.
    modpath = osutil_getmodulepath();
    if (modpath == NULL)
    {
        bdestroy(ext);
        return;
    }

    // Attempt to open the module directory.
    dir = opendir(modpath->data);
    if (dir == NULL)
    {
        // The directory does not exist, so we don't load
        // any custom debugger modules.
        modules_online = false;
        bdestroy(modpath);
        bdestroy(ext);
        return;
    }

    // Load each file from the hw directory.
    while ((entry = readdir(dir)) != NULL)
    {
        name = bfromcstr(&entry->d_name[0]);

        // Check to see whether it is a lua file.
        if (binstr(name, blength(name) - 4, ext) == BSTR_ERR)
        {
            // Not a Lua file, skip over and
            // then continue.
            bdestroy(name);
            continue;
        }

        // Check to see if it is a normal file.
#if defined(DT_REG)
        if (entry->d_type != DT_REG)
#elif defined(DT_DIR)
        if (entry->d_type == DT_DIR)
#elif defined(DT_UNKNOWN)
        if (entry->d_type == DT_UNKNOWN)
#else
#error Build system must support DT_REG, DT_DIR or DT_UNKNOWN in dirent.h.
#endif
        {
            // Not a file, skip over and then
            // continue.
            bdestroy(name);
            continue;
        }

        // Attempt to load the Lua file.
        printd(LEVEL_VERBOSE, "loading custom debugger module from: %s\n", name->data);
        dsm = dbg_lua_load(name);
        if (dsm != NULL)
            list_append(&modules, dsm);

        // Free data.
        bdestroy(name);
    }

    // Free resources.
    closedir(dir);
}
示例#9
0
struct lua_preproc* pp_lua_load(bstring name)
{
	bstring path, modtype;
	struct lua_preproc* pp;
	int module;

	// Calculate full path to file.
	path = osutil_getmodulepath();
	bconchar(path, '/');
	bconcat(path, name);

	// Create the new lua preprocessor structure.
	pp = malloc(sizeof(struct lua_preproc));
	pp->state = lua_open();
	assert(pp->state != NULL);
	luaL_openlibs(pp->state);
	luaX_loadexpressionlib(pp->state);

	// Execute the code in the new Lua context.
	if (luaL_dofile(pp->state, path->data) != 0)
	{
		printd(LEVEL_ERROR, "lua error was %s.\n", lua_tostring(pp->state, -1));

		// Return NULL.
		lua_close(pp->state);
		free(pp);
		bdestroy(path);
		return NULL;
	}

	// Load tables.
	lua_getglobal(pp->state, "MODULE");
	module = lua_gettop(pp->state);

	// Ensure module table was provided.
	if (lua_isnoneornil(pp->state, module))
	{
		printd(LEVEL_ERROR, "failed to load preprocessor module from %s.\n", path->data);

		// Return NULL.
		lua_close(pp->state);
		free(pp);
		bdestroy(path);
		return NULL;
	}

	// Check to see whether the module is
	// a preprocessor module.
	lua_getfield(pp->state, module, "Type");
	modtype = bfromcstr(lua_tostring(pp->state, -1));
	if (!biseqcstrcaseless(modtype, "Preprocessor"))
	{
		// Return NULL.
		lua_pop(pp->state, 1);
		lua_close(pp->state);
		free(pp);
		bdestroy(modtype);
		bdestroy(path);
		return NULL;
	}
	lua_pop(pp->state, 1);
	bdestroy(modtype);

	// Create the handler table.
	lua_newtable(pp->state);
	lua_setglobal(pp->state, HANDLER_TABLE_NAME);

	// Set the global add_preprocessor_directive function.
	lua_pushcfunction(pp->state, &pp_lua_add_preprocessor_directive);
	lua_setglobal(pp->state, "add_preprocessor_directive");

	// Run the setup function.
	lua_getglobal(pp->state, "setup");
	if (lua_pcall(pp->state, 0, 0, 0) != 0)
	{
		printd(LEVEL_ERROR, "failed to run setup() in preprocessor module from %s.\n", path->data);
	}

	// Unset the add_preprocessor_directive function.
	lua_pushnil(pp->state);
	lua_setglobal(pp->state, "add_preprocessor_directive");

	// Pop tables from stack.
	lua_pop(pp->state, 2);

	// Return new preprocessor module.
	return pp;
}