+ int path_length = wai_getExecutablePath(NULL, 0, NULL);
+ if (path_length != -1) {
+ my_executable_path = (char*)malloc(path_length + 1);
+ int dirname_length = 0;
+ if (wai_getExecutablePath(my_executable_path, path_length, &dirname_length) != -1) {
+ my_executable_path[path_length] = '\0';
+ my_executable_directory = (char *)malloc(dirname_length + 2);
+ strncpy(my_executable_directory, my_executable_path, dirname_length+1);
+ my_executable_directory[dirname_length+1] = '\0';
+ }
+ }
+}
+
+static void show_help(bool showFullHelp, char *command_line){
+ printf("syntax: %s <port> [-h|-help|-m|-f|-flush|-w|-wait|-c|-command|-l|-lua] [cmd_script_file_name] [command][lua_script_name]\n", command_line);
+ printf("\tLinux example:'%s /dev/ttyACM0'\n", command_line);
+ printf("\tWindows example:'%s com3'\n\n", command_line);
+
+ if (showFullHelp){
+ printf("help: <-h|-help> Dump all interactive command's help at once.\n");
+ printf("\t%s -h\n\n", command_line);
+ printf("markdown: <-m> Dump all interactive help at once in markdown syntax\n");
+ printf("\t%s -m\n\n", command_line);
+ printf("flush: <-f|-flush> Output will be flushed after every print.\n");
+ printf("\t%s -f\n\n", command_line);
+ printf("wait: <-w|-wait> 20sec waiting the serial port to appear in the OS\n");
+ printf("\t%s "SERIAL_PORT_H" -w\n\n", command_line);
+ printf("script: A script file with one proxmark3 command per line.\n\n");
+ printf("command: <-c|-command> Execute one proxmark3 command.\n");
+ printf("\t%s "SERIAL_PORT_H" -c \"hf mf chk 1* ?\"\n", command_line);
+ printf("\t%s "SERIAL_PORT_H" -command \"hf mf nested 1 *\"\n\n", command_line);
+ printf("lua: <-l|-lua> Execute lua script.\n");
+ printf("\t%s "SERIAL_PORT_H" -l hf_read\n\n", command_line);
+ }
+}
+
+int main(int argc, char* argv[]) {
+ srand(time(0));
+
+ bool usb_present = false;
+ bool waitCOMPort = false;
+ bool executeCommand = false;
+ bool addLuaExec = false;
+ char *script_cmds_file = NULL;
+ char *script_cmd = NULL;
+
+ if (argc < 2) {
+ show_help(true, argv[0]);
+ return 1;
+ }
+
+ for (int i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i],"-help") == 0) {
+ show_help(false, argv[0]);
+ dumpAllHelp(0);
+ return 0;
+ }
+
+ if (strcmp(argv[i], "-m") == 0) {
+ dumpAllHelp(1);
+ return 0;
+ }
+
+ if(strcmp(argv[i],"-f") == 0 || strcmp(argv[i],"-flush") == 0){
+ printf("Output will be flushed after every print.\n");
+ flushAfterWrite = 1;
+ }
+
+ if(strcmp(argv[i],"-w") == 0 || strcmp(argv[i],"-wait") == 0){
+ waitCOMPort = true;
+ }
+
+ if(strcmp(argv[i],"-c") == 0 || strcmp(argv[i],"-command") == 0){
+ executeCommand = true;
+ }
+
+ if(strcmp(argv[i],"-l") == 0 || strcmp(argv[i],"-lua") == 0){
+ executeCommand = true;
+ addLuaExec = true;
+ }
+ }
+
+ // If the user passed the filename of the 'script' to execute, get it from last parameter
+ if (argc > 2 && argv[argc - 1] && argv[argc - 1][0] != '-') {
+ if (executeCommand){
+ script_cmd = argv[argc - 1];
+
+ while(script_cmd[strlen(script_cmd) - 1] == ' ')
+ script_cmd[strlen(script_cmd) - 1] = 0x00;
+
+ if (strlen(script_cmd) == 0) {
+ script_cmd = NULL;
+ } else {
+ if (addLuaExec){
+ // add "script run " to command
+ char *ctmp = NULL;
+ int len = strlen(script_cmd) + 11 + 1;
+ if ((ctmp = (char*) malloc(len)) != NULL) {
+ memset(ctmp, 0, len);
+ strcpy(ctmp, "script run ");
+ strcpy(&ctmp[11], script_cmd);
+ script_cmd = ctmp;
+ }
+ }
+
+ printf("Execute command from commandline: %s\n", script_cmd);
+ }
+ } else {
+ script_cmds_file = argv[argc - 1];
+ }
+ }
+
+ // check command
+ if (executeCommand && (!script_cmd || strlen(script_cmd) == 0)){
+ printf("ERROR: execute command: command not found.\n");
+ return 2;
+ }
+
+ // set global variables
+ set_my_executable_path();
+
+ // open uart
+ if (!waitCOMPort) {
+ sp = uart_open(argv[1]);
+ } else {
+ printf("Waiting for Proxmark to appear on %s ", argv[1]);
+ fflush(stdout);
+ int openCount = 0;
+ do {
+ sp = uart_open(argv[1]);
+ msleep(1000);
+ printf(".");
+ fflush(stdout);
+ } while(++openCount < 20 && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT));
+ printf("\n");
+ }
+
+ // check result of uart opening
+ if (sp == INVALID_SERIAL_PORT) {
+ printf("ERROR: invalid serial port\n");
+ usb_present = false;
+ offline = 1;
+ } else if (sp == CLAIMED_SERIAL_PORT) {
+ printf("ERROR: serial port is claimed by another process\n");
+ usb_present = false;
+ offline = 1;
+ } else {
+ usb_present = true;
+ offline = 0;
+ }
+
+ // create a mutex to avoid interlacing print commands from our different threads
+ pthread_mutex_init(&print_lock, NULL);
+
+#ifdef HAVE_GUI
+#ifdef _WIN32
+ InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present);
+ MainGraphics();
+#else
+ char* display = getenv("DISPLAY");
+
+ if (display && strlen(display) > 1)
+ {
+ InitGraphics(argc, argv, script_cmds_file, script_cmd, usb_present);
+ MainGraphics();
+ }
+ else
+ {
+ main_loop(script_cmds_file, script_cmd, usb_present);
+ }
+#endif
+#else
+ main_loop(script_cmds_file, script_cmd, usb_present);
+#endif
+
+ // Clean up the port
+ if (usb_present) {
+ uart_close(sp);
+ }
+
+ // clean up mutex
+ pthread_mutex_destroy(&print_lock);
+
+ exit(0);