diff --git a/client/src/fileutils.c b/client/src/fileutils.c index b32d8ec88..4d1b8355d 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -49,6 +49,7 @@ #include "util.h" #ifdef _WIN32 #include "scandir.h" +#include #endif #define PATH_MAX_LENGTH 200 @@ -130,7 +131,87 @@ static bool is_directory(const char *filename) { return S_ISDIR(st.st_mode) != 0; } +/** + * @brief create a new directory. + * @param dirname + * @return + */ +// Not used... +/* +#ifdef _WIN32 +#define make_dir(a) _mkdir(a) +#else +#define make_dir(a) mkdir(a,0755) //note 0755 MUST have leading 0 for octal linux file permissions +#endif +bool create_path(const char *dirname) { + if (dirname == NULL) // nothing to do + return false; + + if ((strlen(dirname) == 1) && (dirname[0] == '/')) + return true; + + if ((strlen(dirname) == 2) && (dirname[1] == ':')) + return true; + + if (fileExists(dirname) == 0) { + + char *bs = strrchr(dirname, '\\'); + char *fs = strrchr(dirname, '/'); + + if ((bs == NULL) && (fs != NULL)) { + *fs = 0x00; + create_path (dirname); + *fs = '/'; + } + + if ((bs != NULL) && (fs == NULL)) { + *bs = 0x00; + create_path (dirname); + *bs = '\\'; + } + + if ((bs != NULL) && (fs != NULL)) { + if (strlen (bs) > strlen (fs)) { + *fs = 0x00; // No slash + create_path (dirname); + *fs = '/'; + } else { + *bs = 0x00; + create_path (dirname); + *bs = '\\'; + } + + } + + if (make_dir(dirname) != 0) { + PrintAndLogEx(ERR, "could not create directory.... "_RED_("%s"),dirname); + return false; + } + } + return true; +} +*/ +/* +bool setDefaultPath (savePaths_t pathIndex,const char *Path) { + + if (pathIndex < spItemCount) { + if ((Path == NULL) && (session.defaultPaths[pathIndex] != NULL)) { + free (session.defaultPaths[pathIndex]); + session.defaultPaths[pathIndex] = NULL; + } + + if (Path != NULL) { + session.defaultPaths[pathIndex] = (char *)realloc(session.defaultPaths[pathIndex], strlen(Path) + 1); + strcpy(session.defaultPaths[pathIndex], Path); + } + } else { + return false; + } + + return true; +} +*/ static char *filenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL) return NULL; if (suffix == NULL) return NULL; @@ -905,10 +986,10 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_ } *datalen = sptr; } + PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName); if (!strcmp(ctype, "settings")) { preferences_load_callback(root); } - PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName); out: json_decref(root); free(fileName); diff --git a/client/src/fileutils.h b/client/src/fileutils.h index ff43b3f7e..2f55a3c1a 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -74,6 +74,9 @@ typedef enum { } DumpFileType_t; int fileExists(const char *filename); +//bool create_path(const char *dirname); +//bool setDefaultPath (savePaths_t pathIndex,const char *Path); // set a path in the path list session.defaultPaths + /** * @brief Utility function to save data to a binary file. This method takes a preferred name, but if that diff --git a/client/src/preferences.c b/client/src/preferences.c index a1de6e4e2..f0c3a0f50 100644 --- a/client/src/preferences.c +++ b/client/src/preferences.c @@ -23,11 +23,9 @@ #include #include "cmdparser.h" #include -// #include +#include #include -//#include "proxgui.h" -//extern void SetWindowsPosition (void); static int CmdHelp(const char *Cmd); static int setCmdHelp(const char *Cmd); @@ -51,31 +49,57 @@ static char *prefGetFilename(void) { int preferences_load(void) { - PrintAndLogEx(INFO, "Looking for preferences..."); - // Set all defaults - session.client_debug_level = OFF; + session.client_debug_level = cdbOFF; + // session.device_debug_level = ddbOFF; session.window_changed = false; - session.window_plot_xpos = 10; - session.window_plot_ypos = 30; - session.window_plot_hsize = 400; - session.window_plot_wsize = 800; - session.window_overlay_xpos = session.window_plot_xpos; - session.window_overlay_ypos = 60 + session.window_plot_ypos + session.window_plot_hsize; - session.window_overlay_hsize = 200; - session.window_overlay_wsize = session.window_plot_wsize; + session.plot.x = 10; + session.plot.y = 30; + session.plot.h = 400; + session.plot.w = 800; + session.overlay.x = session.plot.x; + session.overlay.y = 60 + session.plot.y + session.plot.h; + session.overlay.h = 200; + session.overlay.w = session.plot.w; session.emoji_mode = ALIAS; session.show_hints = false; session.supports_colors = false; +// setDefaultPath (spDefault, ""); +// setDefaultPath (spDump, ""); +// setDefaultPath (spTrace, ""); + +/* + // default save path + if (get_my_user_directory() != NULL) // should return path to .proxmark3 folder + setDefaultPath (spDefault, get_my_user_directory()); + else + setDefaultPath (spDefault, "."); + + // default dump path + if (get_my_user_directory() != NULL) // should return path to .proxmark3 folder + setDefaultPath (spDump, get_my_user_directory()); + else + setDefaultPath (spDump, "."); + + // default dump path + if (get_my_user_directory() != NULL) // should return path to .proxmark3 folder + setDefaultPath (spTrace, get_my_user_directory()); + else + setDefaultPath (spTrace, "."); +*/ // loadFileJson wants these, so pass in place holder values, though not used // in settings load; uint8_t dummyData = 0x00; size_t dummyDL = 0x00; - if (loadFileJSON(prefGetFilename(), &dummyData, sizeof(dummyData), &dummyDL) == PM3_SUCCESS) { - session.preferences_loaded = true; + // to better control json cant find file error msg. + if (fileExists(prefGetFilename())) { + PrintAndLogEx(INFO, "Loading Preferences..."); + if (loadFileJSON(prefGetFilename(), &dummyData, sizeof(dummyData), &dummyDL) == PM3_SUCCESS) { + session.preferences_loaded = true; + } } // Note, if session.settings_loaded == false then the settings_save // will be called in main () to save settings as set in defaults and main() checks. @@ -87,10 +111,14 @@ int preferences_load(void) { int preferences_save(void) { // Note sure if backup has value ? - char backupFilename[FILENAME_MAX + sizeof(preferencesFilename) + 10] = {0}; + char *backupFilename = NULL;// [FILENAME_MAX+sizeof(preferencesFilename)+10] = {0}; + int fnLen = 0; - PrintAndLogEx(INFO, "Saving preferences ..."); - snprintf(backupFilename, sizeof(backupFilename) - 1, "%s.bak", prefGetFilename()); + PrintAndLogEx(INFO, "Saving Preferences..."); + + fnLen = strlen(prefGetFilename()) + 5; // .bak\0 + backupFilename = (char *)calloc(fnLen, sizeof(uint8_t)); + snprintf(backupFilename, fnLen, "%s.bak", prefGetFilename()); if (fileExists(backupFilename)) { if (remove(backupFilename) != 0) { @@ -112,6 +140,9 @@ int preferences_save(void) { if (saveFileJSON(prefGetFilename(), jsfSettings, &dummyData, dummyDL) != PM3_SUCCESS) PrintAndLogEx(ERR, "Error saving preferences to \"%s\"", prefGetFilename()); + if (backupFilename != NULL) + free(backupFilename); + return PM3_SUCCESS; } @@ -119,40 +150,13 @@ void preferences_save_callback(json_t *root) { JsonSaveStr(root, "FileType", "settings"); - // Log level, convert to text - switch (session.client_debug_level) { - case OFF: - JsonSaveStr(root, "client.debug.level", "off"); - break; - case SIMPLE: - JsonSaveStr(root, "client.debug.level", "simple"); - break; - case FULL: - JsonSaveStr(root, "client.debug.level", "full"); - break; - default: - JsonSaveStr(root, "logging.level", "NORMAL"); - } - - // Plot window - JsonSaveInt(root, "window.plot.xpos", session.window_plot_xpos); - JsonSaveInt(root, "window.plot.ypos", session.window_plot_ypos); - JsonSaveInt(root, "window.plot.hsize", session.window_plot_hsize); - JsonSaveInt(root, "window.plot.wsize", session.window_plot_wsize); - - // Overlay/Slider window - JsonSaveInt(root, "window.overlay.xpos", session.window_overlay_xpos); - JsonSaveInt(root, "window.overlay.ypos", session.window_overlay_ypos); - JsonSaveInt(root, "window.overlay.hsize", session.window_overlay_hsize); - JsonSaveInt(root, "window.overlay.wsize", session.window_overlay_wsize); - // Emoji switch (session.emoji_mode) { case ALIAS: JsonSaveStr(root, "show.emoji", "alias"); break; case EMOJI: - JsonSaveStr(root, "show.emoji", "emoji"); + JsonSaveStr(root,"show.emoji","emoji"); break; case ALTTEXT: JsonSaveStr(root, "show.emoji", "alttext"); @@ -167,6 +171,58 @@ void preferences_save_callback(json_t *root) { JsonSaveBoolean(root, "show.hints", session.show_hints); JsonSaveBoolean(root, "os.supports.colors", session.supports_colors); + + // JsonSaveStr(root, "file.default.savepath", session.defaultPaths[spDefault]); + // JsonSaveStr(root, "file.default.dumppath", session.defaultPaths[spDump]); + // JsonSaveStr(root, "file.default.tracepath", session.defaultPaths[spTrace]); + + // Plot window + JsonSaveInt(root, "window.plot.xpos", session.plot.x); + JsonSaveInt(root, "window.plot.ypos", session.plot.y); + JsonSaveInt(root, "window.plot.hsize", session.plot.h); + JsonSaveInt(root, "window.plot.wsize", session.plot.w); + + // Overlay/Slider window + JsonSaveInt(root, "window.overlay.xpos", session.overlay.x); + JsonSaveInt(root, "window.overlay.ypos", session.overlay.y); + JsonSaveInt(root, "window.overlay.hsize", session.overlay.h); + JsonSaveInt(root, "window.overlay.wsize", session.overlay.w); + + // Log level, convert to text + switch (session.client_debug_level) { + case cdbOFF: + JsonSaveStr(root, "client.debug.level", "off"); + break; + case cdbSIMPLE: + JsonSaveStr(root, "client.debug.level", "simple"); + break; + case cdbFULL: + JsonSaveStr(root, "client.debug.level", "full"); + break; + default: + JsonSaveStr(root, "logging.level", "NORMAL"); + } +/* + switch (session.device_debug_level) { + case ddbOFF: + JsonSaveStr(root, "device.debug.level", "off"); + break; + case ddbERROR: + JsonSaveStr(root, "device.debug.level", "error"); + break; + case ddbINFO: + JsonSaveStr(root, "device.debug.level", "info"); + break; + case ddbDEBUG: + JsonSaveStr(root, "device.debug.level", "debug"); + break; + case ddbEXTENDED: + JsonSaveStr(root, "device.debug.level", "extended"); + break; + default: + JsonSaveStr(root, "logging.level", "NORMAL"); + } +*/ } void preferences_load_callback(json_t *root) { @@ -180,30 +236,42 @@ void preferences_load_callback(json_t *root) { if (json_unpack_ex(root, &up_error, 0, "{s:s}", "client.debug.level", &s1) == 0) { strncpy(tempStr, s1, sizeof(tempStr) - 1); str_lower(tempStr); - if (strncmp(tempStr, "off", 3) == 0) session.client_debug_level = OFF; - if (strncmp(tempStr, "simple", 6) == 0) session.client_debug_level = SIMPLE; - if (strncmp(tempStr, "full", 4) == 0) session.client_debug_level = FULL; + if (strncmp(tempStr, "off", 3) == 0) session.client_debug_level = cdbOFF; + if (strncmp(tempStr, "simple", 6) == 0) session.client_debug_level = cdbSIMPLE; + if (strncmp(tempStr, "full", 4) == 0) session.client_debug_level = cdbFULL; } +/* + // default save path + if (json_unpack_ex(root, &up_error, 0, "{s:s}", "file.default.savepath", &s1) == 0) + setDefaultPath (spDefault,s1); + // default dump path + if (json_unpack_ex(root, &up_error, 0, "{s:s}", "file.default.dumppath", &s1) == 0) + setDefaultPath (spDump,s1); + + // default trace path + if (json_unpack_ex(root, &up_error, 0, "{s:s}", "file.default.tracepath", &s1) == 0) + setDefaultPath (spTrace,s1); +*/ // window plot if (json_unpack_ex(root, &up_error, 0, "{s:i}", "window.plot.xpos", &i1) == 0) - session.window_plot_xpos = i1; + session.plot.x = i1; if (json_unpack_ex(root, &up_error, 0, "{s:i}", "window.plot.ypos", &i1) == 0) - session.window_plot_ypos = i1; + session.plot.y = i1; if (json_unpack_ex(root, &up_error, 0, "{s:i}", "window.plot.hsize", &i1) == 0) - session.window_plot_hsize = i1; + session.plot.h = i1; if (json_unpack_ex(root, &up_error, 0, "{s:i}", "window.plot.wsize", &i1) == 0) - session.window_plot_wsize = i1; + session.plot.w = i1; // overlay/slider plot if (json_unpack_ex(root, &up_error, 0, "{s:i}", "window.overlay.xpos", &i1) == 0) - session.window_overlay_xpos = i1; + session.overlay.x = i1; if (json_unpack_ex(root, &up_error, 0, "{s:i}", "window.overlay.ypos", &i1) == 0) - session.window_overlay_ypos = i1; + session.overlay.y = i1; if (json_unpack_ex(root, &up_error, 0, "{s:i}", "window.overlay.hsize", &i1) == 0) - session.window_overlay_hsize = i1; + session.overlay.h = i1; if (json_unpack_ex(root, &up_error, 0, "{s:i}", "window.overlay.wsize", &i1) == 0) - session.window_overlay_wsize = i1; + session.overlay.w = i1; // show options if (json_unpack_ex(root, &up_error, 0, "{s:s}", "show.emoji", &s1) == 0) { @@ -220,7 +288,18 @@ void preferences_load_callback(json_t *root) { if (json_unpack_ex(root, &up_error, 0, "{s:b}", "os.supports.colors", &b1) == 0) session.supports_colors = b1; - +/* + // Logging Level + if (json_unpack_ex(root, &up_error, 0, "{s:s}", "device.debug.level", &s1) == 0) { + strncpy(tempStr, s1, sizeof(tempStr) - 1); + str_lower(tempStr); + if (strncmp(tempStr, "off", 3) == 0) session.device_debug_level = ddbOFF; + if (strncmp(tempStr, "error", 5) == 0) session.device_debug_level = ddbERROR; + if (strncmp(tempStr, "info", 4) == 0) session.device_debug_level = ddbINFO; + if (strncmp(tempStr, "debug", 5) == 0) session.device_debug_level = ddbDEBUG; + if (strncmp(tempStr, "extended", 8) == 0) session.device_debug_level = ddbEXTENDED; + } +*/ } // Help Functions @@ -248,7 +327,7 @@ static int usage_set_color() { } static int usage_set_debug() { - PrintAndLogEx(NORMAL, "Usage: pref set debug "); + PrintAndLogEx(NORMAL, "Usage: pref set clientdebug "); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); PrintAndLogEx(NORMAL, " "_GREEN_("off")" - no debug messages"); @@ -257,6 +336,20 @@ static int usage_set_debug() { return PM3_SUCCESS; } +/* +static int usage_set_devicedebug() { + PrintAndLogEx(NORMAL, "Usage: pref set devicedebug "); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); + PrintAndLogEx(NORMAL, " "_GREEN_("off")" - no debug messages"); + PrintAndLogEx(NORMAL, " "_GREEN_("error")" - error messages"); + PrintAndLogEx(NORMAL, " "_GREEN_("info")" - info messages"); + PrintAndLogEx(NORMAL, " "_GREEN_("debug")" - debug messages"); + PrintAndLogEx(NORMAL, " "_GREEN_("extended")" - extended debug messages"); + + return PM3_SUCCESS; +} +*/ static int usage_set_hints() { PrintAndLogEx(NORMAL, "Usage: pref set hints "); PrintAndLogEx(NORMAL, "Options:"); @@ -266,17 +359,30 @@ static int usage_set_hints() { return PM3_SUCCESS; } +/* +static int usage_set_savePaths() { + PrintAndLogEx(NORMAL, "Usage: pref set savepaths [help] [create] [default ] [dump ] [trace ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " "_GREEN_("help")" - This help"); + PrintAndLogEx(NORMAL, " "_GREEN_("create")" - Create directory if it does not exist"); + PrintAndLogEx(NORMAL, " "_GREEN_("default")" - Deafult path"); + PrintAndLogEx(NORMAL, " "_GREEN_("dump")" - Dump path"); + PrintAndLogEx(NORMAL, " "_GREEN_("trace")" - Trace help"); + return PM3_SUCCESS; +} +*/ // Preference Processing Functions -typedef enum preferenceId {prefNONE, prefHELP, prefEMOJI, prefCOLOR, prefPLOT, prefOVERLAY, prefHINTS, prefCLIENTDEBUG} preferenceId_t; -typedef enum prefShowOpt {prefShowNone, prefShowOLD, prefShowNEW} prefShowOpt_t; +// typedef enum preferenceId {prefNONE,prefHELP,prefEMOJI,prefCOLOR,prefPLOT,prefOVERLAY,prefHINTS,prefCLIENTDEBUG} preferenceId_t; +typedef enum prefShowOpt {prefShowNone, prefShowOLD, prefShowNEW} prefShowOpt_t; -const char *prefShowMsg(prefShowOpt_t Opt) { +const char *prefShowMsg(prefShowOpt_t Opt) +{ switch (Opt) { case prefShowOLD: - return _YELLOW_("[old]"); //strncpy(Msg,"Before ",sizeof(Msg)-1); break; + return _YELLOW_("[old]"); case prefShowNEW: - return _GREEN_("[new]"); // strncpy(Msg,"After ",sizeof(Msg)-1); break; + return _GREEN_("[new]"); case prefShowNone: return ""; } @@ -309,41 +415,87 @@ void showColorState(prefShowOpt_t Opt) { if (session.supports_colors) PrintAndLogEx(NORMAL, " %s color.................. "_GREEN_("ansi"), prefShowMsg(Opt)); else - PrintAndLogEx(NORMAL, " %s color.................. "_GREEN_("off"), prefShowMsg(Opt)); + PrintAndLogEx(NORMAL, " %s color.................. "_WHITE_("off"), prefShowMsg(Opt)); } void showClientDebugState(prefShowOpt_t Opt) { switch (session.client_debug_level) { - case OFF: - PrintAndLogEx(NORMAL, " %s client debug........... "_GREEN_("off"), prefShowMsg(Opt)); + case cdbOFF: + PrintAndLogEx(NORMAL, " %s client debug........... "_WHITE_("off"), prefShowMsg(Opt)); break; - case SIMPLE: + case cdbSIMPLE: PrintAndLogEx(NORMAL, " %s client debug........... "_GREEN_("simple"), prefShowMsg(Opt)); break; - case FULL: + case cdbFULL: PrintAndLogEx(NORMAL, " %s client debug........... "_GREEN_("full"), prefShowMsg(Opt)); break; default: PrintAndLogEx(NORMAL, " %s client debug........... "_RED_("unknown"), prefShowMsg(Opt)); } } +/* +void showDeviceDebugState(prefShowOpt_t Opt) { + switch (session.device_debug_level) { + case ddbOFF: + PrintAndLogEx(NORMAL, " %s device debug........... "_WHITE_("off"), prefShowMsg(Opt)); + break; + case ddbERROR: + PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("error"), prefShowMsg(Opt)); + break; + case ddbINFO: + PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("info"), prefShowMsg(Opt)); + break; + case ddbDEBUG: + PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("debug"), prefShowMsg(Opt)); + break; + case ddbEXTENDED: + PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("extended"), prefShowMsg(Opt)); + break; + default: + PrintAndLogEx(NORMAL, " %s device debug........... "_RED_("unknown"), prefShowMsg(Opt)); + } +} +*/ +/* +void showSavePathState(savePaths_t pathIndex, prefShowOpt_t Opt) { -void showPlotPosState(void) { + char tempStr[50]; + + switch (pathIndex) { + case spDefault: + strcpy (tempStr,"default save path......"); + break; + case spDump: + strcpy (tempStr,"dump save path........."); + break; + case spTrace: + strcpy (tempStr,"trace save path........"); + break; + default: + strcpy (tempStr,_RED_("unknown")" save path......"); + } + if ((session.defaultPaths[pathIndex] == NULL) || (strcmp(session.defaultPaths[pathIndex],"") == 0)) + PrintAndLogEx(NORMAL, " %s %s "_WHITE_("not set"), prefShowMsg(Opt),tempStr); + else + PrintAndLogEx(NORMAL, " %s %s "_GREEN_("%s"), prefShowMsg(Opt), tempStr, session.defaultPaths[pathIndex]); +} +*/ +void showPlotPosState(void){ PrintAndLogEx(NORMAL, " Plot window............ X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"), - session.window_plot_xpos, session.window_plot_ypos, session.window_plot_hsize, session.window_plot_wsize); + session.plot.x, session.plot.y, session.plot.h, session.plot.w); } void showOverlayPosState(void) { PrintAndLogEx(NORMAL, " Slider/Overlay window.. X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"), - session.window_overlay_xpos, session.window_overlay_ypos, session.window_overlay_hsize, session.window_overlay_wsize); + session.overlay.x, session.overlay.y, session.overlay.h, session.overlay.w); } void showHintsState(prefShowOpt_t Opt) { if (session.show_hints) - PrintAndLogEx(NORMAL, " %s Hints.................. "_GREEN_("on"), prefShowMsg(Opt)); + PrintAndLogEx(NORMAL, " %s hints.................. "_GREEN_("on"), prefShowMsg(Opt)); else - PrintAndLogEx(NORMAL, " %s Hints.................. "_GREEN_("off"), prefShowMsg(Opt)); + PrintAndLogEx(NORMAL, " %s hints.................. "_WHITE_("off"), prefShowMsg(Opt)); } static int setCmdEmoji(const char *Cmd) { @@ -465,15 +617,15 @@ static int setCmdDebug(const char *Cmd) { return usage_set_debug(); if (strncmp(strOpt, "off", 3) == 0) { validValue = true; - newValue = OFF; + newValue = cdbOFF; } if (strncmp(strOpt, "simple", 6) == 0) { validValue = true; - newValue = SIMPLE; + newValue = cdbSIMPLE; } if (strncmp(strOpt, "full", 4) == 0) { validValue = true; - newValue = FULL; + newValue = cdbFULL; } if (validValue) { @@ -496,8 +648,75 @@ static int setCmdDebug(const char *Cmd) { return PM3_SUCCESS; } +/* +static int setCmdDeviceDebug (const char *Cmd) +{ + uint8_t cmdp = 0; + bool errors = false; + bool validValue = false; + char strOpt[50]; + devicedebugLevel_t newValue = session.device_debug_level; -static int setCmdHint(const char *Cmd) { + if (param_getchar(Cmd, cmdp) == 0x00) + return usage_set_devicedebug (); + + while ((param_getchar(Cmd, cmdp) != 0x00) && !errors) { + + if (param_getstr(Cmd, cmdp++, strOpt, sizeof(strOpt)) != 0) { + str_lower(strOpt); // convert to lowercase + + if (strncmp (strOpt,"help",4) == 0) + return usage_set_devicedebug(); + if (strncmp (strOpt,"off",3) == 0) { + validValue = true; + newValue = ddbOFF; + } + if (strncmp (strOpt,"error",5) == 0) { + validValue = true; + newValue = ddbERROR; + } + if (strncmp (strOpt,"info",4) == 0) { + validValue = true; + newValue = ddbINFO; + } + if (strncmp (strOpt,"debug",5) == 0) { + validValue = true; + newValue = ddbDEBUG; + } + if (strncmp (strOpt,"extended",8) == 0) { + validValue = true; + newValue = ddbEXTENDED; + } + + if (validValue) { + if (session.device_debug_level != newValue) {// changed + showDeviceDebugState (prefShowOLD); + session.device_debug_level = newValue; + showDeviceDebugState (prefShowNEW); + preferences_save (); + } else { + PrintAndLogEx(INFO,"nothing changed"); + showDeviceDebugState (prefShowNone); + } + if (session.pm3_present) { + PrintAndLogEx (INFO,"setting device debug loglevel"); + SendCommandNG(CMD_SET_DBGMODE, &session.device_debug_level, 1); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_SET_DBGMODE, &resp, 2000) == false) + PrintAndLogEx (INFO,"failed to set device debug loglevel"); + } + } else { + PrintAndLogEx(ERR,"invalid option"); + return usage_set_devicedebug(); + } + } + } + + return PM3_SUCCESS; +} +*/ +static int setCmdHint (const char *Cmd) +{ uint8_t cmdp = 0; bool errors = false; bool validValue = false; @@ -542,16 +761,146 @@ static int setCmdHint(const char *Cmd) { return PM3_SUCCESS; } +/* +static int setCmdSavePaths (const char *Cmd) { + uint8_t cmdp = 0; + bool errors = false; + // bool validValue = false; + char *strOpt = NULL; + int optLen = 0; + char *newValue = NULL; + bool createDir = false; + savePaths_t pathItem = spItemCount; + + + if (param_getchar(Cmd, cmdp) == 0x00) + return usage_set_savePaths(); -static command_t setCommandTable[] = { - {"help", setCmdHelp, AlwaysAvailable, "This help"}, - {"emoji", setCmdEmoji, AlwaysAvailable, "Set emoji display"}, - {"color", setCmdColor, AlwaysAvailable, "Set color support"}, - {"debug", setCmdDebug, AlwaysAvailable, "Set client debug level"}, - {"hints", setCmdHint, AlwaysAvailable, "Set hint display"}, + while ((param_getchar(Cmd, cmdp) != 0x00) && !errors) { + + optLen = param_getlength(Cmd, cmdp)+1; + strOpt = (char *)realloc(strOpt,optLen+1);//, sizeof(uint8_t)); + + if (param_getstr(Cmd, cmdp++, strOpt, optLen) != 0) { + str_lower(strOpt); // convert to lowercase + + if (strncmp(strOpt, "help", 4) == 0) + return usage_set_savePaths(); + + if (strncmp(strOpt, "create", 6) == 0) { + // check if 2 more options. + if (param_getlength(Cmd, cmdp+1) == 0) // should have min 2 more options + return usage_set_savePaths(); + createDir = true; + } else { + if ((strncmp(strOpt, "default", 7) == 0) || + (strncmp(strOpt, "dump", 4) == 0) || + (strncmp(strOpt, "trace", 5) == 0)) { + + // Get Path + optLen = param_getlength(Cmd, cmdp) + 1; + newValue = (char *)realloc(newValue, optLen+1); + if (param_getstr(Cmd, cmdp++, newValue, optLen) == 0) { + PrintAndLogEx(INFO, "missing %s path",strOpt); + return usage_set_savePaths(); + } + // remove trailing slash. + if ((newValue[strlen(newValue)-1] == '/') || (newValue[strlen(newValue)-1] == '\\')) + newValue[strlen(newValue)-1] = 0x00; + + // Check path + if (!fileExists(newValue) && !createDir) { + PrintAndLogEx(ERR,"path does not exist... "_RED_("%s"),newValue); + } else { + // do we need to create it + // if (!fileExists(newValue)) + // create_path (newValue); //mkdir (newValue,0x777); + + pathItem = spItemCount; + if (strncmp(strOpt, "default", 7) == 0) pathItem = spDefault; + if (strncmp(strOpt, "dump", 4) == 0) pathItem = spDump; + if (strncmp(strOpt, "trace", 5) == 0) pathItem = spTrace; + + if (pathItem < spItemCount) { + if (strcmp(newValue, session.defaultPaths[pathItem]) != 0) { + showSavePathState(pathItem, prefShowOLD); + setDefaultPath (pathItem, newValue); + showSavePathState(pathItem, prefShowNEW); + preferences_save(); + } else { + PrintAndLogEx(INFO, "nothing changed"); + showSavePathState(pathItem, prefShowNone); + } + } + } + } else { + return usage_set_savePaths(); + } + } + } + } + + // clean up + if (strOpt != NULL) free (strOpt); + if (newValue != NULL) free (newValue); + + return PM3_SUCCESS; +} +*/ + +int getCmdHelp (const char *Cmd) { + + return PM3_SUCCESS; +} + +int getCmdEmoji (const char *Cmd) { + + showEmojiState(prefShowNone); + + return PM3_SUCCESS; +} + +int getCmdHint (const char *Cmd) { + + showHintsState(prefShowNone); + + return PM3_SUCCESS; +} + +int getCmdColor (const char *Cmd) { + + showColorState(prefShowNone); + + return PM3_SUCCESS; +} + +int getCmdDebug (const char *Cmd) { + + showClientDebugState(prefShowNone); + return PM3_SUCCESS; +} + +static command_t getCommandTable[] = { +// {"help", getCmdHelp, AlwaysAvailable, "This help"}, + {"emoji", getCmdEmoji, AlwaysAvailable, "Get emoji display preference"}, + {"hints", getCmdHint, AlwaysAvailable, "Get hint display preference"}, + {"color", getCmdColor, AlwaysAvailable, "Get color support preference"}, + // {"defaultsavepaths", getCmdSavePaths, AlwaysAvailable, "... to be adjusted next ... "}, + {"clientdebug", getCmdDebug, AlwaysAvailable, "Get client debug level preference"}, + // {"devicedebug", getCmdDeviceDebug, AlwaysAvailable, "Get device debug level"}, {NULL, NULL, NULL, NULL} }; +static command_t setCommandTable[] = { + {"help", setCmdHelp, AlwaysAvailable, "This help"}, + {"emoji", setCmdEmoji, AlwaysAvailable, "Set emoji display"}, + {"hints", setCmdHint, AlwaysAvailable, "Set hint display"}, + {"color", setCmdColor, AlwaysAvailable, "Set color support"}, + // {"defaultsavepaths", setCmdSavePaths, AlwaysAvailable, "... to be adjusted next ... "}, + {"clientdebug", setCmdDebug, AlwaysAvailable, "Set client debug level"}, + // {"devicedebug", setCmdDeviceDebug, AlwaysAvailable, "Set device debug level"}, + {NULL, NULL, NULL, NULL} +}; static int setCmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far @@ -560,6 +909,12 @@ static int setCmdHelp(const char *Cmd) { return PM3_SUCCESS; } +int CmdPrefGet(const char *Cmd) { + clearCommandBuffer(); + + return CmdsParse(getCommandTable, Cmd); +} + int CmdPrefSet(const char *Cmd) { clearCommandBuffer(); @@ -569,21 +924,25 @@ int CmdPrefSet(const char *Cmd) { static int CmdPrefShow(const char *Cmd) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, _BLUE_("Preferences")); - - if (!session. preferences_loaded) { - PrintAndLogEx(ERR, "Preferneces not loaded"); + PrintAndLogEx(NORMAL, _CYAN_("Preferences loaded from %s"),prefGetFilename()); + + if (!session.preferences_loaded) { + PrintAndLogEx (ERR, "Preferneces not loaded"); return PM3_ESOFT; } - PrintAndLogEx(NORMAL, " preference file........ "_GREEN_("%s"), prefGetFilename()); + // PrintAndLogEx(NORMAL, " preference file........ "_GREEN_("%s"), prefGetFilename()); showEmojiState(prefShowNone); - showColorState(prefShowNone); - // showPlotPosState (); - // showOverlayPosState (); - showClientDebugState(prefShowNone); showHintsState(prefShowNone); + showColorState(prefShowNone); + // showPlotPosState (); + // showOverlayPosState (); + // showSavePathState(spDefault, prefShowNone); + // showSavePathState(spDump, prefShowNone); + // showSavePathState(spTrace, prefShowNone); + showClientDebugState(prefShowNone); +// showDeviceDebugState(prefShowNone); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; @@ -597,9 +956,9 @@ static int CmdPrefSave (const char *Cmd) { */ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"get", CmdPrefGet, AlwaysAvailable, "Get a preference"}, {"set", CmdPrefSet, AlwaysAvailable, "Set a preference"}, - {"show", CmdPrefShow, AlwaysAvailable, "Show preferences"}, -// {"save", CmdPrefSave, AlwaysAvailable, "Save preferences now"}, + {"show", CmdPrefShow, AlwaysAvailable, "Show all preferences"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/preferences.h b/client/src/preferences.h index 38e2272cb..0d7705027 100644 --- a/client/src/preferences.h +++ b/client/src/preferences.h @@ -9,6 +9,7 @@ #define PREFERENCES_H_ #include "fileutils.h" +#include // Current working directory will be prepended. #define preferencesFilename "preferences.json" diff --git a/client/src/proxguiqt.cpp b/client/src/proxguiqt.cpp index 945a1922f..f2fb5986a 100644 --- a/client/src/proxguiqt.cpp +++ b/client/src/proxguiqt.cpp @@ -139,21 +139,21 @@ ProxGuiQT::~ProxGuiQT(void) { SliderWidget::SliderWidget() { // Set the initail postion and size from settings if (session.preferences_loaded) - setGeometry(session.window_overlay_xpos, session.window_overlay_ypos, session.window_overlay_wsize, session.window_overlay_hsize); + setGeometry(session.overlay.x, session.overlay.y, session.overlay.w, session.overlay.h); else resize(800, 400); } void SliderWidget::resizeEvent(QResizeEvent *event) { - session.window_overlay_hsize = event->size().height(); - session.window_overlay_wsize = event->size().width(); + session.overlay.h = event->size().height(); + session.overlay.w = event->size().width(); session.window_changed = true; } void SliderWidget::moveEvent(QMoveEvent *event) { - session.window_overlay_xpos = event->pos().x(); - session.window_overlay_ypos = event->pos().y(); + session.overlay.x = event->pos().x(); + session.overlay.y = event->pos().y(); session.window_changed = true; } @@ -199,7 +199,7 @@ ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent) { this->master = master; // Set the initail postion and size from settings if (session.preferences_loaded) - setGeometry(session.window_plot_xpos, session.window_plot_ypos, session.window_plot_wsize, session.window_plot_hsize); + setGeometry(session.plot.x, session.plot.y, session.plot.w, session.plot.h); else resize(800, 400); @@ -224,7 +224,7 @@ ProxWidget::ProxWidget(QWidget *parent, ProxGuiQT *master) : QWidget(parent) { QObject::connect(opsController->horizontalSlider_dirthr_down, SIGNAL(valueChanged(int)), this, SLOT(vchange_dthr_down(int))); QObject::connect(opsController->horizontalSlider_askedge, SIGNAL(valueChanged(int)), this, SLOT(vchange_askedge(int))); - controlWidget->setGeometry(session.window_overlay_xpos, session.window_overlay_ypos, session.window_overlay_wsize, session.window_overlay_hsize); + controlWidget->setGeometry(session.overlay.x, session.overlay.y, session.overlay.w, session.overlay.h); // Set up the plot widget, which does the actual plotting plot = new Plot(this); @@ -292,13 +292,13 @@ void ProxWidget::showEvent(QShowEvent *event) { plot->show(); } void ProxWidget::moveEvent(QMoveEvent *event) { - session.window_plot_xpos = event->pos().x(); - session.window_plot_ypos = event->pos().y(); + session.plot.x = event->pos().x(); + session.plot.y = event->pos().y(); session.window_changed = true; } void ProxWidget::resizeEvent(QResizeEvent *event) { - session.window_plot_hsize = event->size().height(); - session.window_plot_wsize = event->size().width(); + session.plot.h = event->size().height(); + session.plot.w = event->size().width(); session.window_changed = true; } diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 7f3a81299..62c438a80 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -38,7 +38,7 @@ #endif // Used to enable/disable use of preferences json file -// #define USE_PREFERENCE_FILE +#define USE_PREFERENCE_FILE #ifdef _WIN32 @@ -412,13 +412,14 @@ static void set_my_executable_path(void) { } static const char *my_user_directory = NULL; -static char _cwd_Buffer [FILENAME_MAX] = {0}; +// static char _cwd_Buffer [FILENAME_MAX] = {0}; const char *get_my_user_directory(void) { return my_user_directory; } + static void set_my_user_directory(void) { - my_user_directory = getenv("HOME"); +/* my_user_directory = getenv("HOME"); // if not found, default to current directory if (my_user_directory == NULL) { @@ -428,6 +429,38 @@ static void set_my_user_directory(void) { if (_cwd_Buffer[i] == '\\') _cwd_Buffer[i] = '/'; // my_user_directory = "."; } +*/ + my_user_directory = getenv("HOME"); + + // if not found, default to current directory + if (my_user_directory == NULL) { + + char *cwd_Buffer = NULL; + uint16_t pathLen = FILENAME_MAX; // should be a good starting point + bool error = false; + + cwd_Buffer = (char *)calloc(pathLen, sizeof(uint8_t)); + + while (!error && (GetCurrentDir (cwd_Buffer,pathLen) == NULL)) { + if (errno == ERANGE) { // Need bigger buffer + pathLen += 10; // if buffer was too small add 10 characters and try again + cwd_Buffer = realloc(cwd_Buffer, pathLen); + } else { + error = true; + free (cwd_Buffer); + cwd_Buffer = NULL; + } + printf ("Len... %d\n",pathLen); + } + + if (!error) { + + for (int i = 0; i < strlen(cwd_Buffer); i++) + if (cwd_Buffer[i] == '\\') cwd_Buffer[i] = '/'; + + my_user_directory = cwd_Buffer; + } + } } static void show_help(bool showFullHelp, char *exec_name) { @@ -668,10 +701,6 @@ int main(int argc, char *argv[]) { // Load Settings and assign // This will allow the command line to override the settings.json values preferences_load(); - // Change height/width (Rows,Cols) - Testing - // printf ("\e[8;50;100t"); - // printf ("\e[3;50;50t"); // x,y - //printf ("Path : %s \n",my_user_directory); // quick patch for debug level g_debugMode = session.client_debug_level; // settings_save (); @@ -877,6 +906,12 @@ int main(int argc, char *argv[]) { session.supports_colors = true; session.emoji_mode = EMOJI; } + } else { + // even if prefs, we disable colors if stdin or stdout is not a TTY + if ((! session.stdinOnTTY) || (! session.stdoutOnTTY)) { + session.supports_colors = false; + session.emoji_mode = ALTTEXT; + } } #else if (session.stdinOnTTY && session.stdoutOnTTY) { @@ -945,9 +980,22 @@ int main(int argc, char *argv[]) { // Doing this here will ensure other checks and updates are saved to over rule default // e.g. Linux color use check if (!session.preferences_loaded) { + PrintAndLogEx (INFO,"Creating initial preferences file"); // json save reports file name, so just info msg here preferences_save(); // Save defaults session.preferences_loaded = true; + } /* else { + // Set device debug level + PrintAndLogEx(INFO,"setting device debug loglevel"); + if (session.pm3_present) { + SendCommandNG(CMD_SET_DBGMODE, &session.device_debug_level, 1); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_SET_DBGMODE, &resp, 2000) == false) + PrintAndLogEx (INFO,"failed to set device debug loglevel"); + } + else + PrintAndLogEx(WARNING,"Proxmark3 not ready to set debug level"); } + */ #endif #ifdef HAVE_GUI diff --git a/client/src/ui.h b/client/src/ui.h index 24c4b7201..e47031d70 100644 --- a/client/src/ui.h +++ b/client/src/ui.h @@ -19,7 +19,10 @@ typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t; typedef enum emojiMode {ALIAS, EMOJI, ALTTEXT, ERASE} emojiMode_t; -typedef enum clientdebugLevel {OFF, SIMPLE, FULL} clientdebugLevel_t; +typedef enum clientdebugLevel {cdbOFF, cdbSIMPLE, cdbFULL} clientdebugLevel_t; +// typedef enum devicedebugLevel {ddbOFF, ddbERROR, ddbINFO, ddbDEBUG, ddbEXTENDED} devicedebugLevel_t; +//typedef enum savePaths {spDefault, spDump, spTrace, spItemCount} savePaths_t; // last item spItemCount used to auto map to number of files +typedef struct {int x; int y; int h; int w;} qtWindow_t; typedef struct { bool preferences_loaded; @@ -31,15 +34,11 @@ typedef struct { bool help_dump_mode; bool show_hints; bool window_changed; // track if plot/overlay pos/size changed to save on exit - int window_plot_xpos; - int window_plot_ypos; - int window_plot_hsize; - int window_plot_wsize; - int window_overlay_xpos; - int window_overlay_ypos; - int window_overlay_hsize; - int window_overlay_wsize; + qtWindow_t plot; + qtWindow_t overlay; +// char *defaultPaths[spItemCount]; // Array should allow loop searching for files clientdebugLevel_t client_debug_level; +// uint8_t device_debug_level; } session_arg_t; extern session_arg_t session;