1 /** **************************************************************
2  \page run_scripts Executing Script Parsing Class
3 
4  \par run_script.cxx (FLAMP)
5 
6  \par Author(s):
7  Robert Stiles, KK5VD, Copyright © 2014
8  <br>
9  <br>
10  This is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 3 of the License, or
13  (at your option) any later version. This software is distributed in
14  the hope that it will be useful, but WITHOUT ANY WARRANTY; without
15  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16  PURPOSE.  See the GNU General Public License for more details. You
17  should have received a copy of the GNU General Public License
18  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  <br>
20  <br>
21  \par USE:
22  This code is the interface between the parsing engine and the
23  GUI code. The processing of the GUI is performed via 'C' style
24  callback fuctions.
25  <br>
26  \par NOTE:
27  Do not call process_xxx() functions directly. Must be called from the
28  ScriptParsing Class.
29  *******************************************************************/
30 
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <iostream>
34 #include <fstream>
35 #include <sstream>
36 #include <cstring>
37 #include <ctime>
38 #include <vector>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <stdio.h>
42 #include <errno.h>
43 #include <time.h>
44 #include <pthread.h>
45 #include <libgen.h>
46 #include <ctype.h>
47 #include <sys/time.h>
48 
49 #include <FL/Fl.H>
50 #include <FL/Enumerations.H>
51 #include <FL/Fl_Window.H>
52 #include <FL/Fl_Button.H>
53 #include <FL/Fl_Group.H>
54 #include <FL/Fl_Sys_Menu_Bar.H>
55 #include <FL/x.H>
56 #include <FL/Fl_Help_Dialog.H>
57 #include <FL/Fl_Menu_Item.H>
58 #include <FL/Fl_File_Icon.H>
59 //#include <FL/Fl_Native_File_Chooser.H>
60 #include <FL/Fl_File_Chooser.H>
61 
62 #include "flamp.h"
63 #include "amp.h"
64 #include "flamp_dialog.h"
65 
66 #include "debug.h"
67 #include "util.h"
68 #include "gettext.h"
69 #include "flinput2.h"
70 #include "date.h"
71 #include "calendar.h"
72 #include "icons.h"
73 #include "fileselect.h"
74 #include "file_io.h"
75 #include "status.h"
76 #include "pixmaps.h"
77 #include "threads.h"
78 #include "xml_io.h"
79 #include "tagSearch.h"
80 #include "time_table.h"
81 #include "ztimer.h"
82 #include "script_parsing.h"
83 #include "fileselect.h"
84 
85 #ifdef WIN32
86 #  include "flamprc.h"
87 #  include "compat.h"
88 #endif
89 
90 #include <FL/filename.H>
91 
92 #include <FL/x.H>
93 #include <FL/Fl_Pixmap.H>
94 #include <FL/Fl_Image.H>
95 
96 #ifdef __WIN32__
97 #define PATH_SEPERATOR "\\"
98 #define PATH_CHAR_SEPERATOR '\\'
99 #else
100 #define PATH_SEPERATOR "/"
101 #define PATH_CHAR_SEPERATOR '/'
102 #endif
103 
104 pthread_mutex_t mutex_script_io = PTHREAD_MUTEX_INITIALIZER;
105 
106 extern const char *s_basic_modes[];
107 extern const char *event_types[];
108 
109 extern std::string flamp_script_dir;
110 extern std::string flamp_script_default_dir;
111 
112 extern void addfile(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
113 extern void auto_load_tx_queue_from_tx_directory(void);
114 
115 static int process_auto_load_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
116 static int process_base(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
117 static int process_blocks(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
118 static int process_callfrom(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
119 static int process_clear_missing(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
120 static int process_clear_rx_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
121 static int process_clear_tx_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
122 static int process_compression(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
123 static int process_event_forever(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
124 static int process_event_timed(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
125 static int process_event_times(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
126 static int process_event_type(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
127 static int process_event(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
128 static int process_file(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
129 static int process_hamcast_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
130 static int process_hamcast(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
131 static int process_header_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
132 static int process_header_repeat(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
133 static int process_info(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
134 static int process_inhibit_header(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
135 static int process_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
136 static int process_load_txdir(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
137 static int process_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
138 static int process_queue_filepath(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
139 static int process_reset(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
140 static int process_rx_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
141 static int process_sync_with(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
142 static int process_tx_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
143 static int process_tx_report(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
144 static int process_unproto_markers(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
145 static int process_warn_user(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
146 static int process_xmit_repeat(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
147 
148 #if 0 // Unsued fuctions
149 static int process_callto(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
150 static int process_header(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
151 static int process_path(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
152 static int process_proto(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
153 #endif
154 
155 typedef struct _call_script {
156 	char filename[FL_PATH_MAX];
157 	bool queueflag;
158 } CALL_SCRIPT;
159 
160 CALL_SCRIPT call_script;
161 
162 void script_execute(void *);
163 void script_execute(const char *filename, bool queue_flag);
164 
165 //! @struct command_funcs
166 //! An array of script commands to their respect call functions. Used
167 //! to assign the call back routine.
168 
169 typedef struct command_funcs {
170 	char * command;
171 	int (*func)(ScriptParsing *sp, SCRIPT_COMMANDS *sc);
172 } COMMAND_FUNCS;
173 
174 //! @typedef COMMAND_FUNCS
175 //! @see struct command_funcs
176 //! Storage for the command to function call backs.
177 
178 static COMMAND_FUNCS callback_functions[] = {
179 	{ (char *) CMD_AUTO_LOAD_QUEUE, process_auto_load_queue },
180 	{ (char *) CMD_BASE,            process_base },
181 	{ (char *) CMD_BLOCKS,          process_blocks },
182 	{ (char *) CMD_CALLFROM,        process_callfrom },
183 	{ (char *) CMD_CLEAR_MISSING,   process_clear_missing },
184 	{ (char *) CMD_CLEAR_RXQ,       process_clear_rx_queue },
185 	{ (char *) CMD_CLEAR_TXQ,       process_clear_tx_queue },
186 	{ (char *) CMD_COMP,            process_compression },
187 	{ (char *) CMD_EVENT_FOREVER,   process_event_forever },
188 	{ (char *) CMD_EVENT_TIMED,     process_event_timed },
189 	{ (char *) CMD_EVENT_TIMES,     process_event_times },
190 	{ (char *) CMD_EVENT_TYPE,      process_event_type },
191 	{ (char *) CMD_EVENT,           process_event },
192 	{ (char *) CMD_FILE,            process_file },
193 	{ (char *) CMD_HAMCAST_MODEM,   process_hamcast_modem },
194 	{ (char *) CMD_HAMCAST,         process_hamcast },
195 	{ (char *) CMD_HDR_REPEAT,      process_header_repeat },
196 	{ (char *) CMD_HEADER_MODEM,    process_header_modem },
197 	{ (char *) CMD_INFO,            process_info },
198 	{ (char *) CMD_INHIBIT_HEADER,  process_inhibit_header},
199 	{ (char *) CMD_INTERVAL,        process_interval },
200 	{ (char *) CMD_LOAD_TXDIR,      process_load_txdir},
201 	{ (char *) CMD_MODEM,           process_modem },
202 	{ (char *) CMD_QUEUE_FILEPATH,  process_queue_filepath },
203 	{ (char *) CMD_RESET,           process_reset },
204 	{ (char *) CMD_RX_INTERVAL,     process_rx_interval },
205 	{ (char *) CMD_SYNC_WITH,       process_sync_with },
206 	{ (char *) CMD_TX_INTERVAL,     process_tx_interval },
207 	{ (char *) CMD_TX_REPORT,       process_tx_report },
208 	{ (char *) CMD_UNPROTO_MARKERS, process_unproto_markers },
209 	{ (char *) CMD_WARN_USER,       process_warn_user },
210 	{ (char *) CMD_XMIT_REPEAT,     process_xmit_repeat },
211 #if 0 // Currently not used at this level
212 	{ (char *) CMD_CALLTO,          process_callto }, // Handled in the GUI code
213 	{ (char *) CMD_HEADER,          process_header }, // Handled in HEADER MODEM COMMAND
214 	{ (char *) CMD_PATH,            process_path },   // Handled internally
215 	{ (char *) CMD_PROTO,           process_proto },  // Handled in the GUI code
216 #endif
217 	{ (char *) 0, 0}
218 };
219 
220 #if 0 // Unused Functions, Do not remove code.
221 /** ********************************************************
222  * \brief Enable/Disable protocol use (AMP-2).
223  * \param sp Access to ScritpParsing members.
224  * \param sc Access to SCRIPT_COMMANDS structure variables.
225  * \return 0 (no error) Other (error)
226  ***********************************************************/
227 static int process_proto(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
228 {
229 	bool flag = sp->proto(); // Logic inverted for syntax reasons.
230 
231 	if(flag) {
232 		btn_enable_tx_unproto->value(false);
233 		progStatus.enable_tx_unproto = false;
234 	} else {
235 		btn_enable_tx_unproto->value(true);
236 		progStatus.enable_tx_unproto = true;
237 	}
238 
239 	return 0;
240 }
241 
242 /** ********************************************************
243  * \brief Not used.
244  * \param sp Access to ScritpParsing members.
245  * \param sc Access to SCRIPT_COMMANDS structure variables.
246  * \return 0 (no error) Other (error)
247  ***********************************************************/
248 static int process_header(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
249 {
250 	btn_enable_header_modem->value(sp->header_modem_enable());
251 	progStatus.use_header_modem = sp->header_modem_enable();
252 
253 	return 0;
254 }
255 
256 /** ********************************************************
257  * \brief Assign Call to.
258  * \param sp Access to ScritpParsing members.
259  * \param sc Access to SCRIPT_COMMANDS structure variables.
260  * \return 0 (no error) Other (error)
261  * \par Note:
262  * This string storage can be assigned to anything. User
263  * should follow the limitations imposed by the rules
264  * of the host country.
265  ***********************************************************/
266 static int process_callto(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
267 {
268 	return 0; // Leave this in place. cAmp panel data update conflict.
269 
270 	if(!sp->call_to().empty()) {
271 		txt_tx_send_to->value(sp->call_to().c_str());
272 	}
273 
274 	return 0;
275 }
276 #endif // #if 0 Unused Functions, Do not remove code.
277 
278 /** ********************************************************
279  * \brief Trim leading and trailing spaces from string.
280  * \param s String to modify
281  * \return s modified string.
282  ***********************************************************/
trim(std::string & s)283 static inline std::string &trim(std::string &s) {
284 	char *buffer = (char *)0;
285 	char *dst    = (char *)0;
286 	char *end    = (char *)0;
287 	char *src    = (char *)0;
288 	long count   = s.size();
289 
290 	buffer = new char[count + 1];
291 	if(!buffer) return s;
292 
293 	memcpy(buffer, s.c_str(), count);
294 	buffer[count] = 0;
295 
296 	dst = src = buffer;
297 	end = &buffer[count];
298 
299 	while(src < end) {
300 		if(*src > ' ') break;
301 		src++;
302 	}
303 
304 	if(src > dst) {
305 		while((dst < end) && (src < end))
306 			*dst++ = *src++;
307 		*dst = 0;
308 	}
309 
310 	while(end >= buffer) {
311 		if(*end > ' ') break;
312 		*end-- = 0;
313 	}
314 
315 	s.assign(buffer);
316 
317 	delete [] buffer;
318 
319 	return s;
320 }
321 
322 /** ********************************************************
323  * \brief Assign auto load queue flag for timed events.
324  * \param sp Access to ScritpParsing members.
325  * \param sc Access to SCRIPT_COMMANDS structure variables.
326  * \return 0 (no error) Other (error)
327  ***********************************************************/
process_auto_load_queue(ScriptParsing * sp,SCRIPT_COMMANDS * sc)328 static int process_auto_load_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
329 {
330 	bool value = sp->auto_load_queue();
331 	progStatus.auto_load_queue = value;
332 	btn_auto_load_queue->value(value);
333 
334 	return 0;
335 }
336 
337 /** ********************************************************
338  * \brief Assign base conversion type.
339  * \param sp Access to ScritpParsing members.
340  * \param sc Access to SCRIPT_COMMANDS structure variables.
341  * \return 0 (no error) Other (error)
342  ***********************************************************/
process_base(ScriptParsing * sp,SCRIPT_COMMANDS * sc)343 static int process_base(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
344 {
345 	return 0; // Leave this in place. cAmp panel data update conflict.
346 
347 	char *base_string = (char *)0;
348 	int base = sp->base();
349 	int index = 0;
350 
351 	switch(base) {
352 		case 64:
353 			base_string = (char *) "base64";
354 			index = 1;
355 			break;
356 
357 		case 128:
358 			base_string = (char *) "base128";
359 			index = 2;
360 			break;
361 
362 		case 256:
363 			base_string = (char *) "base256";
364 			index = 3;
365 			break;
366 
367 		default:
368 			LOG_INFO("Unknown base encoder selected (%d)", base);
369 			return -1;
370 	}
371 
372 	progStatus.encoder = index;
373 	encoders->value(base_string);
374 
375 	return 0;
376 }
377 
378 /** ********************************************************
379  * \brief Assign block size.
380  * \param sp Access to ScritpParsing members.
381  * \param sc Access to SCRIPT_COMMANDS structure variables.
382  * \return 0 (no error) Other (error)
383  ***********************************************************/
process_blocks(ScriptParsing * sp,SCRIPT_COMMANDS * sc)384 static int process_blocks(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
385 {
386 	int blocks = sp->blocks();
387 	int mask   = ~0x0f;
388 	int value = 0;
389 
390 	if((blocks >= CNT_BLOCK_SIZE_MINIMUM) && (blocks <= CNT_BLOCK_SIZE_MAXIMUM)) {
391 		value = blocks & mask;
392 		cnt_blocksize->value(value);
393 		progStatus.blocksize = value;
394 	}
395 
396 	return 0;
397 }
398 
399 /** ********************************************************
400  * \brief Assign Call from.
401  * \param sp Access to ScritpParsing members.
402  * \param sc Access to SCRIPT_COMMANDS structure variables.
403  * \return 0 (no error) Other (error)
404  * \par Note:
405  * This string storage can be assigned to anything. User
406  * should follow the limitations imposed by the rules
407  * of the host country.
408  ***********************************************************/
process_callfrom(ScriptParsing * sp,SCRIPT_COMMANDS * sc)409 static int process_callfrom(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
410 {
411 	if(!sp->call_from().empty()) {
412 		txt_tx_mycall->value(sp->call_from().c_str());
413 		progStatus.my_call.assign(sp->call_from());
414 	}
415 
416 	return 0;
417 }
418 
419 /** ********************************************************
420  * \brief Set flag to clear the missing report queue after
421  * the retransmitting of the missed data.
422  * \param sp Access to ScritpParsing members.
423  * \param sc Access to SCRIPT_COMMANDS structure variables.
424  * \return 0 (no error) Other (error)
425  ***********************************************************/
process_clear_missing(ScriptParsing * sp,SCRIPT_COMMANDS * sc)426 static int process_clear_missing(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
427 {
428 	bool value = sp->clear_missing();
429 	progStatus.clear_tosend_on_tx_blocks = value;
430 	btn_clear_tosend_on_tx_blocks->value(value);
431 
432 	return 0;
433 }
434 
435 /** ********************************************************
436  * \brief Clear the receive queue.
437  * \param sp Access to ScritpParsing members.
438  * \param sc Access to SCRIPT_COMMANDS structure variables.
439  * \return 0 (no error) Other (error)
440  ***********************************************************/
process_clear_rx_queue(ScriptParsing * sp,SCRIPT_COMMANDS * sc)441 static int process_clear_rx_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
442 {
443 	int count = rx_queue->size();
444 	if(count) {
445 		rx_queue->select(1);
446 		receive_remove_from_queue(true);
447 	}
448 
449 	return 0;
450 }
451 
452 /** ********************************************************
453  * \brief Clear the transmit queue.
454  * \param sp Access to ScritpParsing members.
455  * \param sc Access to SCRIPT_COMMANDS structure variables.
456  * \return 0 (no error) Other (error)
457  ***********************************************************/
process_clear_tx_queue(ScriptParsing * sp,SCRIPT_COMMANDS * sc)458 static int process_clear_tx_queue(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
459 {
460 	int count = tx_queue->size();
461 	if(count) {
462 		tx_queue->select(1);
463 		tx_removefile(true);
464 	}
465 
466 	return 0;
467 }
468 
469 /** ********************************************************
470  * \brief Enable/Disable Compression. Compression may or may
471  * not be enabled as file size takes precedence.
472  * \param sp Access to ScritpParsing members.
473  * \param sc Access to SCRIPT_COMMANDS structure variables.
474  * \return 0 (no error) Other (error)
475  ***********************************************************/
process_compression(ScriptParsing * sp,SCRIPT_COMMANDS * sc)476 static int process_compression(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
477 {
478 	bool value = sp->comp();
479 	progStatus.use_compression = value;
480 	btn_use_compression->value(value);
481 	return 0;
482 }
483 
484 /** ********************************************************
485  * \brief
486  * \param sp Access to ScritpParsing members.
487  * \param sc Access to SCRIPT_COMMANDS structure variables.
488  * \return 0 (no error) Other (error)
489  ***********************************************************/
process_event_times(ScriptParsing * sp,SCRIPT_COMMANDS * sc)490 static int process_event_times(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
491 {
492 	std::string event_time;
493 
494 	event_time.assign(sp->event_times());
495 	if(event_time.empty()) return 0;
496 
497 	event_time = trim(event_time);
498 	txt_repeat_times->value(event_time.c_str());
499 	progStatus.repeat_times.assign(event_time);
500 
501 	return 0;
502 }
503 
504 /** ********************************************************
505  * \brief
506  * \param sp Access to ScritpParsing members.
507  * \param sc Access to SCRIPT_COMMANDS structure variables.
508  * \return 0 (no error) Other (error)
509  ***********************************************************/
process_event_timed(ScriptParsing * sp,SCRIPT_COMMANDS * sc)510 static int process_event_timed(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
511 {
512 	bool value = sp->event_timed();
513 
514 	btn_repeat_at_times->value(value);
515 	btn_repeat_at_times->do_callback();
516 
517 	if(value)
518 		sp->event_forever(false);
519 
520 	return 0;
521 }
522 
523 /** ********************************************************
524  * \brief
525  * \param sp Access to ScritpParsing members.
526  * \param sc Access to SCRIPT_COMMANDS structure variables.
527  * \return 0 (no error) Other (error)
528  ***********************************************************/
process_event_type(ScriptParsing * sp,SCRIPT_COMMANDS * sc)529 static int process_event_type(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
530 {
531 	int event_type = sp->event_type();
532 	char *cPtr = (char *)0;
533 
534 	switch(event_type) {
535 		case et_5_min:
536 		case et_15_min:
537 		case et_30_min:
538 		case et_hourly:
539 		case et_even_hours:
540 		case et_odd_hours:
541 		case et_repeat_at:
542 		case et_one_time_at:
543 		case et_continious_at:
544 			progStatus.repeat_every = event_type;
545 			cPtr = (char *) event_types[event_type];
546 			if(cPtr) {
547 				cbo_repeat_every->value(cPtr);
548 			}
549 	}
550 
551 	return 0;
552 }
553 
554 /** ********************************************************
555  * \brief Enable/Disable Events (all kinds)
556  * \param sp Access to ScritpParsing members.
557  * \param sc Access to SCRIPT_COMMANDS structure variables.
558  * \return 0 (no error) Other (error)
559  **********************************************************/
process_event(ScriptParsing * sp,SCRIPT_COMMANDS * sc)560 static int process_event(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
561 {
562 	bool value = sp->event();
563 	int results = 1;
564 	int warn = 0;
565 
566 	warn = sp->event_forever() | btn_repeat_forever->value();
567 
568 	if(value && warn)
569 		results = fl_choice2(_("Enable Events?\nIMMEDIATE TRANSMISSION WILL OCCUR!"),
570 							 _("No"), _("Yes"), NULL);
571 
572 	warn = sp->event_timed() | btn_repeat_at_times->value();
573 
574 	if(value && warn)
575 		results = fl_choice2(_("Enable Events?\nImmediate Transmission is possible!"),
576 							 _("No"), _("Yes"), NULL);
577 
578 	if(results) {
579 		do_events->value(value);
580 		do_events->do_callback();
581 	}
582 
583 	return 0;
584 }
585 
586 /** ********************************************************
587  * \brief Enable/Disable forever events
588  * \param sp Access to ScritpParsing members.
589  * \param sc Access to SCRIPT_COMMANDS structure variables.
590  * \return 0 (no error) Other (error)
591  **********************************************************/
process_event_forever(ScriptParsing * sp,SCRIPT_COMMANDS * sc)592 static int process_event_forever(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
593 {
594 
595 	bool repeat_forever = sp->event_forever();
596 	btn_repeat_forever->value(repeat_forever);
597 	btn_repeat_forever->do_callback();
598 	if(repeat_forever)
599 		sp->event_timed(false);
600 
601 	return 0;
602 }
603 
604 /** ********************************************************
605  * \brief Add a file to the transmit queue.
606  * \param sp Access to ScritpParsing members.
607  * \param sc Access to SCRIPT_COMMANDS structure variables.
608  * \return 0 (no error) Other (error)
609  ***********************************************************/
process_file(ScriptParsing * sp,SCRIPT_COMMANDS * sc)610 static int process_file(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
611 {
612 	addfile(sp, sc);
613 
614 	return 0;
615 }
616 
617 /** ********************************************************
618  * \brief Select the Hamcast modem for each of the 4 positions
619  * available.
620  * \param sp Access to ScritpParsing members.
621  * \param sc Access to SCRIPT_COMMANDS structure variables.
622  * \return 0 (no error) Other (error)
623  ***********************************************************/
process_hamcast_modem(ScriptParsing * sp,SCRIPT_COMMANDS * sc)624 static int process_hamcast_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
625 {
626 	if(!sc->args[0]) return -1;
627 
628 	int modem_index = atoi(sc->args[0]);
629 
630 	if(modem_index < 1 || modem_index > 4) return -1;
631 
632 	switch(modem_index) {
633 		case 1:
634 			btn_hamcast_mode_enable_1->value(sp->hamcast_modem_1_enable());
635 			progStatus.hamcast_mode_enable_1 = sp->hamcast_modem_1_enable();
636 
637 			if(!sp->hamcast_modem_1().empty()) {
638 				cbo_hamcast_mode_selection_1->value(sp->hamcast_modem_1().c_str());
639 				progStatus.hamcast_mode_selection_1 = cbo_hamcast_mode_selection_1->index();
640 			}
641 			break;
642 
643 		case 2:
644 			btn_hamcast_mode_enable_2->value(sp->hamcast_modem_2_enable());
645 			progStatus.hamcast_mode_enable_2 = sp->hamcast_modem_2_enable();
646 
647 			if(!sp->hamcast_modem_2().empty()) {
648 				cbo_hamcast_mode_selection_2->value(sp->hamcast_modem_2().c_str());
649 				progStatus.hamcast_mode_selection_2 = cbo_hamcast_mode_selection_2->index();
650 			}
651 			break;
652 
653 		case 3:
654 			btn_hamcast_mode_enable_3->value(sp->hamcast_modem_3_enable());
655 			progStatus.hamcast_mode_enable_3 = sp->hamcast_modem_3_enable();
656 
657 			if(!sp->hamcast_modem_3().empty()) {
658 				cbo_hamcast_mode_selection_3->value(sp->hamcast_modem_3().c_str());
659 				progStatus.hamcast_mode_selection_3 = cbo_hamcast_mode_selection_3->index();
660 			}
661 			break;
662 
663 		case 4:
664 			btn_hamcast_mode_enable_4->value(sp->hamcast_modem_4_enable());
665 			progStatus.hamcast_mode_enable_4 = sp->hamcast_modem_4_enable();
666 
667 			if(!sp->hamcast_modem_4().empty()) {
668 				cbo_hamcast_mode_selection_4->value(sp->hamcast_modem_4().c_str());
669 				progStatus.hamcast_mode_selection_4 = cbo_hamcast_mode_selection_4->index();
670 			}
671 			break;
672 
673 	}
674 
675 	return 0;
676 }
677 
678 /** ********************************************************
679  * \brief Enable/Disable Hamcast operation during event
680  triggered operations.
681  * \param sp Access to ScritpParsing members.
682  * \param sc Access to SCRIPT_COMMANDS structure variables.
683  * \return 0 (no error) Other (error)
684  ***********************************************************/
process_hamcast(ScriptParsing * sp,SCRIPT_COMMANDS * sc)685 static int process_hamcast(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
686 {
687 	btn_hamcast_mode_cycle->value(sp->hamcast());
688 	progStatus.hamcast_mode_cycle = sp->hamcast();
689 	return 0;
690 }
691 
692 /** ********************************************************
693  * \brief Enable/Disable Header modem and select the header
694  * modem used for transmitting.
695  * \param sp Access to ScritpParsing members.
696  * \param sc Access to SCRIPT_COMMANDS structure variables.
697  * \return 0 (no error) Other (error)
698  ***********************************************************/
process_header_modem(ScriptParsing * sp,SCRIPT_COMMANDS * sc)699 static int process_header_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
700 {
701 	btn_enable_header_modem->value(sp->header_modem_enable());
702 	progStatus.use_header_modem = sp->header_modem_enable();
703 
704 	if(!sp->header_modem().empty()) {
705 		cbo_header_modes->value(sp->header_modem().c_str());
706 		progStatus.header_selected_mode = cbo_header_modes->index();
707 	}
708 
709 	return 0;
710 }
711 
712 /** ********************************************************
713  * \brief Number of times the header data is repeated.
714  * \param sp Access to ScritpParsing members.
715  * \param sc Access to SCRIPT_COMMANDS structure variables.
716  * \return 0 (no error) Other (error)
717  ***********************************************************/
process_header_repeat(ScriptParsing * sp,SCRIPT_COMMANDS * sc)718 static int process_header_repeat(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
719 {
720 	int value = sp->hdr_repeat();
721 	int min = cnt_repeat_header->minimum();
722 	int max = cnt_repeat_header->maximum();
723 
724 	if(value > max) value = max;
725 	if(value < min) value = min;
726 
727 	cnt_repeat_header->value(value);
728 	progStatus.repeat_header = value;
729 
730 	return 0;
731 }
732 
733 /** ********************************************************
734  * \brief Set the information field in the configuration panel
735  * \param sp Access to ScritpParsing members.
736  * \param sc Access to SCRIPT_COMMANDS structure variables.
737  * \return 0 (no error) Other (error)
738  ***********************************************************/
process_info(ScriptParsing * sp,SCRIPT_COMMANDS * sc)739 static int process_info(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
740 {
741 	if(!sp->info().empty()) {
742 		txt_tx_myinfo->value(sp->info().c_str());
743 		progStatus.my_info.assign(sp->info());
744 	}
745 
746 	return 0;
747 }
748 
749 /** ********************************************************
750  * \brief Enable/Diable Inhibit header modem on fills.
751  * \param sp Access to ScritpParsing members.
752  * \param sc Access to SCRIPT_COMMANDS structure variables.
753  * \return 0 (no error) Other (error)
754  ***********************************************************/
process_inhibit_header(ScriptParsing * sp,SCRIPT_COMMANDS * sc)755 static int process_inhibit_header(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
756 {
757 	btn_disable_header_modem_on_block_fills->value(sp->inhibit_header());
758 	progStatus.disable_header_modem_on_block_fills = sp->inhibit_header();
759 
760 	return 0;
761 }
762 
763 /** ********************************************************
764  * \brief Enable/Disable Interval timer
765  * \param sp Access to ScritpParsing members.
766  * \param sc Access to SCRIPT_COMMANDS structure variables.
767  * \return 0 (no error) Other (error)
768  ***********************************************************/
process_interval(ScriptParsing * sp,SCRIPT_COMMANDS * sc)769 static int process_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
770 {
771 	btn_enable_txrx_interval->value(sp->interval());
772 	progStatus.use_txrx_interval = sp->interval();
773 
774 	return 0;
775 }
776 
777 /** ********************************************************
778  * \brief Flag event load queue to load from tx/ direcotry
779  * \param sp Access to ScritpParsing members.
780  * \param sc Access to SCRIPT_COMMANDS structure variables.
781  * \return 0 (no error) Other (error)
782  ***********************************************************/
process_load_txdir(ScriptParsing * sp,SCRIPT_COMMANDS * sc)783 static int process_load_txdir(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
784 {
785 	btn_load_from_tx_folder->value(sp->load_txdir());
786 	progStatus.load_from_tx_folder = sp->load_txdir();
787 
788 	return 0;
789 }
790 
791 /** ********************************************************
792  * \brief Select transmit modem
793  * \param sp Access to ScritpParsing members.
794  * \param sc Access to SCRIPT_COMMANDS structure variables.
795  * \return 0 (no error) Other (error)
796  ***********************************************************/
process_modem(ScriptParsing * sp,SCRIPT_COMMANDS * sc)797 static int process_modem(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
798 {
799 	if(!sp->modem().empty()) {
800 		cbo_modes->put_value(sp->modem().c_str());
801 		progStatus.selected_mode = cbo_modes->index();
802 		cbo_modes->do_callback();
803 	}
804 
805 	return 0;
806 }
807 
808 /** ********************************************************
809  * \brief Set the filename and path of the event queue load script.
810  * \param sp Access to ScritpParsing members.
811  * \param sc Access to SCRIPT_COMMANDS structure variables.
812  * \return 0 (no error) Other (error)
813  ***********************************************************/
process_queue_filepath(ScriptParsing * sp,SCRIPT_COMMANDS * sc)814 static int process_queue_filepath(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
815 {
816 	if(sp->queue_filepath().empty()) return 0;
817 
818 	txt_auto_load_queue_path->value(sp->queue_filepath().c_str());
819 	progStatus.auto_load_queue_path.assign(sp->queue_filepath());
820 	return 0;
821 }
822 
823 /** ********************************************************
824  * \brief Reset Configuration panel attributes
825  * \param sp Access to ScritpParsing members.
826  * \param sc Access to SCRIPT_COMMANDS structure variables.
827  * \return 0 (no error) Other (error)
828  ***********************************************************/
process_reset(ScriptParsing * sp,SCRIPT_COMMANDS * sc)829 static int process_reset(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
830 {
831 	int reset_type = sp->reset();
832 
833 	switch(reset_type) {
834 		case RESET_ALL:
835 
836 			sp->call_to("");
837 			txt_tx_mycall->value("");
838 			progStatus.my_call.clear();
839 
840 			sp->info("");
841 			txt_tx_myinfo->value("");
842 			progStatus.my_info.clear();
843 
844 		case RESET_PARTIAL:
845 
846 			sp->interval(false);
847 			btn_enable_txrx_interval->value(false);
848 			progStatus.use_txrx_interval = false;
849 
850 			sp->sync_with_flamp(false);
851 			btn_sync_mode_flamp_fldigi->value(false);
852 			progStatus.sync_mode_flamp_fldigi = false;
853 
854 			sp->sync_with_fldigi(false);
855 			btn_sync_mode_fldigi_flamp->value(false);
856 			progStatus.sync_mode_fldigi_flamp = false;
857 
858 			sp->sync_with_prior(false);
859 			btn_fldigi_xmt_mode_change->value(false);
860 			progStatus.fldigi_xmt_mode_change = false;
861 
862 			sp->tx_report(false);
863 			btn_enable_tx_on_report->value(false);
864 			progStatus.use_txrx_interval = false;
865 
866 			sp->warn_user(false);
867 			btn_enable_delete_warning->value(false);
868 			progStatus.use_tx_on_report = false;
869 
870 			sp->clear_missing(false);
871 			btn_clear_tosend_on_tx_blocks->value(false);
872 			progStatus.clear_tosend_on_tx_blocks = false;
873 
874 			sp->inhibit_header(false);
875 			btn_disable_header_modem_on_block_fills->value(false);
876 			progStatus.disable_header_modem_on_block_fills = false;
877 
878 			sp->header_modem_enable(false);
879 			btn_enable_header_modem->value(false);
880 			progStatus.use_header_modem = false;
881 
882 			sp->proto(true);
883 			btn_enable_tx_unproto->value(false);
884 			progStatus.enable_tx_unproto = false;
885 
886 			sp->unproto_markers(false);
887 			btn_enable_unproto_markers->value(false);
888 			progStatus.enable_unproto_markers = false;
889 
890 			sp->load_txdir(false);
891 			btn_load_from_tx_folder->value(false);
892 			progStatus.load_from_tx_folder = false;
893 
894 			sp->event(false);
895 			btn_repeat_at_times->value(false);
896 			progStatus.repeat_at_times = false;
897 
898 			sp->queue_filepath("");
899 			txt_auto_load_queue_path->value("");
900 			progStatus.auto_load_queue_path.clear();
901 
902 			sp->auto_load_queue(false);
903 			btn_auto_load_queue->value(false);
904 			progStatus.auto_load_queue = false;
905 
906 			sp->event_times("");
907 			txt_repeat_times->value("");
908 			progStatus.repeat_times.clear();
909 
910 			sp->hamcast_modem_1_enable(false);
911 			btn_hamcast_mode_enable_1->value(false);
912 			progStatus.hamcast_mode_enable_1 = false;
913 
914 			sp->hamcast_modem_2_enable(false);
915 			btn_hamcast_mode_enable_2->value(false);
916 			progStatus.hamcast_mode_enable_2 = false;
917 
918 			sp->hamcast_modem_3_enable(false);
919 			btn_hamcast_mode_enable_3->value(false);
920 			progStatus.hamcast_mode_enable_3 = false;
921 
922 			sp->hamcast_modem_4_enable(false);
923 			btn_hamcast_mode_enable_4->value(false);
924 			progStatus.hamcast_mode_enable_4 = false;
925 
926 			sp->hamcast(false);
927 			btn_hamcast_mode_cycle->value(false);
928 			progStatus.hamcast_mode_cycle = false;
929 
930 			sp->event_forever(false);
931 			btn_repeat_forever->value(false);
932 			btn_repeat_forever->do_callback(); // Requires callback()
933 
934 			sp->event_timed(false);
935 			btn_repeat_at_times->value(false);
936 			btn_repeat_at_times->do_callback(); // Requires callback()
937 
938 			do_events->value(false);
939 			do_events->do_callback(); // Requires callback()
940 
941 		default:;
942 	}
943 
944 	return 0;
945 }
946 
947 /** ********************************************************
948  * \brief Set the receive interval in seconds
949  * \param sp Access to ScritpParsing members.
950  * \param sc Access to SCRIPT_COMMANDS structure variables.
951  * \return 0 (no error) Other (error)
952  ***********************************************************/
process_rx_interval(ScriptParsing * sp,SCRIPT_COMMANDS * sc)953 static int process_rx_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
954 {
955 	int max   = cnt_rx_interval_secs->maximum();
956 	int min   = cnt_rx_interval_secs->minimum();
957 	int value = sp->rx_interval();
958 
959 	if(value > max) value = max;
960 	if(value < min) value = min;
961 
962 	cnt_rx_interval_secs->value(value);
963 	progStatus.rx_interval_seconds = value;
964 
965 	return 0;
966 }
967 
968 /** ********************************************************
969  * \brief Set the sync modes between FLAMP and FLDIGI
970  * \param sp Access to ScritpParsing members.
971  * \param sc Access to SCRIPT_COMMANDS structure variables.
972  * \return 0 (no error) Other (error)
973  ***********************************************************/
process_sync_with(ScriptParsing * sp,SCRIPT_COMMANDS * sc)974 static int process_sync_with(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
975 {
976 	std::string str;
977 
978 	str.assign(sc->args[0]);
979 
980 	if(str.empty()) return 0;
981 
982 	int i = 0;
983 	int c = (int) str.size();
984 
985 	for(i = 0; i < c; i++)
986 		str[i] = toupper(str[i]);
987 
988 	if(strncmp(str.c_str(), "FLDIGI", 6) == 0) {
989 		btn_sync_mode_flamp_fldigi->value(sp->sync_with_fldigi());
990 		progStatus.sync_mode_flamp_fldigi = sp->sync_with_fldigi();
991 		btn_sync_mode_flamp_fldigi->do_callback();
992 		return 0;
993 	}
994 
995 	if(strncmp(str.c_str(), "FLAMP", 5) == 0) {
996 		btn_sync_mode_fldigi_flamp->value(sp->sync_with_flamp());
997 		progStatus.sync_mode_fldigi_flamp = sp->sync_with_flamp();
998 		btn_sync_mode_fldigi_flamp->do_callback();
999 		return 0;
1000 	}
1001 
1002 	if(strncmp(str.c_str(), "PRIOR", 5) == 0) {
1003 		btn_fldigi_xmt_mode_change->value(sp->sync_with_prior());
1004 		progStatus.fldigi_xmt_mode_change = sp->sync_with_prior();
1005 		btn_fldigi_xmt_mode_change->do_callback();
1006 		return 0;
1007 	}
1008 
1009 	return -1;
1010 }
1011 
1012 /** ********************************************************
1013  * \brief Set the transmit interval in minutes.
1014  * \param sp Access to ScritpParsing members.
1015  * \param sc Access to SCRIPT_COMMANDS structure variables.
1016  * \return 0 (no error) Other (error)
1017  ***********************************************************/
process_tx_interval(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1018 static int process_tx_interval(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1019 {
1020 	float max   = cnt_tx_interval_mins->maximum();
1021 	float min   = cnt_tx_interval_mins->minimum();
1022 	float value = sp->tx_interval();
1023 
1024 	if(value > max) value = max;
1025 	if(value < min) value = min;
1026 
1027 	cnt_tx_interval_mins->value(value);
1028 	progStatus.tx_interval_minutes = value;
1029 	set_txt_tx_interval();
1030 
1031 	return 0;
1032 }
1033 
1034 /** ********************************************************
1035  * \brief Enable/Disable transmit on report
1036  * \param sp Access to ScritpParsing members.
1037  * \param sc Access to SCRIPT_COMMANDS structure variables.
1038  * \return 0 (no error) Other (error)
1039  ***********************************************************/
process_tx_report(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1040 static int process_tx_report(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1041 {
1042 	btn_enable_tx_on_report->value(sp->tx_report());
1043 	progStatus.use_tx_on_report = sp->tx_report();
1044 
1045 	return 0;
1046 }
1047 
1048 /** ********************************************************
1049  * \brief Enable/Disable unproto start and end markers.
1050  * \param sp Access to ScritpParsing members.
1051  * \param sc Access to SCRIPT_COMMANDS structure variables.
1052  * \return 0 (no error) Other (error)
1053  ***********************************************************/
process_unproto_markers(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1054 static int process_unproto_markers(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1055 {
1056 	btn_enable_unproto_markers->value(sp->unproto_markers());
1057 	progStatus.enable_unproto_markers = sp->unproto_markers();
1058 
1059 	return 0;
1060 }
1061 
1062 /** ********************************************************
1063  * \brief Enable/Disable dialog box warning when deleting
1064  * transmit queue items.
1065  * \param sp Access to ScritpParsing members.
1066  * \param sc Access to SCRIPT_COMMANDS structure variables.
1067  * \return 0 (no error) Other (error)
1068  ***********************************************************/
process_warn_user(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1069 static int process_warn_user(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1070 {
1071 	btn_enable_delete_warning->value(sp->warn_user());
1072 	progStatus.enable_delete_warning = sp->warn_user();
1073 
1074 	return 0;
1075 }
1076 
1077 /** ********************************************************
1078  * \brief Set the number of time the non header data is sent.
1079  * \param sp Access to ScritpParsing members.
1080  * \param sc Access to SCRIPT_COMMANDS structure variables.
1081  * \return 0 (no error) Other (error)
1082  ***********************************************************/
process_xmit_repeat(ScriptParsing * sp,SCRIPT_COMMANDS * sc)1083 static int process_xmit_repeat(ScriptParsing *sp, SCRIPT_COMMANDS *sc)
1084 {
1085 	int max   = cnt_repeat_nbr->maximum();
1086 	int min   = cnt_repeat_nbr->minimum();
1087 	int value = sp->xmit_repeat();
1088 
1089 	if(value > max) value = max;
1090 	if(value < min) value = min;
1091 
1092 	cnt_repeat_nbr->value(value);
1093 	progStatus.repeatNN = value;
1094 
1095 
1096 	return 0;
1097 }
1098 
1099 /** ********************************************************
1100  * \brief Call back function when executing a configuration script.
1101  * Called from the File->Execute Config Script menu item.
1102  * \param void
1103  ***********************************************************/
script_execute(const char * filename,bool queue_flag)1104 void script_execute(const char *filename, bool queue_flag)
1105 {
1106 	int count = 0;
1107 	int index = 0;
1108 	SCRIPT_CODES error = script_no_errors;
1109 	ScriptParsing *sp = 0;
1110 	static std::string script_filename = "";
1111 
1112 	if(!filename) {
1113 		LOG_INFO("Script file name (path) null pointer");
1114 		return;
1115 	}
1116 
1117 	script_filename.assign(filename);
1118 
1119 	if(script_filename.empty()) {
1120 		LOG_INFO("Script file name (path) invalid");
1121 		return;
1122 	}
1123 
1124 	sp = new ScriptParsing;
1125 
1126 	if(!sp) {
1127 		LOG_INFO("ScriptParsing Class Allocation Fail (%s)", script_filename.c_str());
1128 		return;
1129 	}
1130 
1131 	index = 0;
1132 	// All commands support callback functions.
1133 	while(callback_functions[index].command) {
1134 		sp->assign_callback(callback_functions[index].command, callback_functions[index].func);
1135 		index++;
1136 	}
1137 
1138 	count = 0;
1139 	while(s_modes[count]) {
1140 		if(count > 100) break;
1141 		count++;
1142 	}
1143 
1144 	// Assign "validation parameters" to the following functions.
1145 	sp->assign_valid_parameters("MODEM",         (const char **) s_modes, count);
1146 	sp->assign_valid_parameters("HEADER MODEM",  (const char **) s_modes, count);
1147 	sp->assign_valid_parameters("HAMCAST MODEM", (const char **) s_modes, count);
1148 
1149 	// Limit command set depending on queue_flag
1150 
1151 	if(queue_flag) {
1152 		sp->file_type(QUEUE_COMMAND);
1153 	} else {
1154 		sp->file_type(SCRIPT_COMMAND);
1155 	}
1156 
1157 	// LOG_INFO("Executing Script:%s", script_filename.c_str());
1158 
1159 	error = sp->parse_commands((char *) script_filename.c_str());
1160 
1161 	if(error != script_no_errors) {
1162 		LOG_INFO("Error(s) in processing script file: %s", script_filename.c_str());
1163 		fl_alert("%s", "Script File contains Error(s)\nSee Log file for details.");
1164 	}
1165 
1166 	if(sp)
1167 		delete sp;
1168 }
1169 
1170 /** ********************************************************
1171  * \brief Call back function when executing a configuration script.
1172  * Called from the File->Execute Config Script menu item.
1173  * \param void
1174  ***********************************************************/
cb_scripts(bool reset_path=false)1175 void cb_scripts(bool reset_path = false)
1176 {
1177 	pthread_mutex_lock(&mutex_script_io);
1178 
1179 	static bool first_time = true;
1180 	static char script_filename[FL_PATH_MAX + 1];
1181 	std::string new_path = "";
1182 
1183 	if(reset_path || first_time) {
1184 		memset(script_filename, 0, sizeof(script_filename));
1185 		strncpy(script_filename, flamp_script_dir.c_str(), FL_PATH_MAX);
1186 		int len = strnlen(script_filename, FL_PATH_MAX);
1187 
1188 		if(len > 0) {
1189 			len--;
1190 			if(script_filename[len] == PATH_CHAR_SEPERATOR);
1191 			else strncat(script_filename, PATH_SEPERATOR, FL_PATH_MAX);
1192 		} else {
1193 			return;
1194 		}
1195 
1196 		first_time = false;
1197 	}
1198 
1199 	const char *p = FSEL::select((char *)"Script Files", (char *)"*.txt", \
1200 		script_filename);
1201 
1202 	if(p) {
1203 		memset(script_filename, 0, sizeof(script_filename));
1204 		strncpy(script_filename, p, FL_PATH_MAX);
1205 
1206 		Fl::lock();
1207 		script_execute(script_filename, false);
1208 		Fl::unlock();
1209 
1210 		show_selected_xmt(1);
1211 	}
1212 
1213 	pthread_mutex_unlock(&mutex_script_io);
1214 }
1215 
1216 /** ********************************************************
1217  * \brief Call back function when executing a queue script.
1218  * \param void
1219  ***********************************************************/
cb_load_tx_queue(void)1220 void cb_load_tx_queue(void)
1221 {
1222 	std::string script_filename;
1223 	script_filename.assign(txt_auto_load_queue_path->value());
1224 
1225 	if(progStatus.load_from_tx_folder) {
1226 		auto_load_tx_queue_from_tx_directory();
1227 	} else {
1228 		std::string script_filename;
1229 		script_filename.assign(txt_auto_load_queue_path->value());
1230 
1231 		if(script_filename.empty()) {
1232 			LOG_INFO("Queue Load file list (path) not assigned");
1233 			return;
1234 		}
1235 
1236 		pthread_mutex_lock(&mutex_script_io);
1237 		strncpy(call_script.filename, script_filename.c_str(), FL_PATH_MAX-1);
1238 		call_script.queueflag = true;
1239 		Fl::awake(script_execute, (void *)&call_script);
1240 		pthread_mutex_unlock(&mutex_script_io);
1241 	}
1242 
1243 	show_selected_xmt(0);
1244 }
1245 
1246 
1247 /** ********************************************************
1248  * \brief Hander for FL:awake call.
1249  * \param void
1250  ***********************************************************/
script_execute(void * v)1251 void script_execute(void *v) {
1252 	CALL_SCRIPT *s = (CALL_SCRIPT *)v;
1253 	if(!s) return;
1254 	Fl::lock();
1255 	script_execute(s->filename, s->queueflag);
1256 	Fl::unlock();
1257 }
1258 
1259 
1260