Fix format-truncation warning, missing string.h inclusion and strnlen warning (#723)
[proxmark3-svn] / client / ui.c
CommitLineData
a553f267 1//-----------------------------------------------------------------------------
212ef3a0 2// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
a553f267 3// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
4//
5// This code is licensed to you under the terms of the GNU GPL, version 2 or,
6// at your option, any later version. See the LICENSE.txt file for the text of
7// the license.
8//-----------------------------------------------------------------------------
9// UI utilities
10//-----------------------------------------------------------------------------
11
3775e9e8
MF
12#include <stdbool.h>
13#ifndef EXTERNAL_PRINTANDLOG
51969283 14#include <stdlib.h>
7fe9b0b7 15#include <stdio.h>
3775e9e8 16#include <stdarg.h>
51969283 17#include <readline/readline.h>
9492e0b0 18#include <pthread.h>
6b882a39 19#include "util.h"
3775e9e8 20#endif
7fe9b0b7 21
22#include "ui.h"
23
3fe71039 24double CursorScaleFactor = 1;
b8fdac9e 25int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0;
61aaee35 26bool flushAfterWrite = false; //buzzy
0f321d63 27int GridOffset = 0;
3fe71039 28bool GridLocked = false;
b8fdac9e 29bool showDemod = true;
0f321d63 30
7fe9b0b7 31static char *logfilename = "proxmark3.log";
32
3775e9e8 33#ifndef EXTERNAL_PRINTANDLOG
f5ecd97b 34static pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;
3775e9e8 35
6b882a39
OM
36void PrintAndLogEx(logLevel_t level, char *fmt, ...) {
37
38 // skip debug messages if client debugging is turned off i.e. 'DATA SETDEBUG 0'
39// if (g_debugMode == 0 && level == DEBUG)
40// return;
41
42 char buffer[MAX_PRINT_BUFFER] = {0};
43 char buffer2[MAX_PRINT_BUFFER] = {0};
44 char prefix[20] = {0};
45 char *token = NULL;
46 int size = 0;
47 // {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG}
48 static char *prefixes[7] = { "", "", "INFO: ", "FAILED: ", "WARNING: ", "ERROR: ", "#: "};
49
50 switch( level ) {
51 case FAILED:
52 strncpy(prefix,_RED_(FAILED: ), sizeof(prefix)-1);
53 break;
54 case DEBUG:
55 strncpy(prefix,_BLUE_(#: ), sizeof(prefix)-1);
56 break;
57 case SUCCESS:
58 strncpy(prefix,_GREEN_( ), sizeof(prefix)-1);
59 break;
60 case WARNING:
61 strncpy(prefix,_CYAN_(WARNING: ), sizeof(prefix)-1);
62 break;
63 default:
64 strncpy(prefix, prefixes[level], sizeof(prefix)-1);
65 break;
66 }
67
68 va_list args;
69 va_start(args, fmt);
70 vsnprintf(buffer, sizeof(buffer), fmt, args);
71 va_end(args);
72
73 // no prefixes for normal
74 if ( level == NORMAL ) {
75 PrintAndLog(buffer);
76 return;
77 }
78
79 if (strchr(buffer, '\n')) {
80
81 const char delim[2] = "\n";
82
83 // line starts with newline
84 if (buffer[0] == '\n')
85 PrintAndLog("");
86
87 token = strtok(buffer, delim);
88
89 while (token != NULL) {
90
91 size = strlen(buffer2);
92
93 if (strlen(token))
94 snprintf(buffer2+size, sizeof(buffer2)-size, "%s%s\n", prefix, token);
95 else
96 snprintf(buffer2+size, sizeof(buffer2)-size, "\n");
97
98 token = strtok(NULL, delim);
99 }
100 PrintAndLog(buffer2);
101 } else {
994f21fe 102 snprintf(buffer2, sizeof(buffer2), "%s%.*s", prefix, MAX_PRINT_BUFFER - 20, buffer);
6b882a39
OM
103 PrintAndLog(buffer2);
104 }
105}
106
7fe9b0b7 107void PrintAndLog(char *fmt, ...)
108{
51969283
M
109 char *saved_line;
110 int saved_point;
9492e0b0 111 va_list argptr, argptr2;
112 static FILE *logfile = NULL;
113 static int logging=1;
7fe9b0b7 114
acf0582d 115 // lock this section to avoid interlacing prints from different threads
9492e0b0 116 pthread_mutex_lock(&print_lock);
117
118 if (logging && !logfile) {
119 logfile=fopen(logfilename, "a");
120 if (!logfile) {
121 fprintf(stderr, "Can't open logfile, logging disabled!\n");
122 logging=0;
123 }
124 }
ed50f7f3 125
a5a83016
MF
126 // If there is an incoming message from the hardware (eg: lf hid read) in
127 // the background (while the prompt is displayed and accepting user input),
128 // stash the prompt and bring it back later.
ed50f7f3 129#ifdef RL_STATE_READCMD
a5a83016 130 // We are using GNU readline. libedit (OSX) doesn't support this flag.
51969283 131 int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0;
7fe9b0b7 132
51969283
M
133 if (need_hack) {
134 saved_point = rl_point;
135 saved_line = rl_copy_text(0, rl_end);
136 rl_save_prompt();
137 rl_replace_line("", 0);
138 rl_redisplay();
139 }
ed50f7f3 140#endif
51969283 141
9492e0b0 142 va_start(argptr, fmt);
143 va_copy(argptr2, argptr);
144 vprintf(fmt, argptr);
145 printf(" "); // cleaning prompt
146 va_end(argptr);
147 printf("\n");
51969283 148
a5a83016
MF
149#ifdef RL_STATE_READCMD
150 // We are using GNU readline. libedit (OSX) doesn't support this flag.
51969283
M
151 if (need_hack) {
152 rl_restore_prompt();
153 rl_replace_line(saved_line, 0);
154 rl_point = saved_point;
155 rl_redisplay();
156 free(saved_line);
157 }
a5a83016 158#endif
51969283 159
9492e0b0 160 if (logging && logfile) {
161 vfprintf(logfile, fmt, argptr2);
162 fprintf(logfile,"\n");
163 fflush(logfile);
164 }
165 va_end(argptr2);
166
61aaee35 167 if (flushAfterWrite) //buzzy
ed77aabe 168 {
169 fflush(NULL);
170 }
9492e0b0 171 //release lock
172 pthread_mutex_unlock(&print_lock);
7fe9b0b7 173}
3775e9e8 174#endif
9492e0b0 175
7fe9b0b7 176void SetLogFilename(char *fn)
177{
178 logfilename = fn;
179}
61aaee35 180
181void SetFlushAfterWrite(bool flush_after_write) {
182 flushAfterWrite = flush_after_write;
183}
184
Impressum, Datenschutz