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