1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2014
3 //              David Freese, W1HKJ
4 //
5 // This file is part of flmsg
6 //
7 // flrig is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // flrig is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You 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 // ----------------------------------------------------------------------------
20 
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <iostream>
24 #include <fstream>
25 #include <sstream>
26 #include <cstring>
27 #include <ctime>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <stdio.h>
31 #include <errno.h>
32 
33 #include <FL/Fl.H>
34 #include <FL/Enumerations.H>
35 #include <FL/Fl_Window.H>
36 #include <FL/Fl_Button.H>
37 #include <FL/Fl_Group.H>
38 #include <FL/Fl_Sys_Menu_Bar.H>
39 #include <FL/x.H>
40 #include <FL/Fl_Help_Dialog.H>
41 #include <FL/Fl_Menu_Item.H>
42 #include <FL/Fl_File_Icon.H>
43 
44 #include "config.h"
45 #include "flmsg_config.h"
46 
47 #include "flmsg.h"
48 #include "flmsg_arq.h"
49 
50 #include "templates.h"
51 #include "debug.h"
52 #include "util.h"
53 #include "gettext.h"
54 #include "flmsg_dialog.h"
55 #include "flinput2.h"
56 #include "date.h"
57 #include "calendar.h"
58 #include "icons.h"
59 #include "fileselect.h"
60 #include "wrap.h"
61 #include "status.h"
62 #include "pixmaps.h"
63 #include "threads.h"
64 #include "xml_io.h"
65 
66 #include "socket.h"
67 
68 #include "mongoose.h"
69 
70 #include "timeops.h"
71 
72 #include "arq.h"
73 
74 #ifdef WIN32
75 #  include "flmsgrc.h"
76 #  include "compat.h"
77 #  define dirent fl_dirent_no_thanks
78 #endif
79 
80 #include <FL/filename.H>
81 #include "dirent-check.h"
82 
83 #include <FL/x.H>
84 #include <FL/Fl_Pixmap.H>
85 #include <FL/Fl_Image.H>
86 
87 #include "XmlRpcClient.h"
88 
89 using namespace std;
90 
91 //----------------------------------------------------------------------
92 // Mongoose web server
93 struct mg_server *server = (mg_server *)NULL;
94 void *poll_server(void *);
95 int  start_web_server();
96 void close_server();
97 char *mongoose_msg;
98 string mongoose_msgs;
99 
100 int srvr_portnbr = 8080;
101 char sz_srvr_portnbr[6];
102 
103 //----------------------------------------------------------------------
104 // log files
105 void rotate_log(std::string filename);
106 //----------------------------------------------------------------------
107 
108 const char *options[] = {\
109 "flmsg unique options",
110 "--help",
111 "--version",
112 "--server-port\tstarting port number for forms web server [8080]",
113 "--flmsg-dir\tfull-path-name-of-folder for all FLMSG folders",
114 "--auto-dir\tfull-path-name-of-folder for autosend files",
115 "\tauto-dir, flmsg-dir can be separate and unique",
116 "--p FILENAME\tprint and exit",
117 "--b FILENAME\tprint and stay open",
118 "Fltk UI options",
119 "-bg\t-background [COLOR]",
120 "-bg2\t-background2 [COLOR]",
121 "-di\t-display [host:n.n]",
122 "-dn\t-dnd : enable drag and drop",
123 "-nodn\t-nodnd : disable drag and drop",
124 "-fg\t-foreground [COLOR]",
125 "-g\t-geometry [WxH+X+Y]",
126 "-i\t-iconic",
127 "-k\t-kbd : enable keyboard focus:",
128 "-nok\t-nokbd : en/disable keyboard focus",
129 "-na\t-name [CLASSNAME]",
130 "-s\t-scheme [none | base | gtk+ | plastic | gleam], default = gtk+",
131 "-ti\t[WINDOWTITLE]",
132 "-to\t-tooltips : enable tooltips",
133 "-not\t-notooltips : disable tooltips\n",
134 0
135 };
136 
137 Fl_Double_Window *mainwindow = (Fl_Double_Window *)0;
138 Fl_Double_Window *expert_dialog = (Fl_Double_Window *)0;
139 Fl_Double_Window *tyro_dialog = (Fl_Double_Window *)0;
140 Fl_Double_Window *optionswindow = (Fl_Double_Window *)0;
141 Fl_Double_Window *arlwindow = (Fl_Double_Window *)0;
142 Fl_Double_Window *config_dialog = (Fl_Double_Window *)0;
143 Fl_Double_Window *hxwindow = (Fl_Double_Window *)0;
144 Fl_Double_Window *header_window = (Fl_Double_Window *)0;
145 
146 pthread_t *xmlrpc_thread = 0;
147 pthread_mutex_t mutex_xmlrpc = PTHREAD_MUTEX_INITIALIZER;
148 
149 bool printme = false;
150 bool exit_after_print = false;
151 int  selected_form = NONE;
152 
153 string title;
154 
155 string errtext;
156 
157 // fldigi, flmsg share a common files directory structure
158 
159 #ifdef __WIN32__
160 	string FLMSG_dir_default = "$USERPROFILE/NBEMS.files/";
161 #else
162 	string FLMSG_dir_default = "$HOME/.nbems/";
163 #endif
164 
165 string FLMSG_dir = "";
166 string ARQ_dir = "";
167 string ARQ_files_dir = "";
168 string ARQ_recv_dir = "";
169 string ARQ_send_dir = "";
170 string WRAP_dir = "";
171 string WRAP_recv_dir = "";
172 string WRAP_send_dir = "";
173 //string WRAP_auto_dir = "";
174 string ICS_dir = "";
175 string ICS_msg_dir = "";
176 string ICS_tmp_dir = "";
177 string CSV_dir = "";
178 string CUSTOM_dir = "";
179 string XFR_dir = "";
180 string FLMSG_temp_dir = "";
181 string FLMSG_log_dir = "";
182 string FLMSG_custom_dir = "";
183 
184 string cmd_fname = "";
185 
186 string TITLE = ":TITLE:";
187 
188 string evalstr = "";
189 
190 string parse_info = "";
191 
192 //======================================================================
193 // custom edit/view only program use
194 
195 bool update_custom = false;
196 
197 //======================================================================
198 
199 //string defRTFname = "";
200 
201 // utility functions
202 
203 //----------------------------------------------------------------------
204 // header fields
205 //----------------------------------------------------------------------
206 
207 string hdr_from = "";
208 string hdr_edit = "";
209 static string szFrom = ":hdr_fm:";
210 static string szEdit = ":hdr_ed:";
211 
check_mycall()212 bool check_mycall()
213 {
214 	if (mainwindow == tyro_dialog)
215 		return true;
216 
217 	if (!progStatus.my_call.empty())
218 		return true;
219 
220 	if (!config_dialog->visible())
221 		cb_config_personal();
222 
223 	return false;
224 }
225 
226 // create flmsg line output for string data
lineout(string & field,string & data)227 string lineout(string &field, string &data)
228 {
229 	static string sout;
230 	static char sznum[80];
231 	if (data.empty()) return "";
232 	snprintf(sznum, sizeof(sznum), "%0d", (int)data.length());
233 	sout.assign(field);
234 	sout.append(sznum).append(" ").append(data).append("\n");
235 	return sout;
236 }
237 // create flmsg line output for binary data
binout(string & field,bool & data)238 string binout( string &field, bool &data)
239 {
240 	static string sout;
241 	if (!data) return "";
242 	sout = field;
243 	sout.append(" ").append( data ? "T" : "F").append("\n");
244 	return sout;
245 }
246 
247 //----------------------------------------------------------------------
248 // header for flmsg output file
249 //----------------------------------------------------------------------
clear_header()250 void clear_header()
251 {
252 	hdr_from.clear();
253 	hdr_edit.clear();
254 }
255 
header(const char * msgtype)256 string header(const char *msgtype )
257 {
258 	string hdr;
259 	hdr.assign("<flmsg>").append (PACKAGE_VERSION).append("\n");
260 	hdr.append(lineout(szFrom, hdr_from));
261 	hdr.append(lineout(szEdit, hdr_edit));
262 	hdr.append(msgtype).append("\n");
263 	return hdr;
264 }
265 
read_header(string & str)266 void read_header(string &str)
267 {
268 	clear_header();
269 	hdr_from = findstr(str, szFrom);
270 	hdr_edit = findstr(str, szEdit);
271 }
272 
update_header(hdr_reason reason)273 void update_header(hdr_reason reason)
274 {
275 	if (progStatus.my_call.empty()) return;
276 
277 	static string dt;
278 	int utc = progStatus.UTC;
279 	int dtf = progStatus.dtformat;
280 	progStatus.UTC = 2;
281 	progStatus.dtformat = 4;
282 	dt.assign(szDate()).append(szTime(6));
283 	progStatus.UTC = utc;
284 	progStatus.dtformat = dtf;
285 
286 	switch (reason) {
287 	case NEW :
288 		clear_header();
289 		hdr_edit.assign("\n").append(progStatus.my_call).append(" ").append(dt);
290 		break;
291 	case CHANGED:
292 		if (!hdr_edit.empty()) {
293 			size_t p1 = string::npos, p2 = string::npos;
294 			while( (p1 = hdr_edit.find(progStatus.my_call)) != string::npos) {
295 				p2 = hdr_edit.find("\n", p1);
296 				if (p2 != string::npos)
297 					hdr_edit.erase(p1, p2 - p1 + 1);
298 				else
299 					hdr_edit.erase(p1);
300 			}
301 		}
302 		hdr_edit.append("\n").append(progStatus.my_call).append(" ").append(dt);
303 		break;
304 	case FROM:
305 		if (!hdr_from.empty()) {
306 			size_t p1 = string::npos, p2 = string::npos;
307 			while( (p1 = hdr_from.find(progStatus.my_call)) != string::npos) {
308 				p2 = hdr_from.find("\n", p1);
309 				if (p2 != string::npos)
310 					hdr_from.erase(p1, p2 - p1 + 1);
311 				else
312 					hdr_from.erase(p1);
313 			}
314 		}
315 		hdr_from.append("\n").append(progStatus.my_call).append(" ").append(dt);
316 		break;
317 		default: ;
318 	}
319 	size_t p;
320 	p = hdr_from.find("\n\n");
321 	while(hdr_from.find("\n\n") != string::npos) {
322 		hdr_from.replace(p, 2, "\n");
323 		p = hdr_from.find("\n\n");
324 	}
325 	p = hdr_edit.find("\n\n");
326 	while(hdr_edit.find("\n\n") != string::npos) {
327 		hdr_edit.replace(p, 2, "\n");
328 		p = hdr_edit.find("\n\n");
329 	}
330 }
331 
332 // find string data associated with a field specifier
findstr(string & haystack,string & needle)333 string findstr(string &haystack, string &needle)
334 {
335 	size_t p = haystack.find(needle, 0);
336 	if (p == string::npos) return "";
337 	p += needle.length();
338 	int nchar;
339 	sscanf(&haystack[p], "%d", &nchar);
340 	if (nchar) {
341 		p = haystack.find(' ', p);
342 		p++;
343 		return haystack.substr(p, nchar);
344 	}
345 	return "";
346 }
347 
348 // find boolean data associated with a field specifier
findbin(string & haystack,string & needle)349 bool findbin(string &haystack, string &needle)
350 {
351 	size_t p = haystack.find(needle, 0);
352 	if (p == string::npos) return false;
353 	p += needle.length() + 1;
354 	if (haystack.find("F", p) == p) return false;
355 	if (haystack.find("T", p) == p) return true;
356 	return false;
357 }
358 
359 // replace string
replacestr(string & form,string & where,string & what)360 void replacestr(string &form, string &where, string &what)
361 {
362 	size_t p = form.find(where);
363 	while (p != string::npos) {
364 		form.replace(p, where.length(), what);
365 		p = form.find(where);
366 	}
367 }
368 
replacelf(string & form,int n)369 void replacelf(string &form, int n)
370 {
371 	size_t p = 0;
372 	int i = 0;
373 	while ( (p = form.find("\n", p)) != string::npos) {
374 		form.insert(p, "<br>");
375 		p += 5;
376 		i++;
377 	}
378 	if (n)
379 		for (int j = i; j < n; j++)
380 			form.append("<br>\n");
381 }
382 
substitutestr(string & form,string & where,string & what)383 void substitutestr(string &form, string &where, string &what)
384 {
385 	size_t p = 0;
386 	p = form.find(where, p);
387 	while (p != string::npos) {
388 		form.replace(p, where.length(), what);
389 		p++;
390 		p = form.find(where, p);
391 	}
392 }
393 
striplf(string & what)394 void striplf(string &what)
395 {
396 	while (*what.rbegin() == '\n') what.erase(what.end()-1);
397 }
398 
strip_html(string & buffer)399 void strip_html(string &buffer)
400 {
401 	string amp = "&";		string amprep = "&#38;";
402 	string quote = "\"";	string quoterep = "&#34;";
403 	string less = "<";		string lessrep = "&#60;";
404 	string more = ">";		string morerep = "&#62;";
405 	substitutestr(buffer, amp, amprep);
406 	substitutestr(buffer, quote, quoterep);
407 	substitutestr(buffer, less, lessrep);
408 	substitutestr(buffer, more, morerep);
409 }
410 
remove_cr(string & buffer)411 void remove_cr(string &buffer)
412 {
413 	size_t p = string::npos;
414 	while ((p = buffer.find('\r')) != string::npos) buffer.erase(p,1);
415 }
416 
417 //----------------------------------------------------------------------
remove_spaces_from_filename(string & fname)418 void remove_spaces_from_filename(string &fname)
419 {
420 	size_t n = fname.length();
421 	char szfname[n + 1];
422 	char *p;
423 	memset(szfname, 0, n + 1);
424 	strcpy(szfname, fname.c_str());
425 	p = (char *)fl_filename_name(szfname);
426 	while (*p) {
427 		if (*p == ' ') *p = '_';
428 		p++;
429 	}
430 	fname = szfname;
431 }
432 
szTime(int typ)433 char *szTime(int typ)
434 {
435 	static char szDt[80];
436 	time_t tmptr;
437 	tm sTime;
438 	time (&tmptr);
439 	switch (typ) {
440 		case 0:
441 			localtime_r(&tmptr, &sTime);
442 			strftime(szDt, 79, "%H%ML", &sTime);
443 			break;
444 		case 1:
445 			localtime_r(&tmptr, &sTime);
446 			strftime(szDt, 79, "%H:%ML", &sTime);
447 			break;
448 		case 2:
449 			gmtime_r (&tmptr, &sTime);
450 			strftime(szDt, 79, "%H%MZ", &sTime);
451 			break;
452 		case 3:
453 			gmtime_r (&tmptr, &sTime);
454 			strftime(szDt, 79, "%H:%MZ", &sTime);
455 			break;
456 		case 4:
457 			gmtime_r (&tmptr, &sTime);
458 			strftime(szDt, 79, "%H%M UTC", &sTime);
459 			break;
460 		case 5:
461 			gmtime_r (&tmptr, &sTime);
462 			strftime(szDt, 79, "%H:%M UTC", &sTime);
463 			break;
464 		case 6:
465 			gmtime_r (&tmptr, &sTime);
466 			strftime(szDt, 79, "%H%M%S", &sTime);
467 			break;
468 		case 7:
469 			localtime_r(&tmptr, &sTime);
470 			strftime(szDt, 79, "%H%M", &sTime);
471 			break;
472 		default:
473 			localtime_r(&tmptr, &sTime);
474 			strftime(szDt, 79, "%H%ML", &sTime);
475 	}
476 	return szDt;
477 }
478 
szDate(int df)479 char *szDate(int df)
480 {
481 	static char szDt[80];
482 	time_t tmptr;
483 	tm sTime;
484 	time (&tmptr);
485 	if (progStatus.UTC > 1) {
486 		gmtime_r (&tmptr, &sTime);
487 	} else {
488 		localtime_r(&tmptr, &sTime);
489 	}
490 	switch (df > -1 ? df: progStatus.dtformat) {
491 		case 0: strftime(szDt, 79, "%Y-%m-%d", &sTime); break;
492 		case 1: strftime(szDt, 79, "%m/%d/%y", &sTime); break;
493 		case 2: strftime(szDt, 79, "%d/%m/%y", &sTime); break;
494 		case 3: strftime(szDt, 79, "%Y-%d-%m", &sTime); break;
495 		case 4: strftime(szDt, 79, "%Y%d%m", &sTime); break;
496 		default: strftime(szDt, 79, "%Y-%m-%d", &sTime);
497 	}
498 	return szDt;
499 }
500 
szAbbrevDate()501 char *szAbbrevDate()
502 {
503 	static char szDt[80];
504 	time_t tmptr;
505 	tm sTime;
506 	time (&tmptr);
507 	if (progStatus.UTC) {
508 		gmtime_r (&tmptr, &sTime);
509 	} else {
510 		localtime_r(&tmptr, &sTime);
511 	}
512 	strftime(szDt, 79, "%b %d", &sTime);
513 	for (int i = 0; i < 3; i++) szDt[i] = toupper(szDt[i]);
514 	return szDt;
515 }
516 
szDateTime()517 char *szDateTime()
518 {
519 	static char szDt[80];
520 	time_t tmptr;
521 	tm sTime;
522 	time (&tmptr);
523 	if (progStatus.UTC) {
524 		gmtime_r (&tmptr, &sTime);
525 		strftime(szDt, 79, "%d%H%MZ %b %Y", &sTime);
526 	} else {
527 		localtime_r(&tmptr, &sTime);
528 		strftime(szDt, 79, "%d%H%ML %b %Y", &sTime);
529 	}
530 	for (size_t i = 0; i < strlen(szDt); i++) szDt[i] = toupper(szDt[i]);
531 	return szDt;
532 }
533 
szMarsDateTime()534 char *szMarsDateTime()
535 {
536 	static char szDt[80];
537 	time_t tmptr;
538 	tm sTime;
539 	time (&tmptr);
540 	gmtime_r (&tmptr, &sTime);
541 	strftime(szDt, 79, "%d%H%MZ %b %Y", &sTime);
542 	for (size_t i = 0; i < strlen(szDt); i++) szDt[i] = toupper(szDt[i]);
543 	return szDt;
544 }
545 
szCAPDateTime()546 char *szCAPDateTime()
547 {
548 	static char szDt[80];
549 	time_t tmptr;
550 	tm sTime;
551 	time (&tmptr);
552 	if (progStatus.caplocal) {
553 		localtime_r(&tmptr, &sTime);
554 		strftime(szDt, 79, "%d %H%ML %b %y", &sTime);
555 	} else {
556 		gmtime_r (&tmptr, &sTime);
557 		strftime(szDt, 79, "%d %H%MZ %b %y", &sTime);
558 	}
559 	for (size_t i = 0; i < strlen(szDt); i++) szDt[i] = toupper(szDt[i]);
560 	return szDt;
561 }
562 
named_file()563 char *named_file()
564 {
565 	static char szfname[400];
566 	static char szDt[80];
567 	szfname[0] = 0;
568 	if (!progStatus.call_fname && !progStatus.dt_fname && !progStatus.sernbr_fname)
569 		return szfname;
570 
571 	time_t tmptr;
572 	tm sTime;
573 	time (&tmptr);
574 	switch (progStatus.dt_fname) {
575 		case 1 :
576 			localtime_r (&tmptr, &sTime);
577 			strftime(szDt, sizeof(szDt), "%Y%m%d-%H%M%SL", &sTime);
578 			break;
579 		case 2 :
580 			localtime_r (&tmptr, &sTime);
581 			strftime(szDt, sizeof(szDt), "%Y%m%d-%H%M%S%Z", &sTime);
582 			break;
583 		case 3 :
584 			localtime_r (&tmptr, &sTime);
585 			strftime(szDt, sizeof(szDt), "%Y%m%d-%H%M%S%z", &sTime);
586 			break;
587 		case 4 :
588 			gmtime_r (&tmptr, &sTime);
589 			strftime(szDt, sizeof(szDt), "%Y%m%d-%H%M%SZ", &sTime);
590 			break;
591 		case 0 :
592 		default :
593 			szDt[0] = 0;
594 	}
595 
596 	if (progStatus.call_fname) strcat(szfname, progStatus.my_call.c_str());
597 
598 	if (selected_form == RADIOGRAM  && progStatus.rgnbr_fname) {
599 		if (szfname[0]) strcat(szfname, "-");
600 		strcat(szfname, progStatus.rgnbr.c_str());
601 	} else {
602 		if (szDt[0]) {
603 			if (szfname[0]) strcat(szfname, "-");
604 			strcat(szfname, szDt);
605 		}
606 		if (progStatus.sernbr_fname) {
607 			if (szfname[0]) strcat(szfname, "-");
608 			strcat(szfname, progStatus.sernbr.c_str());
609 		}
610 	}
611 	return szfname;
612 }
613 
update_sernbr()614 void update_sernbr ()
615 {
616 string dfname = FLMSG_dir;
617 dfname.append("flmsg.sernbrs");
618 FILE *debug_file = fl_fopen(dfname.c_str(), "a");
619 	int n = atoi(progStatus.sernbr.c_str());
620 	n++;
621 	char szn[12];
622 	snprintf(szn, sizeof(szn), "%d", n);
623 	progStatus.sernbr = szn;
624 	txt_sernbr->value(szn);
625 	txt_sernbr->redraw();
626 fprintf(debug_file, "New ser # %s\n" , szn);
627 fclose(debug_file);
628 }
629 
extract_text(string & buffer,const char * fname)630 void extract_text(string &buffer, const char *fname)
631 {
632 	remove_cr(buffer);
633 
634 	if (buffer.find("<radiogram>") != string::npos) {
635 		selected_form = RADIOGRAM;
636 		read_rg_buffer(buffer);
637 		if (fname) def_rg_filename = fname;
638 		select_form(selected_form);
639 	} else if (buffer.find("<iaru>") != string::npos) {
640 		selected_form = IARU;
641 		iaru_read_buffer(buffer);
642 		if (fname) iaru_def_filename = fname;
643 		select_form(selected_form);
644 	} else if (buffer.find("<cap105>") != string::npos) {
645 		selected_form = CAP105;
646 		cap105_read_buffer(buffer);
647 		if (fname) cap105_def_filename = fname;
648 		select_form(selected_form);
649 	} else if (buffer.find("<cap110>") != string::npos) {
650 		selected_form = CAP110;
651 		read_c110_buffer(buffer);
652 		if (fname) cap110_def_filename = fname;
653 		select_form(selected_form);
654 	} else if (buffer.find("<mars_daily>") != string::npos) {
655 		selected_form = MARSDAILY;
656 		read_mars_daily_buffer(buffer);
657 		if (fname) def_mars_daily_filename = fname;
658 		select_form(selected_form);
659 	} else if (buffer.find("<mars_ineei>") != string::npos) {
660 		selected_form = MARSINEEI;
661 		read_mars_ineei_buffer(buffer);
662 		if (fname) def_mars_ineei_filename = fname;
663 		select_form(selected_form);
664 	} else if (buffer.find("<mars_net>") != string::npos) {
665 		selected_form = MARSNET;
666 		read_mars_net_buffer(buffer);
667 		if (fname) def_mars_net_filename = fname;
668 		select_form(selected_form);
669 	} else if (buffer.find("<mars_army>") != string::npos) {
670 		selected_form = MARSARMY;
671 		read_mars_army_buffer(buffer);
672 		if (fname) def_mars_army_filename = fname;
673 		select_form(selected_form);
674 	} else if (buffer.find("<nhc_wx>") != string::npos) {
675 		selected_form = WXHC;
676 		read_wxhc_buffer(buffer);
677 		if (fname) def_wxhc_filename = fname;
678 		select_form(selected_form);
679 	} else if (buffer.find("<severe_wx>") != string::npos) {
680 		selected_form = SEVEREWX;
681 		read_severe_wx_buffer(buffer);
682 		if (fname) def_severe_wx_filename = fname;
683 		select_form(selected_form);
684 	} else if (buffer.find("<storm_wx>") != string::npos) {
685 		selected_form = STORMREP;
686 		read_storm_buffer(buffer);
687 		if (fname) def_storm_filename = fname;
688 		select_form(selected_form);
689 	} else if (buffer.find("<hics203>") != string::npos) {
690 		selected_form = HICS203;
691 		read_hics203_buffer(buffer);
692 		if (fname) def_hics203_filename = fname;
693 		select_form(selected_form);
694 	} else if (buffer.find("<hics206>") != string::npos) {
695 		selected_form = HICS206;
696 		h206_read_buffer(buffer);
697 		if (fname) h206_def_filename = fname;
698 		select_form(selected_form);
699 	} else if (buffer.find("<hics213>") != string::npos) {
700 		selected_form = HICS213;
701 		h213_read_buffer(buffer);
702 		if (fname) h213_def_filename = fname;
703 		select_form(selected_form);
704 	} else if (buffer.find("<hics214>") != string::npos) {
705 		selected_form = HICS214;
706 		hics214_read_buffer(buffer);
707 		if (fname) hics214_def_filename = fname;
708 		select_form(selected_form);
709 	} else if (buffer.find("<ics203>") != string::npos) {
710 		selected_form = ICS203;
711 		read_203_buffer(buffer);
712 		if (fname) def_203_filename = fname;
713 		select_form(selected_form);
714 	} else if (buffer.find("<ics205>") != string::npos) {
715 		selected_form = ICS205;
716 		read_205_buffer(buffer);
717 		if (fname) def_205_filename= fname;
718 		select_form(selected_form);
719 	} else if (buffer.find("<ics205a>") != string::npos) {
720 		selected_form = ICS205A;
721 		read_205a_buffer(buffer);
722 		if (fname) def_205a_filename = fname;
723 		select_form(selected_form);
724 	} else if (buffer.find("<ics206>") != string::npos) {
725 		selected_form = ICS206;
726 		read_206_buffer(buffer);
727 		if (fname) def_206_filename = fname;
728 		select_form(selected_form);
729 	} else if (buffer.find("<ics213>") != string::npos) {
730 		selected_form = ICS213;
731 		read_213_buffer(buffer);
732 		if (fname) def_213_filename = fname;
733 		select_form(selected_form);
734 	} else if (buffer.find("<ics214>") != string::npos) {
735 		selected_form = ICS214;
736 		read_214_buffer(buffer);
737 		if (fname) def_214_filename = fname;
738 		select_form(selected_form);
739 	} else if (buffer.find("<ics216>") != string::npos) {
740 		selected_form = ICS216;
741 		read_216_buffer(buffer);
742 		if (fname) def_216_filename = fname;
743 		select_form(selected_form);
744 	} else if (buffer.find("<ics309>") != string::npos) {
745 		selected_form = ICS309;
746 		read_309_buffer(buffer);
747 		if (fname) def_309_filename = fname;
748 		select_form(selected_form);
749 	} else if (buffer.find("<netlog>") != string::npos) {
750 		selected_form = NETLOG;
751 		read_netlog_buffer(buffer);
752 		if (fname) def_netlog_filename = fname;
753 		select_form(selected_form);
754 	} else if (buffer.find("<plaintext>") != string::npos) {
755 		selected_form = PLAINTEXT;
756 		read_ptbuffer(buffer);
757 		if (fname) def_pt_filename = fname;
758 		select_form(selected_form);
759 	} else if (buffer.find("<blankform>") != string::npos) {
760 		selected_form = BLANK;
761 		read_blankbuffer(buffer);
762 		if (fname) def_blank_filename = fname;
763 		select_form(selected_form);
764 	} else if (buffer.find("<csvform>") != string::npos) {
765 		selected_form = CSV;
766 		read_csvbuffer(buffer);
767 		if (fname) def_csv_filename = fname;
768 		select_form(selected_form);
769 	} else if (buffer.find("<customform>") != string::npos) {
770 		selected_form = CUSTOM;
771 		read_custombuffer(buffer);
772 		if (fname) def_custom_filename = fname;
773 		select_form(selected_form);
774 	} else if (!exit_after_print){
775 extern string blank_field;
776 extern void update_blankform();
777 		selected_form = BLANK;
778 		cb_blank_new();
779 		if (fname) def_blank_filename = fname;
780 		select_form(selected_form);
781 		blank_field = buffer;
782 		update_blankform();
783 	}
784 }
785 
786 //
read_data_file(string s)787 void read_data_file(string s)
788 {
789 	long filesize = 0;
790 //	char *buff, *buffend;
791 	int retval;
792 	FILE *icsfile;
793 
794 	icsfile = fopen (s.c_str(), "rb");// "r");
795 	if (!icsfile)
796 		return;
797 // determine its size for buffer creation
798 	fseek (icsfile, 0, SEEK_END);
799 	filesize = ftell (icsfile);
800 // test file integrity
801 	if (filesize == 0) {
802 		fl_alert2(_("Empty file"));
803         fclose (icsfile);
804 		return;
805 	}
806 
807 // read the entire file into the buffer
808 	string buffer;
809 	buffer.resize(filesize);
810 	fseek(icsfile, 0, SEEK_SET);
811 	retval = fread( (void*)buffer.c_str(), 1, filesize, icsfile);
812 	fclose(icsfile);
813 	if (retval != filesize) {
814 		fl_alert2(_("Read error"));
815 		return;
816 	}
817 
818 	extract_text(buffer, s.c_str());
819 }
820 
eval_transfer_size()821 int eval_transfer_size()
822 {
823 	switch (selected_form) {
824 		case ICS203:	return eval_203_fsize();
825 		case ICS205:	return eval_205_fsize();
826 		case ICS205A:	return eval_205a_fsize();
827 		case ICS206:	return eval_206_fsize();
828 		case ICS213:	return eval_213_fsize();
829 		case ICS214:	return eval_214_fsize();
830 		case ICS216:	return eval_216_fsize();
831 		case ICS309:	return eval_309_fsize();
832 		case NETLOG:	return eval_netlog_fsize();
833 		case HICS203:	return eval_hics203_fsize();
834 		case HICS206:	return eval_h206_fsize();
835 		case HICS213:	return eval_h213_fsize();
836 		case HICS214:	return eval_hics214_fsize();
837 		case RADIOGRAM:	return eval_rg_fsize();
838 		case IARU:		return eval_iaru_fsize();
839 		case CAP105:	return eval_cap105_fsize();
840 		case CAP110:	return eval_cap110_fsize();
841 		case PLAINTEXT:	return eval_pt_fsize();
842 		case BLANK:		return eval_blank_fsize();
843 		case CSV:		return eval_csv_fsize();
844 		case CUSTOM:	return eval_custom_fsize();
845 		case TRANSFER:	return eval_transfer_fsize();
846 		case CUSTOM_TRANSFER: return eval_transfer_custom_form_fsize();
847 		case MARSDAILY:	return eval_mars_daily_fsize();
848 		case MARSINEEI:	return eval_mars_ineei_fsize();
849 		case MARSNET:	return eval_mars_net_fsize();
850 		case MARSARMY:	return eval_mars_army_fsize();
851 		case WXHC:		return eval_wxhc_fsize();
852 		case SEVEREWX:	return eval_severe_wx_fsize();
853 		case STORMREP:	return eval_storm_fsize();
854 		default : ;
855 	}
856 	return 0;
857 }
858 
cb_new()859 void cb_new()
860 {
861 	switch (selected_form) {
862 		case ICS203: cb_203_new(); break;
863 		case ICS205: cb_205_new(); break;
864 		case ICS205A: cb_205a_new(); break;
865 		case ICS206: cb_206_new(); break;
866 		case ICS213: cb_213_new(); break;
867 		case ICS214: cb_214_new(); break;
868 		case ICS216: cb_216_new(); break;
869 		case ICS309: cb_309_new(); break;
870 		case NETLOG: cb_netlog_new(); break;
871 		case HICS203: cb_hics203_new(); break;
872 		case HICS206: h206_cb_new(); break;
873 		case HICS213: h213_cb_new(); break;
874 		case HICS214: hics214_cb_new(); break;
875 		case RADIOGRAM: cb_rg_new(); break;
876 		case IARU: iaru_cb_new(); break;
877 		case CAP105: cap105_cb_new(); break;
878 		case CAP110: cap110_cb_new(); break;
879 		case PLAINTEXT: cb_pt_new(); break;
880 		case BLANK: cb_blank_new(); break;
881 		case TRANSFER: cb_transfer_new(); break;
882 		case CSV: cb_csv_new(); break;
883 		case CUSTOM: cb_custom_new(); break;
884 		case MARSDAILY: cb_mars_daily_new(); break;
885 		case MARSINEEI: cb_mars_ineei_new(); break;
886 		case MARSNET: cb_mars_net_new(); break;
887 		case MARSARMY: cb_mars_army_new(); break;
888 		case WXHC: cb_wxhc_new(); break;
889 		case SEVEREWX: cb_severe_wx_new(); break;
890 		case STORMREP: cb_storm_new(); break;
891 		default : return;
892 	}
893 	clear_estimate();
894 }
895 
cb_import()896 void cb_import()
897 {
898 	switch (selected_form) {
899 		case ICS203: cb_203_import(); break;
900 		case ICS205: cb_205_import(); break;
901 		case ICS205A: cb_205a_import(); break;
902 		case ICS206: cb_206_import(); break;
903 		case ICS213: cb_213_import(); break;
904 		case ICS214: cb_214_import(); break;
905 		case ICS216: cb_216_import(); break;
906 		case ICS309: cb_309_import(); break;
907 		case NETLOG: cb_netlog_import(); break;
908 		case HICS203: cb_hics203_import(); break;
909 		case HICS206: h206_cb_import(); break;
910 		case HICS213: h213_cb_import(); break;
911 		case HICS214: hics214_cb_import(); break;
912 		case RADIOGRAM: cb_rg_import(); break;
913 		case IARU: iaru_cb_import(); break;
914 		case CAP105: cap105_cb_import(); break;
915 		case CAP110: cap110_cb_import(); break;
916 		case PLAINTEXT:
917 		case BLANK:
918 		case CSV:
919 		case CUSTOM:
920 		case MARSDAILY:
921 		case MARSINEEI:
922 		case MARSNET:
923 		case MARSARMY:
924 		case WXHC:
925 		case SEVEREWX:
926 		case STORMREP:
927 		default:
928 			fl_alert2("Not implemented");
929 	}
930 	estimate();
931 }
932 
cb_export()933 void cb_export()
934 {
935 	switch (selected_form) {
936 		case ICS203: cb_203_export(); break;
937 		case ICS205: cb_205_export(); break;
938 		case ICS205A: cb_205a_export(); break;
939 		case ICS206: cb_206_export(); break;
940 		case ICS213: cb_213_export(); break;
941 		case ICS214: cb_214_export(); break;
942 		case ICS216: cb_216_export(); break;
943 		case ICS309: cb_309_export(); break;
944 		case NETLOG: cb_netlog_export(); break;
945 		case HICS203: cb_hics203_export(); break;
946 		case HICS206: h206_cb_export(); break;
947 		case HICS213: h213_cb_export(); break;
948 		case HICS214: hics214_cb_export(); break;
949 		case RADIOGRAM: cb_rg_export(); break;
950 		case IARU: iaru_cb_export(); break;
951 		case CAP105: cap105_cb_export(); break;
952 		case CAP110: cap110_cb_export(); break;
953 		case PLAINTEXT:
954 		case BLANK:
955 		case CSV:
956 		case CUSTOM:
957 		case MARSDAILY:
958 		case MARSINEEI:
959 		case MARSNET:
960 		case MARSARMY:
961 		case WXHC:
962 		case SEVEREWX:
963 		case STORMREP:
964 		default:
965 			fl_alert2("Not implemented");
966 	}
967 }
968 
wrap_import(const char * fname)969 void wrap_import(const char *fname)
970 {
971 	string filename;
972 	string inpbuffer;
973 
974 	bool isok = import_wrapfile(fname, filename, inpbuffer);
975 
976 	if (!isok && !exit_after_print) {
977 		isok = !fl_choice2(_("Checksum failed\n\nIgnore errors?"), "yes", "no", NULL);
978 	}
979 
980 	if (inpbuffer.find("<transfer") != string::npos) {
981 		save_this_file_as(filename, inpbuffer);
982 		return;
983 	}
984 
985 	if (isok) {
986 		if (!(inpbuffer.find("<transfer>") != string::npos &&
987 			inpbuffer.find("<html_file>") != string::npos) )
988 			remove_cr( inpbuffer );
989 		if (inpbuffer.find("<flics") != string::npos ||
990 			inpbuffer.find("<flmsg") != string::npos) {
991 			if (inpbuffer.find("<ics203>") != string::npos) {
992 				selected_form = ICS203;
993 				cb_203_wrap_import(filename, inpbuffer);
994 			} else if (inpbuffer.find("<hics203>") != string::npos) {
995 				selected_form = HICS203;
996 				cb_hics203_wrap_import(filename, inpbuffer);
997 			} else if (inpbuffer.find("<hics206>") != string::npos) {
998 				selected_form = HICS206;
999 				h206_cb_wrap_import(filename, inpbuffer);
1000 			} else if (inpbuffer.find("<hics213>") != string::npos) {
1001 				selected_form = HICS213;
1002 				h213_cb_wrap_import(filename, inpbuffer);
1003 			} else if (inpbuffer.find("<hics214>") != string::npos) {
1004 				selected_form = HICS214;
1005 				hics214_cb_wrap_import(filename, inpbuffer);
1006 			} else if (inpbuffer.find("<ics205>") != string::npos) {
1007 				selected_form = ICS205;
1008 				cb_205_wrap_import(filename, inpbuffer);
1009 			} else if (inpbuffer.find("<ics205a>") != string::npos) {
1010 				selected_form = ICS205A;
1011 				cb_205a_wrap_import(filename, inpbuffer);
1012 			} else if (inpbuffer.find("<ics206>") != string::npos) {
1013 				selected_form = ICS206;
1014 				cb_206_wrap_import(filename, inpbuffer);
1015 			} else if (inpbuffer.find("<ics213>") != string::npos) {
1016 				selected_form = ICS213;
1017 				cb_213_wrap_import(filename, inpbuffer);
1018 			} else if (inpbuffer.find("<ics214>") != string::npos) {
1019 				selected_form = ICS214;
1020 				cb_214_wrap_import(filename, inpbuffer);
1021 			} else if (inpbuffer.find("<ics216>") != string::npos) {
1022 				selected_form = ICS216;
1023 				cb_216_wrap_import(filename, inpbuffer);
1024 			} else if (inpbuffer.find("<ics309>") != string::npos) {
1025 				selected_form = ICS309;
1026 				cb_309_wrap_import(filename, inpbuffer);
1027 			} else if (inpbuffer.find("<netlog>") != string::npos) {
1028 				selected_form = NETLOG;
1029 				cb_netlog_wrap_import(filename, inpbuffer);
1030 			} else if (inpbuffer.find("<radiogram>") != string::npos) {
1031 				selected_form = RADIOGRAM;
1032 				cb_rg_wrap_import(filename, inpbuffer);
1033 			} else if (inpbuffer.find("<iaru>") != string::npos) {
1034 				selected_form = IARU;
1035 				iaru_cb_wrap_import(filename, inpbuffer);
1036 			} else if (inpbuffer.find("<cap105>") != string::npos) {
1037 				selected_form = CAP105;
1038 				cap105_cb_wrap_import(filename, inpbuffer);
1039 			} else if (inpbuffer.find("<cap110>") != string::npos) {
1040 				selected_form = CAP110;
1041 				cap110_cb_wrap_import(filename, inpbuffer);
1042 			} else if (inpbuffer.find("<plaintext>") != string::npos) {
1043 				selected_form = PLAINTEXT;
1044 				cb_pt_wrap_import(filename, inpbuffer);
1045 			} else if (inpbuffer.find("<blankform>") != string::npos) {
1046 				selected_form = BLANK;
1047 				cb_blank_wrap_import(filename, inpbuffer);
1048 			} else if (inpbuffer.find("<csvform>") != string::npos) {
1049 				selected_form = CSV;
1050 				cb_csv_wrap_import(filename, inpbuffer);
1051 			} else if (inpbuffer.find("<customform>") != string::npos) {
1052 				selected_form = CUSTOM;
1053 				cb_custom_wrap_import(filename, inpbuffer);
1054 			} else if (inpbuffer.find("<mars_daily>") != string::npos) {
1055 				selected_form = MARSDAILY;
1056 				cb_mars_daily_wrap_import(filename, inpbuffer);
1057 			} else if (inpbuffer.find("<mars_ineei>") != string::npos) {
1058 				selected_form = MARSINEEI;
1059 				cb_mars_ineei_wrap_import(filename, inpbuffer);
1060 			} else if (inpbuffer.find("<mars_net>") != string::npos) {
1061 				selected_form = MARSNET;
1062 				cb_mars_net_wrap_import(filename, inpbuffer);
1063 			} else if (inpbuffer.find("<mars_army>") != string::npos) {
1064 				selected_form = MARSARMY;
1065 				cb_mars_army_wrap_import(filename, inpbuffer);
1066 			} else if (inpbuffer.find("<nhc_wx>") != string::npos) {
1067 				selected_form = WXHC;
1068 				cb_wxhc_wrap_import(filename, inpbuffer);
1069 			} else if (inpbuffer.find("<severe_wx>") != string::npos) {
1070 				selected_form = SEVEREWX;
1071 				cb_severe_wx_wrap_import(filename, inpbuffer);
1072 			} else if (inpbuffer.find("<storm_wx>") != string::npos) {
1073 				selected_form = STORMREP;
1074 				cb_storm_wrap_import(filename, inpbuffer);;
1075 			} else if (inpbuffer.find("<transfer>") != string::npos) {
1076 				selected_form = TRANSFER;
1077 				cb_transfer_wrap_import(filename, inpbuffer);
1078 			} else if (inpbuffer.find("<html_form>") != string::npos) {
1079 				selected_form = CUSTOM_TRANSFER;
1080 				cb_custom_form_wrap_import(filename, inpbuffer);
1081 			} else if (!exit_after_print) {
1082 				selected_form = NONE;
1083 				if (!fl_choice2(_("Cannot identify file type\n\nOpen as text file?"), "yes", "no", NULL)) {
1084 					filename = fname;
1085 					filename.append(".txt");
1086 					FILE *badfile = fopen(filename.c_str(), "w");
1087 					fwrite(inpbuffer.c_str(), inpbuffer.length(), 1, badfile);
1088 					fclose(badfile);
1089 					open_url(filename.c_str());
1090 				}
1091 			}
1092 		}
1093 		select_form(selected_form);
1094 		estimate();
1095 		return;
1096 	}
1097 
1098 	if (printme) {
1099 		string badform = baddata_html_template;
1100 		string mgstr = "<txt:";
1101 
1102 		string badfile_name = ICS_dir;
1103 		badfile_name.append("err.");
1104 		badfile_name.append(fl_filename_name(fname));
1105 		badfile_name.append(".html");
1106 
1107 		string badbuffer = "Error in file: ";
1108 		badbuffer.append(fname).append("\n\n");
1109 		badbuffer.append(errtext);
1110 		replacelf(badbuffer);
1111 
1112 		string title = "Err:";
1113 		title.append(fl_filename_name(fname));
1114 		size_t p = title.rfind('.');
1115 		if (p != string::npos) title.erase(p);
1116 
1117 		replacestr(badform, TITLE, title);
1118 		replacestr(badform, mgstr, badbuffer);
1119 
1120 		FILE *badfile = fopen(badfile_name.c_str(), "w");
1121 		fprintf(badfile,"%s", badform.c_str());
1122 		fclose(badfile);
1123 		open_url(badfile_name.c_str());
1124 		if (exit_after_print)
1125 			return;
1126 		estimate();
1127 	}
1128 
1129 	if (!fl_choice2(_("Open as text file?"), "yes", "no", NULL)) {
1130 		filename = fname;
1131 		filename.append(".txt");
1132 		FILE *badfile = fopen(filename.c_str(), "w");
1133 		fwrite(inpbuffer.c_str(), inpbuffer.length(), 1, badfile);
1134 		fclose(badfile);
1135 		open_url(filename.c_str());
1136 	}
1137 
1138 }
1139 
cb_wrap_import()1140 void cb_wrap_import()
1141 {
1142 	string wrapfilename = WRAP_recv_dir;
1143 	wrapfilename.append("default").append(WRAP_EXT);
1144 	const char *p = FSEL::select(
1145 		"Import wrapped flmsg file",
1146 		"Wrap file\t*.{wrap,WRAP}",
1147 		wrapfilename.c_str());
1148 	if (p)
1149 		wrap_import(p);
1150 }
1151 
cb_wrap_export()1152 void cb_wrap_export()
1153 {
1154 	switch (selected_form) {
1155 		case ICS203: cb_203_wrap_export(); break;
1156 		case ICS205: cb_205_wrap_export(); break;
1157 		case ICS205A: cb_205a_wrap_export(); break;
1158 		case ICS206: cb_206_wrap_export(); break;
1159 		case ICS213: cb_213_wrap_export(); break;
1160 		case ICS214: cb_214_wrap_export(); break;
1161 		case ICS216: cb_216_wrap_export(); break;
1162 		case ICS309: cb_309_wrap_export(); break;
1163 		case NETLOG: cb_netlog_wrap_export(); break;
1164 		case HICS203: cb_hics203_wrap_export(); break;
1165 		case HICS206: h206_cb_wrap_export(); break;
1166 		case HICS213: h213_cb_wrap_export(); break;
1167 		case HICS214: hics214_cb_wrap_export(); break;
1168 		case RADIOGRAM: cb_rg_wrap_export(); break;
1169 		case IARU: iaru_cb_wrap_export(); break;
1170 		case CAP105: cap105_cb_wrap_export(); break;
1171 		case CAP110: cap110_cb_wrap_export(); break;
1172 		case PLAINTEXT: cb_pt_wrap_export(); break;
1173 		case BLANK: cb_blank_wrap_export(); break;
1174 		case CSV: cb_csv_wrap_export(); break;
1175 		case CUSTOM: cb_custom_wrap_export(); break;
1176 		case TRANSFER: break;//cb_transfer_wrap_export(); break;
1177 		case MARSDAILY: cb_mars_daily_wrap_export(); break;
1178 		case MARSINEEI: cb_mars_ineei_wrap_export(); break;
1179 		case MARSNET: cb_mars_net_wrap_export(); break;
1180 		case MARSARMY: cb_mars_army_wrap_export(); break;
1181 		case WXHC: cb_wxhc_wrap_export(); break;
1182 		case SEVEREWX: cb_severe_wx_wrap_export(); break;
1183 		case STORMREP: cb_storm_wrap_export(); break;
1184 		default: return;
1185 	}
1186 
1187 	if (!progStatus.open_on_export)
1188 		return;
1189 
1190 	string location = wrap_outfilename;
1191 	size_t p = location.rfind('/');
1192 	if (p != string::npos)
1193 		location.erase(p+1);
1194 	open_url(location.c_str());
1195 }
1196 
cb_wrap_autosend()1197 void cb_wrap_autosend()
1198 {
1199 	if (progStatus.change_modem_with_autosend)
1200 		send_new_modem();
1201 	switch (selected_form) {
1202 		case ICS203: cb_203_wrap_autosend(); break;
1203 		case ICS205: cb_205_wrap_autosend(); break;
1204 		case ICS205A: cb_205a_wrap_autosend(); break;
1205 		case ICS206: cb_206_wrap_autosend(); break;
1206 		case ICS213: cb_213_wrap_autosend(); break;
1207 		case ICS214: cb_214_wrap_autosend(); break;
1208 		case ICS216: cb_216_wrap_autosend(); break;
1209 		case ICS309: cb_309_wrap_autosend(); break;
1210 		case NETLOG: cb_netlog_wrap_autosend(); break;
1211 		case HICS203: cb_hics203_wrap_autosend(); break;
1212 		case HICS206: h206_cb_wrap_autosend(); break;
1213 		case HICS213: h213_cb_wrap_autosend(); break;
1214 		case HICS214: hics214_cb_wrap_autosend(); break;
1215 		case RADIOGRAM: cb_rg_wrap_autosend(); break;
1216 		case IARU: iaru_cb_wrap_autosend(); break;
1217 		case CAP105: cap105_cb_wrap_autosend(); break;
1218 		case CAP110: cap110_cb_wrap_autosend(); break;
1219 		case PLAINTEXT: cb_pt_wrap_autosend(); break;
1220 		case BLANK: cb_blank_wrap_autosend(); break;
1221 		case CSV: cb_csv_wrap_autosend(); break;
1222 		case CUSTOM: cb_custom_wrap_autosend(); break;
1223 		case TRANSFER: cb_transfer_wrap_autosend(); break;
1224 		case CUSTOM_TRANSFER: cb_transfer_custom_html(); break;
1225 		case MARSDAILY: cb_mars_daily_wrap_autosend(); break;
1226 		case MARSINEEI: cb_mars_ineei_wrap_autosend(); break;
1227 		case MARSNET: cb_mars_net_wrap_autosend(); break;
1228 		case MARSARMY: cb_mars_army_wrap_autosend(); break;
1229 		case WXHC: cb_wxhc_wrap_autosend(); break;
1230 		case SEVEREWX: cb_severe_wx_wrap_autosend(); break;
1231 		case STORMREP: cb_storm_wrap_autosend(); break;
1232 		default: return;
1233 	}
1234 }
1235 
cb_load_template()1236 void cb_load_template()
1237 {
1238 	switch (selected_form) {
1239 		case ICS203: cb_203_load_template(); break;
1240 		case ICS205: cb_205_load_template(); break;
1241 		case ICS205A: cb_205a_load_template(); break;
1242 		case ICS206: cb_206_load_template(); break;
1243 		case ICS213: cb_213_load_template(); break;
1244 		case ICS214: cb_214_load_template(); break;
1245 		case ICS216: cb_216_load_template(); break;
1246 		case ICS309: cb_309_load_template(); break;
1247 		case NETLOG: cb_netlog_load_template(); break;
1248 		case HICS203: cb_hics203_load_template(); break;
1249 		case HICS206: h206_cb_load_template(); break;
1250 		case HICS213: h213_cb_load_template(); break;
1251 		case HICS214: hics214_cb_load_template(); break;
1252 		case RADIOGRAM: cb_rg_load_template(); break;
1253 		case IARU: iaru_cb_load_template(); break;
1254 		case CAP105: cap105_cb_load_template(); break;
1255 		case CAP110: cap110_cb_load_template(); break;
1256 		case PLAINTEXT: cb_pt_load_template(); break;
1257 		case BLANK: cb_blank_load_template(); break;
1258 		case CSV: cb_csv_load_template(); break;
1259 		case CUSTOM: cb_custom_load_template(); break;
1260 		case MARSDAILY: cb_mars_daily_load_template(); break;
1261 		case MARSINEEI: cb_mars_ineei_load_template(); break;
1262 		case MARSNET: cb_mars_net_load_template(); break;
1263 		case MARSARMY: cb_mars_army_load_template(); break;
1264 		case WXHC: cb_wxhc_load_template(); break;
1265 		case SEVEREWX: cb_severe_wx_load_template(); break;
1266 		case STORMREP: cb_storm_load_template(); break;
1267 		default: return;
1268 	}
1269 	estimate();
1270 }
1271 
cb_save_template()1272 void cb_save_template()
1273 {
1274 	switch (selected_form) {
1275 		case ICS203: cb_203_save_template(); break;
1276 		case ICS205: cb_205_save_template(); break;
1277 		case ICS205A: cb_205a_save_template(); break;
1278 		case ICS206: cb_206_save_template(); break;
1279 		case ICS213: cb_213_save_template(); break;
1280 		case ICS214: cb_214_save_template(); break;
1281 		case ICS216: cb_216_save_template(); break;
1282 		case ICS309: cb_309_save_template(); break;
1283 		case NETLOG: cb_netlog_save_template(); break;
1284 		case HICS203: cb_hics203_save_template(); break;
1285 		case HICS206: h206_cb_save_template(); break;
1286 		case HICS213: h213_cb_save_template(); break;
1287 		case HICS214: hics214_cb_save_template(); break;
1288 		case RADIOGRAM: cb_rg_save_template(); break;
1289 		case IARU: iaru_cb_save_template(); break;
1290 		case CAP105: cap105_cb_save_template(); break;
1291 		case CAP110: cap110_cb_save_template(); break;
1292 		case PLAINTEXT: cb_pt_save_template(); break;
1293 		case BLANK: cb_blank_save_template(); break;
1294 		case CSV: cb_csv_save_template(); break;
1295 		case CUSTOM: cb_custom_save_template(); break;
1296 		case MARSDAILY: cb_mars_daily_save_template(); break;
1297 		case MARSINEEI: cb_mars_ineei_save_template(); break;
1298 		case MARSNET: cb_mars_net_save_template(); break;
1299 		case MARSARMY: cb_mars_army_save_template(); break;
1300 		case WXHC: cb_wxhc_save_template(); break;
1301 		case SEVEREWX: cb_severe_wx_save_template(); break;
1302 		case STORMREP: cb_storm_save_template(); break;
1303 		default: return;
1304 	}
1305 }
1306 
cb_save_as_template()1307 void cb_save_as_template()
1308 {
1309 	switch (selected_form) {
1310 		case ICS203: cb_203_save_as_template(); break;
1311 		case ICS205: cb_205_save_as_template(); break;
1312 		case ICS205A: cb_205a_save_as_template(); break;
1313 		case ICS206: cb_206_save_as_template(); break;
1314 		case ICS213: cb_213_save_as_template(); break;
1315 		case ICS214: cb_214_save_as_template(); break;
1316 		case ICS216: cb_216_save_as_template(); break;
1317 		case ICS309: cb_309_save_as_template(); break;
1318 		case NETLOG: cb_netlog_save_as_template(); break;
1319 		case HICS203: cb_hics203_save_as_template(); break;
1320 		case HICS206: h206_cb_save_as_template(); break;
1321 		case HICS213: h213_cb_save_as_template(); break;
1322 		case HICS214: hics214_cb_save_as_template(); break;
1323 		case RADIOGRAM: cb_rg_save_as_template(); break;
1324 		case IARU: iaru_cb_save_as_template(); break;
1325 		case CAP105: cap105_cb_save_as_template(); break;
1326 		case CAP110: cap110_cb_save_as_template(); break;
1327 		case PLAINTEXT: cb_pt_save_as_template(); break;
1328 		case BLANK: cb_blank_save_as_template(); break;
1329 		case CSV: cb_csv_save_as_template(); break;
1330 		case CUSTOM: cb_custom_save_as_template(); break;
1331 		case MARSDAILY: cb_mars_daily_save_as_template(); break;
1332 		case MARSINEEI: cb_mars_ineei_save_as_template(); break;
1333 		case MARSNET: cb_mars_net_save_as_template(); break;
1334 		case MARSARMY: cb_mars_army_save_as_template(); break;
1335 		case WXHC: cb_wxhc_save_as_template(); break;
1336 		case SEVEREWX: cb_severe_wx_save_as_template(); break;
1337 		case STORMREP: cb_storm_save_as_template(); break;
1338 		default: return;
1339 	}
1340 }
1341 
cb_open()1342 void cb_open()
1343 {
1344 	switch (selected_form) {
1345 		case ICS203: cb_203_open(); break;
1346 		case ICS205: cb_205_open(); break;
1347 		case ICS205A: cb_205a_open(); break;
1348 		case ICS206: cb_206_open(); break;
1349 		case ICS213: cb_213_open(); break;
1350 		case ICS214: cb_214_open(); break;
1351 		case ICS216: cb_216_open(); break;
1352 		case ICS309: cb_309_open(); break;
1353 		case NETLOG: cb_netlog_open(); break;
1354 		case HICS203: cb_hics203_open(); break;
1355 		case HICS206: h206_cb_open(); break;
1356 		case HICS213: h213_cb_open(); break;
1357 		case HICS214: hics214_cb_open(); break;
1358 		case RADIOGRAM: cb_rg_open(); break;
1359 		case IARU: iaru_cb_open(); break;
1360 		case CAP105: cap105_cb_open(); break;
1361 		case CAP110: cap110_cb_open(); break;
1362 		case PLAINTEXT: cb_pt_open(); break;
1363 		case BLANK: cb_blank_open(); break;
1364 		case CSV: cb_csv_open(); break;
1365 		case CUSTOM: cb_custom_open(); break;
1366 		case MARSDAILY: cb_mars_daily_open(); break;
1367 		case MARSINEEI: cb_mars_ineei_open(); break;
1368 		case MARSNET: cb_mars_net_open(); break;
1369 		case MARSARMY: cb_mars_army_open(); break;
1370 		case WXHC: cb_wxhc_open(); break;
1371 		case SEVEREWX: cb_severe_wx_open(); break;
1372 		case STORMREP: cb_storm_open(); break;
1373 		default : return;
1374 	}
1375 	estimate();
1376 }
1377 
cb_save_as()1378 void cb_save_as()
1379 {
1380 	switch (selected_form) {
1381 		case ICS203: cb_203_save_as(); break;
1382 		case ICS205: cb_205_save_as(); break;
1383 		case ICS205A: cb_205a_save_as(); break;
1384 		case ICS206: cb_206_save_as(); break;
1385 		case ICS213: cb_213_save_as(); break;
1386 		case ICS214: cb_214_save_as(); break;
1387 		case ICS216: cb_216_save_as(); break;
1388 		case ICS309: cb_309_save_as(); break;
1389 		case NETLOG: cb_netlog_save_as(); break;
1390 		case HICS203: cb_hics203_save_as(); break;
1391 		case HICS206: h206_cb_save_as(); break;
1392 		case HICS213: h213_cb_save_as(); break;
1393 		case HICS214: hics214_cb_save_as(); break;
1394 		case RADIOGRAM: cb_rg_save_as(); break;
1395 		case IARU: iaru_cb_save_as(); break;
1396 		case CAP105: cap105_cb_save_as(); break;
1397 		case CAP110: cap110_cb_save_as(); break;
1398 		case PLAINTEXT: cb_pt_save_as(); break;
1399 		case MARSDAILY: cb_mars_daily_save_as(); break;
1400 		case MARSINEEI: cb_mars_ineei_save_as(); break;
1401 		case MARSNET: cb_mars_net_save_as(); break;
1402 		case MARSARMY: cb_mars_army_save_as(); break;
1403 		case WXHC: cb_wxhc_save_as(); break;
1404 		case SEVEREWX: cb_severe_wx_save_as(); break;
1405 		case STORMREP: cb_storm_save_as(); break;
1406 		case BLANK: cb_blank_save_as(); break;
1407 		case CSV: cb_csv_save_as(); break;
1408 		case CUSTOM: cb_custom_save_as(); break;
1409 		default: return;
1410 	}
1411 }
1412 
cb_save()1413 void cb_save()
1414 {
1415 	switch (selected_form) {
1416 		case ICS203: cb_203_save(); break;
1417 		case ICS205: cb_205_save(); break;
1418 		case ICS205A: cb_205a_save(); break;
1419 		case ICS206: cb_206_save(); break;
1420 		case ICS213: cb_213_save(); break;
1421 		case ICS214: cb_214_save(); break;
1422 		case ICS216: cb_216_save(); break;
1423 		case ICS309: cb_309_save(); break;
1424 		case NETLOG: cb_netlog_save(); break;
1425 		case HICS203: cb_hics203_save(); break;
1426 		case HICS206: h206_cb_save(); break;
1427 		case HICS213: h213_cb_save(); break;
1428 		case HICS214: hics214_cb_save(); break;
1429 		case RADIOGRAM: cb_rg_save(); break;
1430 		case IARU: iaru_cb_save(); break;
1431 		case CAP105: cap105_cb_save(); break;
1432 		case CAP110: cap110_cb_save(); break;
1433 		case PLAINTEXT: cb_pt_save(); break;
1434 		case MARSDAILY: cb_mars_daily_save(); break;
1435 		case MARSINEEI: cb_mars_ineei_save(); break;
1436 		case MARSNET: cb_mars_net_save(); break;
1437 		case MARSARMY: cb_mars_army_save(); break;
1438 		case WXHC: cb_wxhc_save(); break;
1439 		case SEVEREWX: cb_severe_wx_save(); break;
1440 		case STORMREP: cb_storm_save(); break;
1441 		case BLANK: cb_blank_save(); break;
1442 		case CSV: cb_csv_save(); break;
1443 		case CUSTOM: cb_custom_save(); break;
1444 		default: return;
1445 	}
1446 }
1447 
cb_html()1448 void cb_html()
1449 {
1450 	switch (selected_form) {
1451 		case ICS203: cb_203_html(); break;
1452 		case ICS205: cb_205_html(); break;
1453 		case ICS205A: cb_205a_html(); break;
1454 		case ICS206: cb_206_html(); break;
1455 		case ICS213: cb_213_html(); break;
1456 		case ICS214: cb_214_html(); break;
1457 		case ICS216: cb_216_html(); break;
1458 		case ICS309: cb_309_html(); break;
1459 		case NETLOG: cb_netlog_html(); break;
1460 		case HICS203: cb_hics203_html(); break;
1461 		case HICS206: h206_cb_html(); break;
1462 		case HICS213: h213_cb_html(); break;
1463 		case HICS214: hics214_cb_html(); break;
1464 		case RADIOGRAM: cb_rg_html(); break;
1465 		case IARU : iaru_cb_html(); break;
1466 		case CAP105: cap105_cb_html(); break;
1467 		case CAP110: cap110_cb_html(); break;
1468 		case PLAINTEXT: cb_pt_html(); break;
1469 		case MARSDAILY: cb_mars_daily_html(); break;
1470 		case MARSINEEI: cb_mars_ineei_html(); break;
1471 		case MARSNET: cb_mars_net_html(); break;
1472 		case MARSARMY: cb_mars_army_html(); break;
1473 		case WXHC: cb_wxhc_html(); break;
1474 		case SEVEREWX: cb_severe_wx_html(); break;
1475 		case STORMREP: cb_storm_html(); break;
1476 		case BLANK: cb_blank_html(); break;
1477 		case CSV: cb_csv_html(); break;
1478 		case CUSTOM: cb_custom_html(false); break;
1479 		default: return;
1480 	}
1481 }
1482 
cb_html_fcopy()1483 void cb_html_fcopy()
1484 {
1485 	switch (selected_form) {
1486 		case ICS203: cb_203_html(); break;
1487 		case ICS205: cb_205_html(); break;
1488 		case ICS205A: cb_205a_html(); break;
1489 		case ICS206: cb_206_html(); break;
1490 		case ICS213: cb_213_html(); break;
1491 		case ICS214: cb_214_html(); break;
1492 		case ICS216: cb_216_html(); break;
1493 		case ICS309: cb_309_html(); break;
1494 		case NETLOG: cb_netlog_html(); break;
1495 		case HICS203: cb_hics203_html(); break;
1496 		case HICS206: h206_cb_html(); break;
1497 		case HICS213: h213_cb_html(); break;
1498 		case HICS214: hics214_cb_html(); break;
1499 		case RADIOGRAM: cb_rg_html_fcopy(); break;
1500 		default:
1501 			fl_alert2("Not implemented for this form type");
1502 	}
1503 }
1504 
cb_text()1505 void cb_text()
1506 {
1507 	switch (selected_form) {
1508 		case ICS203: cb_203_textout(); break;
1509 		case ICS205: cb_205_textout(); break;
1510 		case ICS205A: cb_205a_textout(); break;
1511 		case ICS206: cb_206_textout(); break;
1512 		case ICS213: cb_213_textout(); break;
1513 		case ICS214: cb_214_textout(); break;
1514 		case ICS216: cb_216_textout(); break;
1515 		case ICS309: cb_309_textout(); break;
1516 		case NETLOG: cb_netlog_textout(); break;
1517 		case HICS203: cb_hics203_textout(); break;
1518 		case HICS206: h206_cb_textout(); break;
1519 		case HICS213: h213_cb_textout(); break;
1520 		case HICS214: hics214_cb_textout(); break;
1521 		case RADIOGRAM: cb_rg_textout(); break;
1522 		case IARU: iaru_cb_textout(); break;
1523 		case CAP105: cap105_cb_textout(); break;
1524 		case CAP110: cap110_cb_textout(); break;
1525 		case PLAINTEXT: cb_pt_textout(); break;
1526 		case MARSDAILY: cb_mars_daily_textout(); break;
1527 		case MARSINEEI: cb_mars_ineei_textout(); break;
1528 		case MARSNET: cb_mars_net_textout(); break;
1529 		case MARSARMY: cb_mars_army_textout(); break;
1530 		case WXHC: cb_wxhc_textout(); break;
1531 		case SEVEREWX: cb_severe_wx_textout(); break;
1532 		case STORMREP: cb_storm_textout(); break;
1533 		case CSV: cb_csv_textout(); break;
1534 		case CUSTOM: cb_custom_textout(); break;
1535 		case BLANK: cb_blank_textout(); break;
1536 		default : return;
1537 	}
1538 }
1539 
1540 //extern void disconnect_from_fldigi();
1541 
cb_exit()1542 void cb_exit()
1543 {
1544 	progStatus.saveLastState();
1545 	FSEL::destroy();
1546 
1547 	Fl::remove_timeout(mainloop);
1548 
1549 	if (progStatus.ID_restore) restore_id();
1550 
1551 	close_xmlrpc();
1552 	close_server();
1553 
1554 	debug::stop();
1555 
1556 	if (expert_dialog) delete expert_dialog;
1557 	if (tyro_dialog) delete tyro_dialog;
1558 
1559 	exit(0);
1560 }
1561 
exit_main(Fl_Widget * w)1562 void exit_main(Fl_Widget *w)
1563 {
1564 	if (Fl::event_key() == FL_Escape)
1565 		return;
1566 	cb_exit();
1567 }
1568 
cb_About()1569 void cb_About()
1570 {
1571 	std::string strver = _("Version ");
1572 	strver.append(PACKAGE_VERSION);
1573 	fl_alert2("%s", strver.c_str());
1574 }
1575 
cb_folders()1576 void cb_folders()
1577 {
1578 	open_url(FLMSG_dir.c_str(), 1);
1579 }
1580 
show_filename(string p)1581 void show_filename(string p)
1582 {
1583 	switch (selected_form) {
1584 		case ICS203:
1585 			base_203_filename = fl_filename_name(p.c_str());
1586 			break;
1587 		case ICS205:
1588 			base_205_filename = fl_filename_name(p.c_str());
1589 			break;
1590 		case ICS205A:
1591 			base_205a_filename = fl_filename_name(p.c_str());
1592 			break;
1593 		case ICS206:
1594 			base_206_filename = fl_filename_name(p.c_str());
1595 			break;
1596 		case ICS213:
1597 			base_213_filename = fl_filename_name(p.c_str());
1598 			break;
1599 		case ICS214:
1600 			base_214_filename = fl_filename_name(p.c_str());
1601 			break;
1602 		case ICS216:
1603 			base_216_filename = fl_filename_name(p.c_str());
1604 			break;
1605 		case ICS309:
1606 			base_309_filename = fl_filename_name(p.c_str());
1607 			break;
1608 		case NETLOG:
1609 			base_netlog_filename = fl_filename_name(p.c_str());
1610 			break;
1611 		case HICS203:
1612 			base_hics203_filename = fl_filename_name(p.c_str());
1613 			break;
1614 		case HICS206:
1615 			h206_base_filename = fl_filename_name(p.c_str());
1616 			break;
1617 		case HICS213:
1618 			h213_base_filename = fl_filename_name(p.c_str());
1619 			break;
1620 		case HICS214:
1621 			hics214_base_filename = fl_filename_name(p.c_str());
1622 			break;
1623 		case RADIOGRAM:
1624 			base_rg_filename = fl_filename_name(p.c_str());
1625 			break;
1626 		case IARU:
1627 			iaru_base_filename = fl_filename_name(p.c_str());
1628 			break;
1629 		case CAP105:
1630 			cap105_base_filename = fl_filename_name(p.c_str());
1631 			break;
1632 		case CAP110:
1633 			cap110_base_filename = fl_filename_name(p.c_str());
1634 			break;
1635 		case PLAINTEXT:
1636 			base_pt_filename = fl_filename_name(p.c_str());
1637 			break;
1638 		case MARSDAILY:
1639 			base_mars_daily_filename = fl_filename_name(p.c_str());
1640 			break;
1641 		case MARSINEEI:
1642 			base_mars_ineei_filename = fl_filename_name(p.c_str());
1643 			break;
1644 		case MARSNET:
1645 			base_mars_net_filename = fl_filename_name(p.c_str());
1646 			break;
1647 		case MARSARMY:
1648 			base_mars_army_filename = fl_filename_name(p.c_str());
1649 			break;
1650 		case WXHC:
1651 			base_wxhc_filename = fl_filename_name(p.c_str());
1652 			break;
1653 		case SEVEREWX:
1654 			base_severe_wx_filename = fl_filename_name(p.c_str());
1655 			break;
1656 		case STORMREP:
1657 			base_storm_filename = fl_filename_name(p.c_str());
1658 			break;
1659 		case BLANK:
1660 			base_blank_filename = fl_filename_name(p.c_str());
1661 			break;
1662 		case CSV:
1663 			base_csv_filename = fl_filename_name(p.c_str());
1664 			break;
1665 		case CUSTOM:
1666 			base_custom_filename = fl_filename_name(p.c_str());
1667 			break;
1668 		case TRANSFER:
1669 			base_transfer_filename = fl_filename_name(p.c_str());
1670 			break;
1671 		case CUSTOM_TRANSFER:
1672 			break;
1673 		default:
1674 			return;
1675 	}
1676 	txt_filename->value(fl_filename_name(p.c_str()));
1677 	txt_filename->redraw();
1678 }
1679 
1680 #define KNAME "fllog"
1681 
1682 #if !defined(__APPLE__) && !defined(__WOE32__) && USE_X
1683 Pixmap  flmsg_icon_pixmap;
1684 
make_pixmap(Pixmap * xpm,const char ** data)1685 void make_pixmap(Pixmap *xpm, const char **data)
1686 {
1687 	Fl_Window w(0,0, KNAME);
1688 	w.xclass(KNAME);
1689 	w.show();
1690 	w.make_current();
1691 	Fl_Pixmap icon(data);
1692 	int maxd = (icon.w() > icon.h()) ? icon.w() : icon.h();
1693 	*xpm = fl_create_offscreen(maxd, maxd);
1694 	fl_begin_offscreen(*xpm);
1695 	fl_color(FL_BACKGROUND_COLOR);
1696 	fl_rectf(0, 0, maxd, maxd);
1697 	icon.draw(maxd - icon.w(), maxd - icon.h());
1698 	fl_end_offscreen();
1699 }
1700 
1701 #endif
1702 
1703 
default_form()1704 void default_form()
1705 {
1706 	selected_form = progStatus.tab;
1707 	select_form(selected_form);
1708 	cb_new();
1709 }
1710 
1711 #if FLMSG_FLTK_API_MAJOR == 1 && FLMSG_FLTK_API_MINOR == 3
default_handler(int event)1712 int default_handler(int event)
1713 {
1714 	if (event != FL_SHORTCUT)
1715 		return 0;
1716 
1717 	else if (Fl::event_ctrl())  {
1718 		Fl_Widget* w = Fl::focus();
1719 		return w->handle(FL_KEYBOARD);
1720 	}
1721 
1722 	return 0;
1723 }
1724 #endif
1725 
1726 #ifdef __APPLE__
1727 // registered file drop call back to operating system
open_callback(const char * param)1728 void open_callback(const char *param)
1729 {
1730 	string pathname = param;
1731 	if (pathname.find(WRAP_EXT) != string::npos)
1732 		wrap_import(pathname.c_str());
1733 	else {
1734 		read_data_file(pathname);
1735 		show_filename(pathname);
1736 	}
1737 }
1738 #endif
1739 
after_start(void *)1740 void after_start(void *)
1741 {
1742 	check_mycall();
1743 
1744 	def_203_filename = ICS_msg_dir;
1745 	def_203_filename.append("default").append(F203_EXT);
1746 	def_203_TemplateName = ICS_tmp_dir;
1747 	def_203_TemplateName.append("default").append(T203_EXT);
1748 
1749 	def_205_filename = ICS_msg_dir;
1750 	def_205_filename.append("default").append(F205_EXT);
1751 	def_205_TemplateName = ICS_tmp_dir;
1752 	def_205_TemplateName.append("default").append(T205_EXT);
1753 
1754 	def_205a_filename = ICS_msg_dir;
1755 	def_205a_filename.append("default").append(F205A_EXT);
1756 	def_205a_TemplateName = ICS_tmp_dir;
1757 	def_205a_TemplateName.append("default").append(T205A_EXT);
1758 
1759 	def_206_filename = ICS_msg_dir;
1760 	def_206_filename.append("default").append(F206_EXT);
1761 	def_206_TemplateName = ICS_tmp_dir;
1762 	def_206_TemplateName.append("default").append(T206_EXT);
1763 
1764 	def_213_filename = ICS_msg_dir;
1765 	def_213_filename.append("default").append(F213_EXT);
1766 	def_213_TemplateName = ICS_tmp_dir;
1767 	def_213_TemplateName.append("default").append(T213_EXT);
1768 
1769 	def_214_filename = ICS_msg_dir;
1770 	def_214_filename.append("default").append(F214_EXT);
1771 	def_214_TemplateName = ICS_tmp_dir;
1772 	def_214_TemplateName.append("default").append(T214_EXT);
1773 
1774 	def_216_filename = ICS_msg_dir;
1775 	def_216_filename.append("default").append(F216_EXT);
1776 	def_216_TemplateName = ICS_tmp_dir;
1777 	def_216_TemplateName.append("default").append(T216_EXT);
1778 
1779 	def_309_filename = ICS_msg_dir;
1780 	def_309_filename.append("default").append(F309_EXT);
1781 	def_309_TemplateName = ICS_tmp_dir;
1782 	def_309_TemplateName.append("default").append(T309_EXT);
1783 
1784 	def_netlog_filename = ICS_msg_dir;
1785 	def_netlog_filename.append("default").append(FNET_EXT);
1786 	def_netlog_TemplateName = ICS_tmp_dir;
1787 	def_netlog_TemplateName.append("default").append(TNET_EXT);
1788 
1789 	def_hics203_filename = ICS_msg_dir;
1790 	def_hics203_filename.append("default").append(HF203_EXT);
1791 	def_hics203_TemplateName = ICS_tmp_dir;
1792 	def_hics203_TemplateName.append("default").append(HT203_EXT);
1793 
1794 	h206_def_filename = ICS_msg_dir;
1795 	h206_def_filename.append("default").append(HF206_EXT);
1796 	h206_def_template_name = ICS_tmp_dir;
1797 	h206_def_template_name.append("default").append(HT206_EXT);
1798 
1799 	h213_def_filename = ICS_msg_dir;
1800 	h213_def_filename.append("default").append(HF213_EXT);
1801 	h213_def_template_name = ICS_tmp_dir;
1802 	h213_def_template_name.append("default").append(HT213_EXT);
1803 
1804 	hics214_def_filename = ICS_msg_dir;
1805 	hics214_def_filename.append("default").append(HF214_EXT);
1806 	hics214_template_name = ICS_tmp_dir;
1807 	hics214_template_name.append("default").append(HT214_EXT);
1808 
1809 	def_rg_filename = ICS_msg_dir;
1810 	def_rg_filename.append("default").append(RGFILE_EXT);
1811 	def_rg_TemplateName = ICS_tmp_dir;
1812 	def_rg_TemplateName.append("default").append(RGTEMP_EXT);
1813 
1814 	iaru_def_filename = ICS_msg_dir;
1815 	iaru_def_filename.append("default").append(IARU_FILE_EXT);
1816 	iaru_def_template_name = ICS_tmp_dir;
1817 	iaru_def_template_name.append("default").append(IARU_TEMP_EXT);
1818 
1819 	cap105_def_filename = ICS_msg_dir;
1820 	cap105_def_filename.append("default").append(CAP105_FILE_EXT);
1821 	cap105_def_template_name = ICS_tmp_dir;
1822 	cap105_def_template_name.append("default").append(CAP105_TEMP_EXT);
1823 	cap105_set_choices();
1824 
1825 	cap110_def_filename = ICS_msg_dir;
1826 	cap110_def_filename.append("default").append(CAP105_FILE_EXT);
1827 	cap110_def_template_name = ICS_tmp_dir;
1828 	cap110_def_template_name.append("default").append(CAP105_TEMP_EXT);
1829 
1830 	def_pt_filename = ICS_msg_dir;
1831 	def_pt_filename.append("default").append(PTFILE_EXT);
1832 	def_pt_TemplateName = ICS_tmp_dir;
1833 	def_pt_TemplateName.append("default").append(PTTEMP_EXT);
1834 
1835 	def_blank_filename = ICS_msg_dir;
1836 	def_blank_filename.append("default").append(BLANKFILE_EXT);
1837 	def_blank_TemplateName = ICS_tmp_dir;
1838 	def_blank_TemplateName.append("default").append(BLANKTEMP_EXT);
1839 
1840 	def_csv_filename = ICS_msg_dir;
1841 	def_csv_filename.append("default").append(CSVFILE_EXT);
1842 	def_csv_TemplateName = ICS_tmp_dir;
1843 	def_csv_TemplateName.append("default").append(CSVTEMP_EXT);
1844 
1845 	def_custom_filename = ICS_msg_dir;
1846 	def_custom_filename.append("default").append(CUSTOMFILE_EXT);
1847 	def_custom_TemplateName = ICS_tmp_dir;
1848 	def_custom_TemplateName.append("default").append(CUSTOMTEMP_EXT);
1849 
1850 	def_mars_daily_filename = ICS_msg_dir;
1851 	def_mars_daily_filename.append("default").append(FMARSDAILY_EXT);
1852 	def_mars_daily_TemplateName = ICS_tmp_dir;
1853 	def_mars_daily_TemplateName.append("default").append(TMARSDAILY_EXT);
1854 
1855 	def_mars_ineei_filename = ICS_msg_dir;
1856 	def_mars_ineei_filename.append("default").append(FMARSINEEI_EXT);
1857 	def_mars_ineei_TemplateName = ICS_tmp_dir;
1858 	def_mars_ineei_TemplateName.append("default").append(TMARSINEEI_EXT);
1859 
1860 	def_mars_net_filename = ICS_msg_dir;
1861 	def_mars_net_filename.append("default").append(FMARSNET_EXT);
1862 	def_mars_net_TemplateName = ICS_tmp_dir;
1863 	def_mars_net_TemplateName.append("default").append(TMARSNET_EXT);
1864 
1865 	def_mars_army_filename = ICS_msg_dir;
1866 	def_mars_army_filename.append("default").append(FMARSARMY_EXT);
1867 	def_mars_army_TemplateName = ICS_tmp_dir;
1868 	def_mars_army_TemplateName.append("default").append(TMARSARMY_EXT);
1869 
1870 	def_wxhc_filename = ICS_msg_dir;
1871 	def_wxhc_filename.append("default").append(FWXHC_EXT);
1872 	def_wxhc_TemplateName = ICS_tmp_dir;
1873 	def_wxhc_TemplateName.append("default").append(TWXHC_EXT);
1874 
1875 	def_severe_wx_filename = ICS_msg_dir;
1876 	def_severe_wx_filename.append("default").append(FSWX_EXT);
1877 	def_severe_wx_TemplateName = ICS_tmp_dir;
1878 	def_severe_wx_TemplateName.append("default").append(TSWX_EXT);
1879 
1880 	def_storm_filename = ICS_msg_dir;
1881 	def_storm_filename.append("default").append(FSTRM_EXT);
1882 	def_storm_TemplateName = ICS_tmp_dir;
1883 	def_storm_TemplateName.append("default").append(TSTRM_EXT);
1884 
1885 	{
1886 		if (!cmd_fname.empty()) {
1887 			if (cmd_fname.find(WRAP_EXT) != string::npos)
1888 				wrap_import(cmd_fname.c_str());
1889 			else {
1890 				read_data_file(cmd_fname);
1891 				show_filename(cmd_fname);
1892 			}
1893 			estimate();
1894 		} else
1895 			default_form();
1896 	// Check to see what io mode FLDIGI is in.
1897 		std::string io_mode = get_io_mode();
1898 		int flag = 0;
1899 		if(!io_mode.empty()) {
1900 			flag = strncmp(io_mode.c_str(), "ARQ", 3);
1901 			if(flag != 0) {
1902 				flag = fl_choice2(_("KISS interface active! Switch FLDIGI to ARQ?"),
1903 					_("No"), _("Yes"), NULL);
1904 				if(flag == 1)
1905 					enable_arq();
1906 			}
1907 		}
1908 	}
1909 
1910 #ifdef __APPLE__
1911 	fl_open_callback(open_callback);
1912 #endif
1913 
1914 	init_flmsg_arq();
1915 
1916 }
1917 
1918 static std::string pname = "";
1919 
main(int argc,char * argv[])1920 int main (int argc, char *argv[])
1921 {
1922 	pname = argv[0];
1923 	size_t pn = pname.rfind("/");
1924 	if (pn != std::string::npos) pname.erase(0, pn + 1);
1925 	pn = pname.rfind("\\");
1926 	if (pn != std::string::npos) pname.erase(0, pn + 1);
1927 	XmlRpc::set_pname(pname);
1928 
1929 	bool have_title = false;
1930 	if (argc > 1) {
1931 		if (strcasecmp("--help", argv[1]) == 0) {
1932 			int i = 0;
1933 			while (options[i] != NULL) {
1934 				printf("%s\n", options[i]);
1935 				i++;
1936 			}
1937 			return 0;
1938 		}
1939 		if (strcasecmp("--version", argv[1]) == 0) {
1940 			printf("Version: %s\n", VERSION);
1941 			return 0;
1942 		}
1943 		for (int i = 0; i < argc; i++)
1944 			if (strcasecmp("-ti", argv[i]) == 0) have_title = true;
1945 	}
1946 
1947 	Fl::lock();
1948 
1949 	Fl::scheme("gtk+");
1950 
1951 	int arg_idx;
1952 
1953 	FLMSG_dir.clear();
1954 
1955 	if (Fl::args(argc, argv, arg_idx, parse_args) != argc)
1956 		showoptions();
1957 
1958 	size_t p;
1959 	string appdir = argv[0];;
1960 
1961 #ifdef __WOE32__
1962 	if (FLMSG_dir.empty()) {
1963 		p = appdir.find("FL_APPS\\");
1964 		if (p == string::npos)
1965 			p = appdir.find("FL_APPS/");
1966 		if (p != string::npos) {
1967 			FLMSG_dir.assign(appdir.substr(0, p + 8));
1968 			FLMSG_dir.append("NBEMS.files\\");
1969 		} else {
1970 			char dirbuf[FL_PATH_MAX + 1];
1971 			fl_filename_expand(dirbuf, sizeof(dirbuf) -1, "$USERPROFILE\\");
1972 			FLMSG_dir.assign(dirbuf);
1973 			FLMSG_dir.append("NBEMS.files/\\");
1974 		}
1975 	}
1976 #else
1977 	char dirbuf[FL_PATH_MAX + 1];
1978 	fl_filename_absolute(dirbuf, FL_PATH_MAX, argv[0]);
1979 	appdir.assign(dirbuf);
1980 	p = appdir.rfind("flmsg");
1981 	if (p != string::npos)
1982 		appdir.erase(p);
1983 	p = appdir.find("FL_APPS/");
1984 	if (p == string::npos) p = appdir.find("ARC_MSG/");
1985 	if (p != string::npos) {
1986 		FLMSG_dir.assign(appdir.substr(0, p + 8));
1987 		FLMSG_dir.append("NBEMS.files/");
1988 	} else if (FLMSG_dir.empty()) {
1989 		fl_filename_expand(dirbuf, FL_PATH_MAX, "$HOME/");
1990 		FLMSG_dir = dirbuf;
1991 		FLMSG_dir.append(".nbems/");
1992 	}
1993 #endif
1994 
1995 	progStatus.loadLastState();
1996 
1997 	expert_dialog = flmsg_dialog();
1998 	tyro_dialog = edit_view_dialog();
1999 
2000 	if (!progStatus.UI_default) {
2001 		int answer = fl_choice(
2002 			"FLMSG: Select Default User Interface\n\n\n",
2003 			"Communicator / Expert",
2004 			"Service Agency / Simple",
2005 			NULL );
2006 		progStatus.UI_default = 1;
2007 		progStatus.UI_expert = !answer;
2008 	}
2009 
2010 	if (progStatus.UI_expert)
2011 		mainwindow = expert_dialog;
2012 	else
2013 		mainwindow = tyro_dialog;
2014 
2015 	mainwindow->callback(exit_main);
2016 	set_rg_choices();
2017 	iaru_set_choices();
2018 	set_datetime_widgets();
2019 
2020 #if FLMSG_FLTK_API_MAJOR == 1 && FLMSG_FLTK_API_MINOR == 3
2021 	Fl::add_handler(default_handler);
2022 #endif
2023 
2024 	config_dialog = create_config_dialog();
2025 
2026 	header_window = headers_dialog();
2027 
2028 	btn_utc_format0->value(progStatus.UTC == 0);
2029 	btn_utc_format1->value(progStatus.UTC == 1);
2030 	btn_utc_format2->value(progStatus.UTC == 2);
2031 	btn_utc_format3->value(progStatus.UTC == 3);
2032 	btn_utc_format4->value(progStatus.UTC == 4);
2033 	btn_utc_format5->value(progStatus.UTC == 5);
2034 
2035 	btn_dtformat0->value(progStatus.dtformat == 0);
2036 	btn_dtformat1->value(progStatus.dtformat == 1);
2037 	btn_dtformat2->value(progStatus.dtformat == 2);
2038 	btn_dtformat3->value(progStatus.dtformat == 3);
2039 
2040 	cnt_wpl->value(progStatus.wpl);
2041 
2042 	Fl_File_Icon::load_system_icons();
2043 	FSEL::create();
2044 
2045 	checkdirectories();
2046 
2047 	string logname = FLMSG_log_dir;
2048 	logname.append("flmsg.log");
2049 	rotate_log(logname);
2050 
2051 	load_custom_menu();
2052 
2053 	string debug_file = FLMSG_dir;
2054 	debug_file.append("debug_log_").append(sz_srvr_portnbr).append(".txt");
2055 	debug::start(debug_file.c_str());
2056 
2057 	LOG_INFO("FLMSG_dir        %s", FLMSG_dir.c_str());
2058 	LOG_INFO("ARQ_dir          %s", ARQ_dir.c_str());
2059 	LOG_INFO("ARQ_files_dir    %s", ARQ_files_dir.c_str());
2060 	LOG_INFO("ARQ_recv_dir     %s", ARQ_recv_dir.c_str());
2061 	LOG_INFO("ARQ_send_dir     %s", ARQ_send_dir.c_str());
2062 	LOG_INFO("WRAP_dir         %s", WRAP_dir.c_str());
2063 	LOG_INFO("WRAP_recv_dir    %s", WRAP_recv_dir.c_str());
2064 	LOG_INFO("WRAP_send_dir    %s", WRAP_send_dir.c_str());
2065 //	LOG_INFO("WRAP_auto_dir    %s", WRAP_auto_dir.c_str());
2066 	LOG_INFO("ICS_dir          %s", ICS_dir.c_str());
2067 	LOG_INFO("ICS_msg_dir      %s", ICS_msg_dir.c_str());
2068 	LOG_INFO("ICS_tmp_dir      %s", ICS_tmp_dir.c_str());
2069 	LOG_INFO("CSV_dir          %s", CSV_dir.c_str());
2070 	LOG_INFO("CUSTOM_dir       %s", CUSTOM_dir.c_str());
2071 	LOG_INFO("Transfer dir     %s", XFR_dir.c_str());
2072 	LOG_INFO("FLMSG_temp_dir   %s", FLMSG_temp_dir.c_str());
2073 	LOG_INFO("FLMSG_log_dir    %s", FLMSG_log_dir.c_str());
2074 
2075 	if (!parse_info.empty())
2076 		LOG_INFO("%s", parse_info.c_str());
2077 
2078 	start_web_server();
2079 
2080 	if (!mongoose_msgs.empty())
2081 		LOG_INFO("%s", mongoose_msgs.c_str());
2082 
2083 	if (printme) {
2084 #ifdef __APPLE_
2085 		fl_open_display();
2086 #endif
2087 		print_and_exit();
2088 		if (exit_after_print) {
2089 			if (server) mg_destroy_server(&server);
2090 			return 0;
2091 		}
2092 	}
2093 
2094 	open_xmlrpc();
2095 	xmlrpc_thread = new pthread_t;
2096 	if (pthread_create(xmlrpc_thread, NULL, xmlrpc_loop, NULL)) {
2097 		perror("pthread_create");
2098 		exit(EXIT_FAILURE);
2099 	}
2100 
2101 	expert_dialog->size_range(570, 492);
2102 	expert_dialog->resize(
2103 		progStatus.mainX, progStatus.mainY,
2104 		progStatus.expertW, progStatus.expertH);
2105 
2106 	tyro_dialog->resize( progStatus.mainX, progStatus.mainY, tyro_dialog->w(), tyro_dialog->h());
2107 
2108 #if defined(__WOE32__)
2109 #  ifndef IDI_ICON
2110 #    define IDI_ICON 101
2111 #  endif
2112 	mainwindow->icon((char*)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));
2113 	mainwindow->show (argc, argv);
2114 #elif !defined(__APPLE__)
2115 	make_pixmap(&flmsg_icon_pixmap, flmsg_icon);
2116 	mainwindow->icon((char *)flmsg_icon_pixmap);
2117 	mainwindow->show(argc, argv);
2118 #else
2119 	mainwindow->show(argc, argv);
2120 #endif
2121 
2122 	if (!have_title) {
2123 		string main_label;
2124 		main_label = PACKAGE_NAME;
2125 		main_label.append(": ").append(PACKAGE_VERSION);
2126 		expert_dialog->label(main_label.c_str());
2127 		tyro_dialog->label(main_label.c_str());
2128 	}
2129 
2130 	Fl::add_timeout(0.10, after_start);
2131 
2132 	int result = Fl::run();
2133 
2134 	if (server) mg_destroy_server(&server);
2135 
2136 	return result;
2137 }
2138 
print_and_exit()2139 void print_and_exit()
2140 {
2141 	if (!cmd_fname.empty()) {
2142 		if (cmd_fname.find(WRAP_EXT) != string::npos) {
2143 			wrap_import(cmd_fname.c_str());
2144 		} else {
2145 			read_data_file(cmd_fname);
2146 		}
2147 
2148 		switch (selected_form) {
2149 		case ICS203 :
2150 			cb_203_save();
2151 			cb_203_html();
2152 			break;
2153 		case ICS205 :
2154 			cb_205_save();
2155 			cb_205_html();
2156 			break;
2157 		case ICS205A :
2158 			cb_205a_save();
2159 			cb_205a_html();
2160 			break;
2161 		case ICS206 :
2162 			cb_206_save();
2163 			cb_206_html();
2164 			break;
2165 		case ICS213 :
2166 			cb_213_save();
2167 			cb_213_html();
2168 			break;
2169 		case ICS214 :
2170 			cb_214_save();
2171 			cb_214_html();
2172 			break;
2173 		case ICS216 :
2174 			cb_216_save();
2175 			cb_216_html();
2176 			break;
2177 		case ICS309 :
2178 			cb_309_save();
2179 			cb_309_html();
2180 			break;
2181 		case NETLOG :
2182 			cb_netlog_save();
2183 			cb_netlog_html();
2184 			break;
2185 		case HICS203 :
2186 			cb_hics203_save();
2187 			cb_hics203_html();
2188 			break;
2189 		case HICS206 :
2190 			h206_cb_save();
2191 			h206_cb_html();
2192 			break;
2193 		case HICS213 :
2194 			h213_cb_save();
2195 			h213_cb_html();
2196 			break;
2197 		case HICS214 :
2198 			hics214_cb_save();
2199 			hics214_cb_html();
2200 			break;
2201 		case RADIOGRAM :
2202 			cb_rg_save();
2203 			cb_rg_html();
2204 			break;
2205 		case PLAINTEXT :
2206 			cb_pt_save();
2207 			cb_pt_html();
2208 			break;
2209 		case BLANK :
2210 			cb_blank_save();
2211 			cb_blank_html();
2212 			break;
2213 		case CSV :
2214 			cb_csv_save();
2215 			cb_csv_html();
2216 			break;
2217 		case CUSTOM :
2218 			cb_custom_save();
2219 			cb_custom_html(true);
2220 			break;
2221 		case MARSDAILY :
2222 			cb_mars_daily_save();
2223 			cb_mars_daily_html();
2224 			break;
2225 		case MARSINEEI :
2226 			cb_mars_ineei_save();
2227 			cb_mars_ineei_html();
2228 			break;
2229 		case MARSNET :
2230 			cb_mars_net_save();
2231 			cb_mars_net_html();
2232 			break;
2233 		case MARSARMY :
2234 			cb_mars_army_save();
2235 			cb_mars_army_html();
2236 			break;
2237 		case WXHC :
2238 			cb_wxhc_save();
2239 			cb_wxhc_html();
2240 			break;
2241 		case SEVEREWX :
2242 			cb_severe_wx_save();
2243 			cb_severe_wx_html();
2244 			break;
2245 		case STORMREP :
2246 			cb_storm_save();
2247 			cb_storm_html();
2248 			break;
2249 		}
2250 	}
2251 }
2252 
drop_box_changed()2253 void drop_box_changed()
2254 {
2255 	string 	buffer = drop_box->value();
2256 	size_t n;
2257 	drop_box->value("");
2258 	drop_box->redraw();
2259 	if ((n = buffer.find("file:///")) != string::npos)
2260 		buffer.erase(0, n + 7);
2261 	if ((buffer.find(":\\")) != string::npos || (buffer.find("/") == 0)) {
2262 		while ((n = buffer.find('\n')) != string::npos)
2263 			buffer.erase(n, 1);
2264 		while ((n = buffer.find('\r')) != string::npos)
2265 			buffer.erase(n, 1);
2266 		if (buffer.find(WRAP_EXT) != string::npos)
2267 			wrap_import(buffer.c_str());
2268 		else
2269 			read_data_file(buffer.c_str());
2270 	} else // try to extract as a text buffer
2271 		extract_text(buffer, NULL);
2272 	estimate();
2273 }
2274 
drop_file_changed()2275 void drop_file_changed()
2276 {
2277 	string 	buffer = drop_file->value();
2278 	size_t n;
2279 	drop_file->value("");
2280 	drop_file->redraw();
2281 	if ((n = buffer.find("file:///")) != string::npos)
2282 		buffer.erase(0, n + 7);
2283 	if ((buffer.find(":\\")) != string::npos || (buffer.find("/") == 0)) {
2284 		while ((n = buffer.find('\n')) != string::npos)
2285 			buffer.erase(n, 1);
2286 		while ((n = buffer.find('\r')) != string::npos)
2287 			buffer.erase(n, 1);
2288 		if (buffer.find(WRAP_EXT) != string::npos)
2289 			wrap_import(buffer.c_str());
2290 		else
2291 			read_data_file(buffer.c_str());
2292 	} else // try to extract as a text buffer
2293 		extract_text(buffer, NULL);
2294 	estimate();
2295 }
2296 
checkdirectories(void)2297 void checkdirectories(void)
2298 {
2299 	struct DIRS {
2300 		string& dir;
2301 		const char* suffix;
2302 		void (*new_dir_func)(void);
2303 	};
2304 #ifdef __WIN32__
2305 	DIRS FLMSG_dirs[] = {
2306 		{ FLMSG_dir,      0, 0 },
2307 		{ ARQ_dir,        "ARQ", 0 },
2308 		{ ARQ_files_dir,  "ARQ\\files", 0 },
2309 		{ ARQ_recv_dir,   "ARQ\\recv", 0 },
2310 		{ ARQ_send_dir,   "ARQ\\send", 0 },
2311 		{ WRAP_dir,       "WRAP", 0 },
2312 		{ WRAP_recv_dir,  "WRAP\\recv", 0 },
2313 		{ WRAP_send_dir,  "WRAP\\send", 0 },
2314 		{ ICS_dir,        "ICS", 0 },
2315 		{ ICS_msg_dir,    "ICS\\messages", 0 },
2316 		{ ICS_tmp_dir,    "ICS\\templates", 0 },
2317 		{ CSV_dir,        "CSV", 0},
2318 		{ CUSTOM_dir,     "CUSTOM", 0},
2319 		{ XFR_dir,        "TRANSFERS", 0},
2320 		{ FLMSG_temp_dir, "temp_files", 0 },
2321 		{ FLMSG_log_dir,  "log_files", 0 }
2322 	};
2323 #else
2324 	DIRS FLMSG_dirs[] = {
2325 		{ FLMSG_dir,      0, 0 },
2326 		{ ARQ_dir,        "ARQ", 0 },
2327 		{ ARQ_files_dir,  "ARQ/files", 0 },
2328 		{ ARQ_recv_dir,   "ARQ/recv", 0 },
2329 		{ ARQ_send_dir,   "ARQ/send", 0 },
2330 		{ WRAP_dir,       "WRAP", 0 },
2331 		{ WRAP_recv_dir,  "WRAP/recv", 0 },
2332 		{ WRAP_send_dir,  "WRAP/send", 0 },
2333 		{ ICS_dir,        "ICS", 0 },
2334 		{ ICS_msg_dir,    "ICS/messages", 0 },
2335 		{ ICS_tmp_dir,    "ICS/templates", 0 },
2336 		{ CSV_dir,        "CSV", 0},
2337 		{ CUSTOM_dir,     "CUSTOM", 0},
2338 		{ XFR_dir,        "TRANSFERS", 0},
2339 		{ FLMSG_temp_dir, "temp_files", 0 },
2340 		{ FLMSG_log_dir,  "log_files", 0 }
2341 	};
2342 #endif
2343 	int r;
2344 
2345 	for (size_t i = 0; i < sizeof(FLMSG_dirs)/sizeof(*FLMSG_dirs); i++) {
2346 		if (FLMSG_dirs[i].dir.empty() && FLMSG_dirs[i].suffix)
2347 			FLMSG_dirs[i].dir.assign(FLMSG_dir).append(FLMSG_dirs[i].suffix).append(PATH_SEP);
2348 
2349 		if ((r = mkdir(FLMSG_dirs[i].dir.c_str(), 0777)) == -1 && errno != EEXIST) {
2350 			cerr << _("Could not make directory") << ' ' << FLMSG_dirs[i].dir
2351 			     << ": " << strerror(errno) << '\n';
2352 			exit(EXIT_FAILURE);
2353 		}
2354 		else if (r == 0 && FLMSG_dirs[i].new_dir_func)
2355 			FLMSG_dirs[i].new_dir_func();
2356 	}
2357 
2358 	if (FLMSG_dir.find("FL_APPS") != std::string::npos) {
2359 		ICS_dir = FLMSG_dir;
2360 #if __WIN32__
2361 		ICS_dir.append("..\\..\\");
2362 #else
2363 		ICS_dir.append("../../");
2364 #endif
2365 		ICS_msg_dir.clear();
2366 		ICS_tmp_dir.clear();
2367 		CUSTOM_dir.clear();
2368 		DIRS MSG_dirs[] = {
2369 			{ ICS_msg_dir, "flmsg.messages", 0},
2370 			{ ICS_tmp_dir, "flmsg.templates", 0},
2371 			{ CUSTOM_dir,  "flmsg.forms", 0},
2372 		};
2373 		for (size_t i = 0; i < sizeof(MSG_dirs) / sizeof(*MSG_dirs); i++) {
2374 			if (MSG_dirs[i].dir.empty() && MSG_dirs[i].suffix)
2375 				MSG_dirs[i].dir.assign(ICS_dir).append(MSG_dirs[i].suffix).append(PATH_SEP);
2376 
2377 			r = mkdir(MSG_dirs[i].dir.c_str(), 0777);
2378 			if (r == -1 && errno != EEXIST) {
2379 				cerr << _("Could not make directory") << ' ' << MSG_dirs[i].dir
2380 					<< ": " << strerror(errno) << '\n';
2381 				exit(EXIT_FAILURE);
2382 			}
2383 			else if (r == 0 && MSG_dirs[i].new_dir_func)
2384 				MSG_dirs[i].new_dir_func();
2385 		}
2386 	}
2387 
2388 }
2389 
showoptions()2390 void showoptions()
2391 {
2392 	if (!optionswindow) {
2393 		optionswindow = optionsdialog();
2394 		for (int i = 0; options[i] != 0; i++)
2395 			brwsOptions->add(options[i]);
2396 	}
2397 	optionswindow->show();
2398 }
2399 
closeoptions()2400 void closeoptions()
2401 {
2402 	optionswindow->hide();
2403 }
2404 //extern Fl_Group	*tab_headers;
2405 
set_config_values()2406 void set_config_values()
2407 {
2408 	btn_dtformat0->value(progStatus.dtformat == 0);
2409 	btn_dtformat1->value(progStatus.dtformat == 1);
2410 	btn_dtformat2->value(progStatus.dtformat == 2);
2411 
2412 	btn_utc_format0->value(progStatus.UTC == 0);
2413 	btn_utc_format1->value(progStatus.UTC == 1);
2414 	btn_utc_format2->value(progStatus.UTC == 2);
2415 	btn_utc_format3->value(progStatus.UTC == 3);
2416 	btn_utc_format4->value(progStatus.UTC == 4);
2417 	btn_utc_format5->value(progStatus.UTC == 5);
2418 
2419 	txt_my_call->value(progStatus.my_call.c_str());
2420 	txt_my_name->value(progStatus.my_name.c_str());
2421 	txt_my_addr->value(progStatus.my_addr.c_str());
2422 	txt_my_city->value(progStatus.my_city.c_str());
2423 	txt_my_tel->value(progStatus.my_tel.c_str());
2424 
2425 	cnt_wpl->value(progStatus.wpl);
2426 
2427 	txt_rgnbr->value(progStatus.rgnbr.c_str());
2428 	btn_rgnbr_fname->value(progStatus.rgnbr_fname);
2429 
2430 	btn_open_on_export->value(progStatus.open_on_export);
2431 	btn_use_compression->value(progStatus.use_compression);
2432 	txt_sernbr->value(progStatus.sernbr.c_str());
2433 	btn_sernbr_fname->value(progStatus.sernbr_fname);
2434 	btn_call_fname->value(progStatus.call_fname);
2435 	cbo_dt_fname->index(progStatus.dt_fname);
2436 
2437 	txt_mars_roster_file->value(progStatus.mars_roster_file.c_str());
2438 
2439 	txt_socket_addr->value(progStatus.xmlrpc_addr.c_str());
2440 	txt_socket_port->value(progStatus.xmlrpc_port.c_str());
2441 
2442 }
2443 
cb_config_date_time()2444 void cb_config_date_time()
2445 {
2446 	set_config_values();
2447 	tabs_config->value(tab_date_time);
2448 	config_dialog->show();
2449 }
2450 
cb_config_personal()2451 void cb_config_personal()
2452 {
2453 	set_config_values();
2454 	tabs_config->value(tab_personal);
2455 	config_dialog->show();
2456 }
2457 
cb_config_radiogram()2458 void cb_config_radiogram()
2459 {
2460 	set_config_values();
2461 	tabs_config->value(tab_config_radiogram);
2462 	config_dialog->show();
2463 }
2464 
cb_config_files()2465 void cb_config_files()
2466 {
2467 	set_config_values();
2468 	tabs_config->value(tab_files);
2469 	config_dialog->show();
2470 }
2471 
2472 //void cb_config_socket()
2473 //{
2474 //	set_config_values();
2475 //	tabs_config->value(tab_socket);
2476 //	config_dialog->show();
2477 //}
2478 
cb_config_arq()2479 void cb_config_arq()
2480 {
2481 	set_config_values();
2482 	tabs_config->value(tab_arq);
2483 	config_dialog->show();
2484 }
2485 
cb_config_UI()2486 void cb_config_UI()
2487 {
2488 	set_config_values();
2489 	tabs_config->value(tab_UI);
2490 	config_dialog->show();
2491 }
2492 
show_help()2493 void show_help()
2494 {
2495 	open_url("http://www.w1hkj.com/flmsg-help/index.html");
2496 }
2497 
custom_download()2498 void custom_download()
2499 {
2500 	open_url("https://sourceforge.net/projects/fldigi/files/flmsg/");
2501 }
2502 
parse_args(int argc,char ** argv,int & idx)2503 int parse_args(int argc, char **argv, int& idx)
2504 {
2505 	if (strstr(argv[idx], "--p")) {
2506 		printme = true;
2507 		exit_after_print = true;
2508 		idx++;
2509 		parse_info.append("parsed --p\n");
2510 		return 1;
2511 	}
2512 
2513 	if (strstr(argv[idx], "--b")) {
2514 		printme = true;
2515 		idx++;
2516 		parse_info.append("parsed --b\n");
2517 		return 1;
2518 	}
2519 
2520 	if (strstr(argv[idx], "--flmsg-dir")) {
2521 		idx++;
2522 		string tmp = argv[idx];
2523 		if (!tmp.empty()) FLMSG_dir_default = tmp;
2524 		size_t p = string::npos;
2525 		while ( (p = FLMSG_dir_default.find("\\")) != string::npos)
2526 			FLMSG_dir_default[p] = '/';
2527 		if (FLMSG_dir_default[FLMSG_dir_default.length() - 1] != '/')
2528 			FLMSG_dir_default += '/';
2529 		FLMSG_dir = FLMSG_dir_default;
2530 		parse_info.append("parsed --flmsg-dir ");
2531 		parse_info.append(FLMSG_dir).append("\n");
2532 		idx++;
2533 		return 2;
2534 	}
2535 
2536 	if (strstr(argv[idx], "--server-port")) {
2537 		idx++;
2538 		int port = 0;
2539 		if (sscanf(argv[idx], "%d", &port) == 1)
2540 			srvr_portnbr = port;
2541 		idx++;
2542 		return 2;
2543 	}
2544 /*
2545 	if (strstr(argv[idx], "--auto-dir")) {
2546 		idx++;
2547 		string tmp = argv[idx];
2548 		if (!tmp.empty()) WRAP_auto_dir = tmp;
2549 		size_t p = string::npos;
2550 		while ( (p = WRAP_auto_dir.find("\\")) != string::npos)
2551 			WRAP_auto_dir[p] = '/';
2552 		parse_info.append("parsed --autodir ");
2553 		parse_info.append(WRAP_auto_dir).append("\n");
2554 		idx++;
2555 		return 2;
2556 	}
2557 */
2558 
2559 	if ( argv[idx][0] == '-' ) {
2560 		return 0;
2561 	}
2562 
2563 	parse_info.append("parsed filename: ").append(argv[idx]).append("\n");
2564 
2565 	string fname = argv[idx];
2566 	if (fname.find(DATAFILE_EXT) != string::npos ||
2567 		fname.find(DATATEMP_EXT) != string::npos ||
2568 
2569 		fname.find(F203_EXT) != string::npos ||
2570 		fname.find(T203_EXT) != string::npos ||
2571 
2572 		fname.find(F205_EXT) != string::npos ||
2573 		fname.find(T205_EXT) != string::npos ||
2574 
2575 		fname.find(F205A_EXT) != string::npos ||
2576 		fname.find(T205A_EXT) != string::npos ||
2577 
2578 		fname.find(F206_EXT) != string::npos ||
2579 		fname.find(T206_EXT) != string::npos ||
2580 
2581 		fname.find(F213_EXT) != string::npos ||
2582 		fname.find(T213_EXT) != string::npos ||
2583 
2584 		fname.find(F214_EXT) != string::npos ||
2585 		fname.find(T214_EXT) != string::npos ||
2586 
2587 		fname.find(F216_EXT) != string::npos ||
2588 		fname.find(T216_EXT) != string::npos ||
2589 
2590 		fname.find(F309_EXT) != string::npos ||
2591 		fname.find(T309_EXT) != string::npos ||
2592 
2593 		fname.find(FNET_EXT) != string::npos ||
2594 		fname.find(TNET_EXT) != string::npos ||
2595 
2596 		fname.find(HF203_EXT) != string::npos ||
2597 		fname.find(HT203_EXT) != string::npos ||
2598 
2599 		fname.find(HF206_EXT) != string::npos ||
2600 		fname.find(HT206_EXT) != string::npos ||
2601 
2602 		fname.find(HF213_EXT) != string::npos ||
2603 		fname.find(HT213_EXT) != string::npos ||
2604 
2605 		fname.find(HF214_EXT) != string::npos ||
2606 		fname.find(HT214_EXT) != string::npos ||
2607 
2608 		fname.find(RGFILE_EXT) != string::npos ||
2609 		fname.find(RGTEMP_EXT) != string::npos ||
2610 
2611 		fname.find(PTFILE_EXT) != string::npos ||
2612 		fname.find(PTTEMP_EXT) != string::npos ||
2613 
2614 		fname.find(BLANKFILE_EXT) != string::npos ||
2615 		fname.find(BLANKTEMP_EXT) != string::npos ||
2616 
2617 		fname.find(CSVFILE_EXT) != string::npos ||
2618 		fname.find(CSVTEMP_EXT) != string::npos ||
2619 
2620 		fname.find(CUSTOMFILE_EXT) != string::npos ||
2621 		fname.find(CUSTOMTEMP_EXT) != string::npos ||
2622 
2623 		fname.find(FMARSDAILY_EXT) != string::npos ||
2624 		fname.find(TMARSDAILY_EXT) != string::npos ||
2625 
2626 		fname.find(FMARSINEEI_EXT) != string::npos ||
2627 		fname.find(TMARSINEEI_EXT) != string::npos ||
2628 
2629 		fname.find(FMARSNET_EXT) != string::npos ||
2630 		fname.find(TMARSNET_EXT) != string::npos ||
2631 
2632 		fname.find(FMARSARMY_EXT) != string::npos ||
2633 		fname.find(TMARSARMY_EXT) != string::npos ||
2634 
2635 		fname.find(FWXHC_EXT) != string::npos ||
2636 		fname.find(TWXHC_EXT) != string::npos ||
2637 
2638 		fname.find(FSWX_EXT) != string::npos ||
2639 		fname.find(TSWX_EXT) != string::npos ||
2640 
2641 		fname.find(IARU_FILE_EXT) != string::npos ||
2642 		fname.find(IARU_TEMP_EXT) != string::npos ||
2643 
2644 		fname.find(CAP105_FILE_EXT) != string::npos ||
2645 		fname.find(CAP105_TEMP_EXT) != string::npos ||
2646 
2647 		fname.find(CAP110_FILE_EXT) != string::npos ||
2648 		fname.find(CAP110_TEMP_EXT) != string::npos ||
2649 
2650 		fname.find(TRANSFER_EXT) != string::npos ||
2651 
2652 		fname.find(WRAP_EXT) != string::npos ) {
2653 		cmd_fname = fname;
2654 	}
2655 	idx++;
2656 	return 1;
2657 }
2658 
open_url(const char * url,int folder)2659 void open_url(const char* url, int folder)
2660 {
2661 //LOG_INFO("%s", url);
2662 #ifndef __WOE32__
2663 
2664 	const char *folders[] = {
2665 #  ifdef __APPLE__
2666 		"open"                    // OS X
2667 #  else
2668 		"fl-xdg-open",            // Puppy Linux
2669 		"xdg-open"                // all other Linux/Unix
2670 #endif
2671 	};
2672 
2673 	const char* browsers[] = {
2674 #  ifdef __APPLE__
2675 		getenv("FLMSG_BROWSER"),  // valid for any OS - set by user
2676 		getenv("BROWSER"),        // valid for any OS - set by user
2677 		"open"                    // OS X
2678 #  else
2679 		"fl-xdg-open",            // Puppy Linux
2680 		getenv("FLMSG_BROWSER"),  // force use of spec'd browser
2681 		getenv("BROWSER"),        // most Linux distributions
2682 		"chromium-browser",       // preferred browser for HTML-5
2683 		"firefox",                // nice, but incomplete HTML-5
2684 		"mozilla",                // nice, but incomplete HTML-5
2685 		"xdg-open",               // let OS determine browser
2686 		"sensible-browser"        // must be something out there!
2687 
2688 #  endif
2689 	};
2690 	switch (fork()) {
2691 	case 0:
2692 #  ifndef NDEBUG
2693 		unsetenv("MALLOC_CHECK_");
2694 		unsetenv("MALLOC_PERTURB_");
2695 #  endif
2696 
2697 		if (folder) {
2698 			for (size_t i = 0; i < sizeof(folders)/sizeof(folders[0]); i++) {
2699 				if (folders[i])
2700 					execlp(folders[i], folders[i], url, (char*)0);
2701 			}
2702 		} else {
2703 			for (size_t i = 0; i < sizeof(browsers)/sizeof(browsers[0]); i++) {
2704 				if (browsers[i])
2705 					execlp(browsers[i], browsers[i], url, (char*)0);
2706 			}
2707 		}
2708 		exit(EXIT_FAILURE);
2709 
2710 	case -1:
2711 		fl_alert2(_("Could not run a web browser:\n%s\n\n"
2712 			 "Open this URL manually:\n%s"),
2713 			 strerror(errno), url);
2714 	}
2715 #else
2716 	if ((int)ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL) <= 32)
2717 		fl_alert2(_("Could not open url:\n%s\n"), url);
2718 #endif
2719 }
2720 
2721 //------------------------------------------------------------------------------
2722 // mongoose server support
2723 //------------------------------------------------------------------------------
2724 bool exit_server = false;
2725 pthread_t *web_server_thread = 0;
2726 pthread_mutex_t mutex_web_server = PTHREAD_MUTEX_INITIALIZER;
2727 
2728 int handle_type = HANDLE_WAITING;
2729 
2730 static const char *html_waiting =
2731   "<html><body>\n\
2732 	Custom form not posted<br>\n\
2733 	</html>";
2734 
2735 //void load_custom(void *)
2736 //{
2737 //	load_custom_menu();
2738 //}
2739 
poll_server(void * d)2740 void * poll_server(void *d)
2741 {
2742 //	int n = 10;
2743 	exit_server = false;
2744 
2745 	while(!exit_server) {
2746 		pthread_mutex_lock(&mutex_web_server);
2747 			mg_poll_server(server, 200);
2748 		pthread_mutex_unlock(&mutex_web_server);
2749 //		n--;
2750 //		if (!n) {
2751 //			if (!progStatus.UI_expert) //flmsg_editor)
2752 //				Fl::awake(load_custom, 0);
2753 //			n = 30;
2754 //		}
2755 		MilliSleep(10);
2756 	}
2757 	return NULL;
2758 }
2759 
close_server()2760 void close_server()
2761 {
2762 	pthread_mutex_lock(&mutex_web_server);
2763 	exit_server = true;
2764 	pthread_mutex_unlock(&mutex_web_server);
2765 	MilliSleep(200);
2766 }
2767 
update_form(void *)2768 void update_form(void *)
2769 {
2770 	cb_custom_save_as();
2771 	update_custom = false;
2772 }
2773 
2774 extern void get_html_vars(struct mg_connection *conn);
web_handler(struct mg_connection * conn)2775 static int web_handler(struct mg_connection *conn)
2776 {
2777 	if (strcmp(conn->uri, "/handle_post_request") == 0) {
2778 		get_html_vars(conn);
2779 		custom_viewer(conn);
2780 		if (update_custom) Fl::awake(update_form);
2781 	} else {
2782 		if (handle_type == HANDLE_EDIT) {
2783 			custom_editor(conn);
2784 		}
2785 		else if (handle_type == HANDLE_VIEW) {
2786 			custom_viewer(conn);
2787 		}
2788 		else if (handle_type == HANDLE_WAITING)
2789 // Show HTML waiting
2790 			mg_send_data(conn, html_waiting, strlen(html_waiting));
2791 	}
2792 	handle_type = HANDLE_NONE;
2793 
2794 	return MG_REQUEST_PROCESSED;
2795 }
2796 
2797 extern char *mg_open_msg;
start_web_server()2798 int start_web_server()
2799 {
2800 	if ((server = mg_create_server(NULL)) == NULL) {
2801 		fl_alert2("%s", "Failed to start web server");
2802 		exit(EXIT_FAILURE);
2803 		return 0;
2804 	}
2805 
2806 	mongoose_msgs.clear();
2807 	char retmsg[500];
2808 	int ret = mg_set_option(server, "document_root", CUSTOM_dir.c_str(), retmsg);
2809 
2810 	if (ret) {
2811 		fl_alert2("%s", "Failed to set file server root directory");
2812 		exit(EXIT_FAILURE);
2813 		return 0;
2814 	}
2815 
2816 	int last_portnbr = srvr_portnbr + 100;
2817 	int test_portnbr = srvr_portnbr;
2818 	while (test_portnbr < last_portnbr) {
2819 		snprintf(sz_srvr_portnbr, sizeof(sz_srvr_portnbr),
2820 				"%d", test_portnbr);
2821 		ret = mg_set_option(server, "listening_port", sz_srvr_portnbr, retmsg);
2822 
2823 		if (ret == 0) break;
2824 		mongoose_msgs.append(retmsg).append(" ")
2825 					 .append(sz_srvr_portnbr);
2826 
2827 		test_portnbr++;
2828 		Fl::awake();
2829 	}
2830 	if (test_portnbr == last_portnbr) {
2831 		LOG_ERROR("%s", mongoose_msgs.c_str());
2832 		fl_alert2(
2833 "Web server port bind failed.\n\
2834 Range %d - %d", srvr_portnbr, last_portnbr - 1);
2835 		exit(EXIT_FAILURE);
2836 		return 0;
2837 	}
2838 	else {
2839 		if (!mongoose_msgs.empty()) mongoose_msgs.append("\n");
2840 		mongoose_msgs.append("Listening on port ").
2841 					  append(sz_srvr_portnbr);
2842 	}
2843 
2844 	mg_set_request_handler(server, web_handler);
2845 
2846 	web_server_thread = new pthread_t;
2847 	if (pthread_create(web_server_thread, NULL, poll_server, NULL)) {
2848 		perror("pthread_create");
2849 		exit(EXIT_FAILURE);
2850 	}
2851 
2852     return 1;
2853 }
2854 
rotate_log(std::string filename)2855 void rotate_log(std::string filename)
2856 {
2857 	const int n = 5; // rename existing log files to keep up to 5 old versions
2858 	ostringstream oldfn, newfn;
2859 	size_t p;
2860 
2861 	oldfn << filename << '.';
2862 	newfn << filename << '.';
2863 	p = oldfn.tellp();
2864 
2865 	for (int i = n - 1; i > 0; i--) {
2866 		oldfn.seekp(p);
2867 		newfn.seekp(p);
2868 		oldfn << i;
2869 		newfn << i + 1;
2870 		rename(oldfn.str().c_str(), newfn.str().c_str());
2871 	}
2872 	rename(filename.c_str(), oldfn.str().c_str());
2873 }
2874 
2875 
2876