Fix format-truncation warning, missing string.h inclusion and strnlen warning (#723)
[proxmark3-svn] / client / ui.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
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
12 #include <stdbool.h>
13 #ifndef EXTERNAL_PRINTANDLOG
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <stdarg.h>
17 #include <readline/readline.h>
18 #include <pthread.h>
19 #include "util.h"
20 #endif
21
22 #include "ui.h"
23
24 double CursorScaleFactor = 1;
25 int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0;
26 bool flushAfterWrite = false; //buzzy
27 int GridOffset = 0;
28 bool GridLocked = false;
29 bool showDemod = true;
30
31 static char *logfilename = "proxmark3.log";
32
33 #ifndef EXTERNAL_PRINTANDLOG
34 static pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;
35
36 void 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 {
102 snprintf(buffer2, sizeof(buffer2), "%s%.*s", prefix, MAX_PRINT_BUFFER - 20, buffer);
103 PrintAndLog(buffer2);
104 }
105 }
106
107 void PrintAndLog(char *fmt, ...)
108 {
109 char *saved_line;
110 int saved_point;
111 va_list argptr, argptr2;
112 static FILE *logfile = NULL;
113 static int logging=1;
114
115 // lock this section to avoid interlacing prints from different threads
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 }
125
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.
129 #ifdef RL_STATE_READCMD
130 // We are using GNU readline. libedit (OSX) doesn't support this flag.
131 int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0;
132
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 }
140 #endif
141
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");
148
149 #ifdef RL_STATE_READCMD
150 // We are using GNU readline. libedit (OSX) doesn't support this flag.
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 }
158 #endif
159
160 if (logging && logfile) {
161 vfprintf(logfile, fmt, argptr2);
162 fprintf(logfile,"\n");
163 fflush(logfile);
164 }
165 va_end(argptr2);
166
167 if (flushAfterWrite) //buzzy
168 {
169 fflush(NULL);
170 }
171 //release lock
172 pthread_mutex_unlock(&print_lock);
173 }
174 #endif
175
176 void SetLogFilename(char *fn)
177 {
178 logfilename = fn;
179 }
180
181 void SetFlushAfterWrite(bool flush_after_write) {
182 flushAfterWrite = flush_after_write;
183 }
184
Impressum, Datenschutz