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 <iostream>
23 #include <fstream>
24 #include <cstring>
25 #include <ctime>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdio.h>
29 #include <errno.h>
30 
31 #include <FL/Fl.H>
32 #include <FL/Enumerations.H>
33 #include <FL/Fl_Window.H>
34 #include <FL/Fl_Button.H>
35 #include <FL/Fl_Group.H>
36 #include <FL/Fl_Sys_Menu_Bar.H>
37 #include <FL/x.H>
38 #include <FL/Fl_Help_Dialog.H>
39 #include <FL/Fl_Menu_Item.H>
40 #include <FL/Fl_File_Icon.H>
41 
42 #include "config.h"
43 #include "flmsg_config.h"
44 
45 #include "flmsg.h"
46 #include "templates.h"
47 #include "debug.h"
48 #include "util.h"
49 #include "gettext.h"
50 #include "flmsg_dialog.h"
51 #include "flinput2.h"
52 #include "date.h"
53 #include "calendar.h"
54 #include "icons.h"
55 #include "fileselect.h"
56 #include "wrap.h"
57 #include "status.h"
58 #include "parse_xml.h"
59 #include "flmsg_strings.h"
60 
61 #ifdef WIN32
62 #  include "flmsgrc.h"
63 #  include "compat.h"
64 #  define dirent fl_dirent_no_thanks
65 #endif
66 
67 #include <FL/filename.H>
68 #include "dirent-check.h"
69 
70 #include <FL/x.H>
71 #include <FL/Fl_Pixmap.H>
72 #include <FL/Fl_Image.H>
73 
74 using namespace std;
75 
76 // ---------------------------------------------------------------------
77 // ics 110 field variables and template variables
78 // ---------------------------------------------------------------------
79 
80 string cap110_mission_nbr			= ":mnbr:";
81 string cap110_station				= ":sta:";
82 string cap110_date					= ":date:";
83 string cap110_ds_a					= ":ds_a:";
84 string cap110_ds_b					= ":ds_b:";
85 string cap110_ds_c					= ":ds_c:";
86 string cap110_ds_d					= ":ds_d:";
87 string cap110_ds_e					= ":ds_e:";
88 string cap110_ds_f					= ":ds_f:";
89 
90 string cap110_comm_time				= ":time[n]:";	// 23
91 string cap110_comm_chref			= ":chref[n]:";	// 23
92 string cap110_comm_call				= ":call[n]:";	// 23
93 string cap110_comm_rem				= ":rem[n]:";	// 23
94 
95 string s110_mission_nbr;
96 string s110_station;
97 string s110_date;
98 string s110_ds_a;
99 string s110_ds_b;
100 string s110_ds_c;
101 string s110_ds_d;
102 string s110_ds_e;
103 string s110_ds_f;
104 
105 string s110_comm_time[23];
106 string s110_comm_call[23];
107 string s110_comm_chref[23];
108 string s110_comm_rem[23];
109 
110 // =====================================================================
111 
112 string	buff_c110;
113 string	cap110_def_filename= "";
114 string	cap110_base_filename = "";
115 string	cap110_def_template_name = "";
116 bool	using_cap110_template = false;
117 
cap110_set_date()118 void cap110_set_date()
119 {
120 	string date = szCAPDateTime();
121 	date.erase(2,6);
122 	txt_110_date->value(date.c_str());
123 }
124 
clear_110fields()125 void clear_110fields()
126 {
127 	s110_mission_nbr.clear();
128 	s110_station.clear();
129 	s110_date.clear();
130 	s110_ds_a.clear();
131 	s110_ds_b.clear();
132 	s110_ds_c.clear();
133 	s110_ds_d.clear();
134 	s110_ds_e.clear();
135 	s110_ds_f.clear();
136 
137 	for (int i = 0; i < 23; i++) {
138 		s110_comm_time[i].clear();
139 		s110_comm_call[i].clear();
140 		s110_comm_chref[i].clear();
141 		s110_comm_rem[i].clear();
142 	}
143 }
144 
check_110fields()145 bool check_110fields()
146 {
147 	if (s110_mission_nbr != txt_110_mission_nbr->value())
148 		return true;
149 	if (s110_station != txt_110_station->value())
150 		return true;
151 	if (s110_date != txt_110_date->value())
152 		return true;
153 	if (s110_ds_a != txt_110_ds_a->value())
154 		return true;
155 	if (s110_ds_b != txt_110_ds_b->value())
156 		return true;
157 	if (s110_ds_c != txt_110_ds_c->value())
158 		return true;
159 	if (s110_ds_d != txt_110_ds_d->value())
160 		return true;
161 	if (s110_ds_e != txt_110_ds_e->value())
162 		return true;
163 	if (s110_ds_f != txt_110_ds_f->value())
164 		return true;
165 	for (int i = 0; i < 23; i++) {
166 		if (s110_comm_time[i] != txt_110_comm_time[i]->value())
167 			return true;
168 		if (s110_comm_call[i] != txt_110_comm_call[i]->value())
169 			return true;
170 		if (s110_comm_chref[i] != txt_110_comm_chref[i]->value())
171 			return true;
172 		if (s110_comm_rem[i] != txt_110_comm_rem[i]->value())
173 			return true;
174 	}
175 	return false;
176 }
177 
update_110fields()178 void update_110fields()
179 {
180 	s110_mission_nbr = txt_110_mission_nbr->value();
181 	s110_station = txt_110_station->value();
182 	s110_date = txt_110_date->value();
183 	s110_ds_a = txt_110_ds_a->value();
184 	s110_ds_b = txt_110_ds_b->value();
185 	s110_ds_c = txt_110_ds_c->value();
186 	s110_ds_d = txt_110_ds_d->value();
187 	s110_ds_e = txt_110_ds_e->value();
188 	s110_ds_f = txt_110_ds_f->value();
189 	for (int i = 0; i < 23; i++) {
190 		s110_comm_time[i] = txt_110_comm_time[i]->value();
191 		s110_comm_call[i] = txt_110_comm_call[i]->value();
192 		s110_comm_chref[i] = txt_110_comm_chref[i]->value();
193 		s110_comm_rem[i] = txt_110_comm_rem[i]->value();
194 	}
195 }
196 
update_110form()197 void update_110form()
198 {
199 	txt_110_mission_nbr->value(s110_mission_nbr.c_str());
200 	txt_110_station->value(s110_station.c_str());
201 	txt_110_date->value(s110_date.c_str());
202 	txt_110_ds_a->value(s110_ds_a.c_str());
203 	txt_110_ds_b->value(s110_ds_b.c_str());
204 	txt_110_ds_c->value(s110_ds_c.c_str());
205 	txt_110_ds_d->value(s110_ds_d.c_str());
206 	txt_110_ds_e->value(s110_ds_e.c_str());
207 	txt_110_ds_f->value(s110_ds_f.c_str());
208 
209 	for (int i = 0; i < 23; i++) {
210 		txt_110_comm_time[i]->value(s110_comm_time[i].c_str());
211 		txt_110_comm_call[i]->value(s110_comm_call[i].c_str());
212 		txt_110_comm_chref[i]->value(s110_comm_chref[i].c_str());
213 		txt_110_comm_rem[i]->value(s110_comm_rem[i].c_str());
214 	}
215 }
216 
clear_110_form()217 void clear_110_form()
218 {
219 	clear_110fields();
220 	update_110form();
221 }
222 
cap110_nn(string & subst,int n)223 string &cap110_nn(string & subst, int n)
224 {
225 	static string garbage = "#$^*!";
226 	static string ics;
227 	ics.clear();
228 	ics = subst;
229 	size_t pos = ics.find("[");
230 	if (pos == string::npos) return garbage;
231 	pos++;
232 	if (n < 10)
233 		ics[pos] = '0' + n;
234 	else {
235 		ics[pos] = n > 19 ? '2' : '1';
236 		ics[pos+1] = '0' + n % 10;
237 		ics[pos+2] = ']';
238 		ics += ':';
239 	}
240 	return ics;
241 }
242 
make_buff_c110(bool compress=false)243 void make_buff_c110(bool compress = false)
244 {
245 	string mbuff;
246 	mbuff.clear();
247 	mbuff.append( lineout( cap110_mission_nbr, s110_mission_nbr ) );
248 	mbuff.append( lineout( cap110_station, s110_station ) );
249 	mbuff.append( lineout( cap110_date, s110_date ) );
250 	mbuff.append( lineout( cap110_ds_a, s110_ds_a ) );
251 	mbuff.append( lineout( cap110_ds_b, s110_ds_b ) );
252 	mbuff.append( lineout( cap110_ds_c, s110_ds_c ) );
253 	mbuff.append( lineout( cap110_ds_d, s110_ds_d ) );
254 	mbuff.append( lineout( cap110_ds_e, s110_ds_e ) );
255 	mbuff.append( lineout( cap110_ds_f, s110_ds_f ) );
256 
257 	for (int i = 0; i < 23; i++) {
258 		mbuff.append( lineout( cap110_nn( cap110_comm_time, i ), s110_comm_time[i] ) );
259 		mbuff.append( lineout( cap110_nn( cap110_comm_call, i ),     s110_comm_call[i] ) );
260 		mbuff.append( lineout( cap110_nn( cap110_comm_chref, i ),     s110_comm_chref[i] ) );
261 		mbuff.append( lineout( cap110_nn( cap110_comm_rem, i ), s110_comm_rem[i] ) );
262 	}
263 	if (compress) compress_maybe(mbuff);
264 	buff_c110.append(mbuff);
265 }
266 
read_c110_buffer(string data)267 void read_c110_buffer(string data)
268 {
269 	clear_110fields();
270 	read_header(data);
271 
272 	s110_mission_nbr = findstr( data, cap110_mission_nbr );
273 	s110_station = findstr( data, cap110_station );
274 	s110_date = findstr( data, cap110_date );
275 	s110_ds_a = findstr( data, cap110_ds_a );
276 	s110_ds_b = findstr( data, cap110_ds_b );
277 	s110_ds_c = findstr( data, cap110_ds_c );
278 	s110_ds_d = findstr( data, cap110_ds_d );
279 	s110_ds_e = findstr( data, cap110_ds_e );
280 	s110_ds_f = findstr( data, cap110_ds_f );
281 
282 	for (int i = 0; i < 23; i++) {
283 		s110_comm_time[i]  = findstr( data, cap110_nn( cap110_comm_time, i ) );
284 		s110_comm_call[i]  = findstr( data, cap110_nn( cap110_comm_call, i ) );
285 		s110_comm_chref[i] = findstr( data, cap110_nn( cap110_comm_chref, i ) );
286 		s110_comm_rem[i]   = findstr( data, cap110_nn( cap110_comm_rem, i ) );
287 	}
288 
289 	update_110form();
290 
291 }
292 
cap110_cb_load_template(string data)293 void cap110_cb_load_template(string data)
294 {
295 	clear_110fields();
296 	read_header(data);
297 
298 	s110_mission_nbr = findstr( data, cap110_mission_nbr );
299 	s110_station = findstr( data, cap110_station );
300 	s110_date = findstr( data, cap110_date );
301 	s110_ds_a = findstr( data, cap110_ds_a );
302 	s110_ds_b = findstr( data, cap110_ds_b );
303 	s110_ds_c = findstr( data, cap110_ds_c );
304 	s110_ds_d = findstr( data, cap110_ds_d );
305 	s110_ds_e = findstr( data, cap110_ds_e );
306 	s110_ds_f = findstr( data, cap110_ds_f );
307 
308 	for (int i = 0; i < 23; i++) {
309 		s110_comm_time[i]  = findstr( data, cap110_nn( cap110_comm_time, i ) );
310 		s110_comm_call[i]  = findstr( data, cap110_nn( cap110_comm_call, i ) );
311 		s110_comm_chref[i] = findstr( data, cap110_nn( cap110_comm_chref, i ) );
312 		s110_comm_rem[i]   = findstr( data, cap110_nn( cap110_comm_rem, i ) );
313 	}
314 
315 	update_110form();
316 }
317 
cap110_cb_new()318 void cap110_cb_new()
319 {
320 	if (check_110fields()) {
321 		if (fl_choice2(xMODIFIED, "No", xMODIFIED, NULL) == 1) {
322 			update_header(CHANGED);
323 			cap110_cb_save();
324 		}
325 	}
326 	clear_110_form();
327 	clear_header();
328 	cap110_def_filename= ICS_msg_dir;
329 	cap110_def_filename.append(xNEW).append(CAP110_FILE_EXT);
330 	show_filename(cap110_def_filename);
331 	using_cap110_template = false;
332 }
333 
cap110_cb_import()334 void cap110_cb_import()
335 {
336 	fl_alert2(xNOTIMPLEMENTED);
337 }
338 
cap110_cb_export()339 void cap110_cb_export()
340 {
341 	fl_alert2(xNOTIMPLEMENTED);
342 }
343 
cap110_cb_wrap_import(string wrapfilename,string inpbuffer)344 void cap110_cb_wrap_import(string wrapfilename, string inpbuffer)
345 {
346 	clear_110_form();
347 	cap110_cb_load_template(inpbuffer);
348 	cap110_def_filename= ICS_msg_dir;
349 	cap110_def_filename.append(wrapfilename);
350 	show_filename(cap110_def_filename);
351 	using_cap110_template = false;
352 }
353 
eval_cap110_fsize()354 int eval_cap110_fsize()
355 {
356 	Ccrc16 chksum;
357 	evalstr.assign("[WRAP:beg][WRAP:lf][WRAP:fn ");
358 	evalstr.append(cap110_base_filename).append("]");
359 	update_110fields();
360 	update_header(FROM);
361 	evalstr.append(header("<cap110>"));
362 	buff_c110.clear();
363 	make_buff_c110(true);
364 	if (buff_c110.empty()) return 0;
365 	compress_maybe( buff_c110 );
366 	evalstr.append( buff_c110 );
367 	evalstr.append("[WRAP:chksum ").append(chksum.scrc16(evalstr)).append("][WRAP:end]");
368 	return evalstr.length();
369 }
370 
cap110_cb_wrap_export()371 void cap110_cb_wrap_export()
372 {
373 	if (check_110fields()) {
374 		if (fl_choice2(xMODIFIED, "No", xMODIFIED, NULL) == 0)
375 			return;
376 		update_header(CHANGED);
377 	}
378 	update_110fields();
379 
380 	if (cap110_base_filename == string(xNEW).append(CAP110_FILE_EXT) ||
381 		cap110_base_filename == string(xDEFAULT).append(CAP110_FILE_EXT) )
382 		if (!cap110_cb_save_as()) return;
383 
384 	string wrapfilename = WRAP_send_dir;
385 	wrapfilename.append(cap110_base_filename);
386 	wrapfilename.append(".wrap");
387 	const char *p = FSEL::saveas(
388 			xSAVEASWRAP,
389 			xWRAPFILE,
390 			wrapfilename.c_str());
391 	if (p) {
392 		string pext = fl_filename_ext(p);
393 		wrapfilename = p;
394 		update_header(FROM);
395 		buff_c110.assign(header("<cap110>"));
396 		make_buff_c110(true);
397 		export_wrapfile(cap110_base_filename, wrapfilename, buff_c110, pext != ".wrap");
398 		write_110(cap110_def_filename);
399 	}
400 }
401 
cap110_cb_wrap_autosend()402 void cap110_cb_wrap_autosend()
403 {
404 	if (check_110fields()) {
405 		if (fl_choice2(xMODIFIED, "No", xMODIFIED, NULL) == 0)
406 			return;
407 		update_header(CHANGED);
408 	}
409 	update_110fields();
410 
411 	if (cap110_base_filename == string(xNEW).append(CAP110_FILE_EXT) ||
412 		cap110_base_filename == string(xDEFAULT).append(CAP110_FILE_EXT) )
413 		cap110_cb_save_as();
414 
415 	update_header(FROM);
416 	buff_c110.assign(header("<cap110>"));
417 	make_buff_c110(true);
418 
419 	xfr_via_socket(cap110_base_filename, buff_c110);
420 	write_110(cap110_def_filename);
421 }
422 
cap110_cb_load_template()423 void cap110_cb_load_template()
424 {
425 	string cap110_def_filename= cap110_def_template_name;
426 	const char *p = FSEL::select(
427 			xOPENTEMPLATE,
428 			string(xTEMPLATEFILE).append(CAP110_TEMP_EXT).c_str(),
429 			cap110_def_filename.c_str());
430 	if (p) {
431 		clear_110_form();
432 		read_data_file(p);
433 		cap110_def_template_name = p;
434 		show_filename(cap110_def_template_name);
435 		using_cap110_template = true;
436 	}
437 }
438 
cap110_cb_save_template()439 void cap110_cb_save_template()
440 {
441 	if (!using_cap110_template) {
442 		cap110_cb_save_as_template();
443 		return;
444 	}
445 	string cap110_def_filename= cap110_def_template_name;
446 	const char *p = FSEL::saveas(
447 			xSAVEASTEMPLATE,
448 			string(xTEMPLATEFILE).append(CAP110_TEMP_EXT).c_str(),
449 			cap110_def_filename.c_str());
450 	if (p) {
451 		update_header(CHANGED);
452 		buff_c110.assign(header("<cap110>"));
453 		make_buff_c110();
454 		write_110(p);
455 	}
456 }
457 
cap110_cb_save_as_template()458 void cap110_cb_save_as_template()
459 {
460 	string cap110_def_filename= cap110_def_template_name;
461 	const char *p = FSEL::saveas(
462 			xSAVEASTEMPLATE,
463 			string(xTEMPLATEFILE).append(CAP110_TEMP_EXT).c_str(),
464 			cap110_def_filename.c_str());
465 	if (p) {
466 		const char *pext = fl_filename_ext(p);
467 		cap110_def_template_name = p;
468 		if (strlen(pext) == 0) cap110_def_template_name.append(CAP110_TEMP_EXT);
469 		remove_spaces_from_filename(cap110_def_template_name);
470 		clear_header();
471 		update_header(CHANGED);
472 		buff_c110.assign(header("<cap110>"));
473 		make_buff_c110();
474 		write_110(cap110_def_template_name);
475 		show_filename(cap110_def_template_name);
476 		using_cap110_template = true;
477 	}
478 }
479 
cap110_cb_open()480 void cap110_cb_open()
481 {
482 	const char *p = FSEL::select(
483 			_(xOPENDATAFILE),
484 			string("CAP-110\t*").append(CAP110_FILE_EXT).c_str(),
485 			cap110_def_filename.c_str());
486 	if (!p) return;
487 	if (strlen(p) == 0) return;
488 	clear_110_form();
489 	read_data_file(p);
490 	using_cap110_template = false;
491 	cap110_def_filename= p;
492 	show_filename(cap110_def_filename);
493 }
494 
write_110(string s)495 void write_110(string s)
496 {
497 	FILE *file110 = fopen(s.c_str(), "w");
498 	if (!file110) return;
499 
500 	fwrite(buff_c110.c_str(), buff_c110.length(), 1, file110);
501 	fclose(file110);
502 }
503 
cap110_cb_save_as()504 bool cap110_cb_save_as()
505 {
506 	const char *p;
507 	string newfilename;
508 
509 	string name = named_file();
510 	if (!name.empty()) {
511 		name.append(CAP110_FILE_EXT);
512 		newfilename = ICS_msg_dir;
513 		newfilename.append(name);
514 	} else
515 		newfilename = cap110_def_filename;
516 
517 	p = FSEL::saveas(
518 			_(xSAVEDATAFILE),
519 			string("CAP-110\t*").append(CAP110_FILE_EXT).c_str(),
520 			newfilename.c_str());
521 
522 	if (!p) return false;
523 	if (strlen(p) == 0) return false;
524 
525 	if (progStatus.sernbr_fname) update_sernbr();
526 
527 	const char *pext = fl_filename_ext(p);
528 	cap110_def_filename= p;
529 	if (strlen(pext) == 0) cap110_def_filename.append(CAP110_FILE_EXT);
530 
531 	remove_spaces_from_filename(cap110_def_filename);
532 	update_110fields();
533 	update_header(NEW);
534 	buff_c110.assign(header("<cap110>"));
535 	make_buff_c110();
536 	write_110(cap110_def_filename);
537 
538 	using_cap110_template = false;
539 	show_filename(cap110_def_filename);
540 	return true;
541 }
542 
cap110_cb_save()543 void cap110_cb_save()
544 {
545 	if (cap110_base_filename == string(xNEW).append(CAP110_FILE_EXT) ||
546 		cap110_base_filename == string(xDEFAULT).append(CAP110_FILE_EXT) ||
547 		using_cap110_template == true) {
548 		cap110_cb_save_as();
549 		return;
550 	}
551 	if (check_110fields()) update_header(CHANGED);
552 	update_110fields();
553 	buff_c110.assign(header("<cap110>"));
554 	make_buff_c110();
555 	write_110(cap110_def_filename);
556 	using_cap110_template = false;
557 }
558 
cap110_cb_html()559 void cap110_cb_html()
560 {
561 	string fname_name = fl_filename_name(cap110_def_filename.c_str());
562 	size_t p = fname_name.rfind('.');
563 	if (p != string::npos) fname_name.erase(p);
564 
565 	string cap110_fname = ICS_dir;
566 	cap110_fname.append(fname_name);
567 	cap110_fname.append(".html");
568 
569 	string html_text = "";
570 	string empty = "<br>";
571 
572 	update_110fields();
573 	string form110 = cap110_html_template;
574 
575 	replacestr(form110, TITLE, fname_name);
576 	replacestr(form110, cap110_mission_nbr, s110_mission_nbr );
577 	replacestr(form110, cap110_station, s110_station );
578 	replacestr(form110, cap110_date, s110_date );
579 	replacestr(form110, cap110_ds_a, s110_ds_a );
580 	replacestr(form110, cap110_ds_b, s110_ds_b );
581 	replacestr(form110, cap110_ds_c, s110_ds_c );
582 	replacestr(form110, cap110_ds_d, s110_ds_d );
583 	replacestr(form110, cap110_ds_e, s110_ds_e );
584 	replacestr(form110, cap110_ds_f, s110_ds_f );
585 
586 	for (int i = 0; i < 23; i++) {
587 		replacestr(form110, cap110_nn( cap110_comm_time, i ),
588 			s110_comm_time[i].empty() ? empty : s110_comm_time[i] );
589 		replacestr(form110, cap110_nn( cap110_comm_call, i ),
590 			s110_comm_call[i].empty() ? empty : s110_comm_call[i] );
591 		replacestr(form110, cap110_nn( cap110_comm_chref, i ),
592 			s110_comm_chref[i].empty() ? empty : s110_comm_chref[i] );
593 		replacestr(form110, cap110_nn( cap110_comm_rem, i ),
594 			s110_comm_rem[i].empty() ? empty : s110_comm_rem[i] );
595 	}
596 
597 	FILE *file110 = fopen(cap110_fname.c_str(), "w");
598 	fprintf(file110,"%s", form110.c_str());
599 	fclose(file110);
600 
601 	open_url(cap110_fname.c_str());
602 }
603 
cap110_cb_msg_type()604 void cap110_cb_msg_type()
605 {
606 	if (tabs_msg_type->value() == tab_cap110 )
607 		show_filename(cap110_def_filename);
608 }
609 
cap110_cb_textout()610 void cap110_cb_textout()
611 {
612 	string cap110_fname = ICS_dir;
613 	cap110_fname.append("cap110.txt");
614 
615 	update_110fields();
616 	string form110 = cap110_text_template;
617 
618 	replacestr(form110, cap110_mission_nbr, s110_mission_nbr );
619 	replacestr(form110, cap110_station, s110_station );
620 	replacestr(form110, cap110_date, s110_date );
621 	replacestr(form110, cap110_ds_a, s110_ds_a );
622 	replacestr(form110, cap110_ds_b, s110_ds_b );
623 	replacestr(form110, cap110_ds_c, s110_ds_c );
624 	replacestr(form110, cap110_ds_d, s110_ds_d );
625 	replacestr(form110, cap110_ds_e, s110_ds_e );
626 	replacestr(form110, cap110_ds_f, s110_ds_f );
627 
628 	string logdata;
629 	string lgdata = xLOGDATA;
630 	const char *fmt = "%-7s|%-12s|%-15s|%s\n";
631 	char tempstr[200];
632 	snprintf(tempstr, sizeof(tempstr), fmt, "TIME", "CALL", "CH REF", "REMARKS");
633 
634 	logdata = tempstr;
635 	for (int i = 0; i < 23; i++) {
636 		if (!s110_comm_time[i].empty() ||
637 			!s110_comm_call[i].empty() ||
638 			!s110_comm_chref[i].empty() ||
639 			!s110_comm_rem[i].empty() ) {
640 			snprintf(tempstr, sizeof(tempstr), fmt,
641 				s110_comm_time[i].c_str(),
642 				s110_comm_call[i].c_str(),
643 				s110_comm_chref[i].c_str(),
644 				s110_comm_rem[i].c_str());
645 			logdata.append(tempstr);
646 		}
647 	}
648 	replacestr(form110, lgdata, logdata);
649 
650 	FILE *file110 = fopen(cap110_fname.c_str(), "w");
651 	fprintf(file110,"%s", form110.c_str());
652 	fclose(file110);
653 
654 	open_url(cap110_fname.c_str());
655 }
656 
657