1 /*********************************************************
2  * cc90hfe (c) Teo Developers
3  *********************************************************
4  *
5  *  Copyright (C) 2012-2017 Fran�ois Mouret
6  *
7  *  This program 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 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program 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, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 
22 /*
23  *  Module     : main.c
24  *  Version    : 0.7.0
25  *  Cr�� par   : Fran�ois Mouret 27/02/2013
26  *  Modifi� par: Fran�ois Mouret 26/07/2013 30/05/2015 31/05/2015
27  *
28  *  Main functions.
29  */
30 
31 
32 #ifndef SCAN_DEPEND
33    #include <stdio.h>
34    #include <string.h>
35    #include <unistd.h>
36    #include <stdlib.h>
37    #ifdef DEBIAN_BUILD
38       #include <sys/stat.h>
39    #endif
40 #endif
41 
42 #include "defs.h"
43 #include "std.h"
44 #include "ini.h"
45 #include "errors.h"
46 #include "option.h"
47 #include "encode.h"
48 #include "cc90.h"
49 #include "main.h"
50 #include "hfe.h"
51 #include "serial.h"
52 
53 int is_fr;
54 struct DISK_INFO disk;
55 struct GUI_INFO gui;
56 int windowed_mode = 0;
57 FILE *fd_debug = NULL;
58 
59 static int current_drive = 0;
60 static int archive_option = 0;
61 static int extract_option = 0;
62 static int install_option = 0;
63 static int version_option = 0;
64 static struct STRING_LIST *file_name_list = NULL;
65 
66 
main_RecordMessage(const char message[])67 static int main_RecordMessage (const char message[])
68 {
69     error_msg = std_free (error_msg);
70     error_msg = std_strdup_printf ("%s : %s", is_fr?"Erreur":"Error", message);
71     return CC90HFE_ERROR;
72 }
73 
74 
75 
read_command_line(int argc,char * argv[])76 static char *read_command_line(int argc, char *argv[])
77 {
78     struct OPTION_ENTRY entries[] = {
79         { "archive",
80           'a',
81           OPTION_ARG_BOOL,
82           &archive_option,
83           is_fr?"Copie du Thomson vers un fichier HFE via CC90"
84                 :"Copy a Thomson disk onto a HFE file via CC90",
85           NULL,
86           0,
87           0 },
88         { "extract",
89           'x',
90           OPTION_ARG_BOOL,
91           &extract_option,
92           is_fr?"Copie d'un fichier HFE vers un Thomson via CC90"
93                :"Copy an HFE file onto a Thomson disk via CC90",
94           NULL,
95           0,
96           0 },
97         { "install",
98           'i',
99           OPTION_ARG_BOOL,
100           &install_option,
101           is_fr?"Installe CC90 (avec INSTALL.BAS tournant sur le Thomson)"
102                :"Install CC90 (with INSTALL.BAS running on the Thomson)",
103           NULL,
104           0,
105           0 },
106         { "version",
107           'v',
108           OPTION_ARG_BOOL,
109           &version_option,
110           is_fr?"Affiche la version du programme"
111                :"Display the program version",
112           NULL,
113           0,
114           0 },
115         { "side-0-is-not-thomson",
116           '\0',
117           OPTION_ARG_BOOL,
118           &gui.not_thomson_side[0],
119           is_fr?"La face 0 n'est pas Thomson"
120                :"Side 0 is not Thomson like",
121           NULL,
122           0,
123           0 },
124         { "side-1-is-not-thomson",
125           '\0',
126           OPTION_ARG_BOOL,
127           &gui.not_thomson_side[1],
128           is_fr?"La face 1 n'est pas Thomson"
129                :"Side 1 is not Thomson like",
130           NULL,
131           0,
132           0 },
133         { "read-retries-max",
134           '\0',
135           OPTION_ARG_INT,
136           &gui.read_retry_max,
137           is_fr?"Nombre maximum de relectures (1-15)"
138                :"Maximum number of retries (1-15)",
139           is_fr?"nombre":"number",
140           1,
141           15 },
142         { NULL, 0, 0, NULL, NULL, NULL }
143     };
144     return option_Parse (argc, argv, PROG_NAME, entries, &file_name_list);
145 }
146 
147 
148 
console_check_file_name_list(void)149 static int console_check_file_name_list (void)
150 {
151     int string_list_length = std_StringListLength (file_name_list);
152 
153     if (string_list_length == 0)
154         return main_RecordMessage (is_fr?"Nom du fichier HFE manquant"
155                                          :"Missing HFE file name");
156 
157     if (string_list_length > 1)
158         return main_RecordMessage (is_fr?"Fichiers HFE trop nombreux"
159                                          :"Too many HFE files");
160 
161     disk.file_name = std_free (disk.file_name);
162     disk.file_name = std_strdup_printf ("%s", file_name_list->str);
163     return 0;
164 }
165 
166 
167 
168 /* console_exit_failure:
169  *  Free all resources and exit with failure.
170  */
console_exit_failure(void)171 static void console_exit_failure (void)
172 {
173     printf ("%s\n", encode_String (error_msg));
174     main_FreeAll ();
175     exit (EXIT_FAILURE);
176 }
177 
178 
open_log(void)179 static void open_log (void)
180 {
181     char *fname = NULL;
182 
183     fname = std_ApplicationPath (APPLICATION_DIR, "cc90hfe.log");
184     fd_debug = fopen (fname, "wb");
185     fname = std_free (fname);
186 }
187 
188 
189 
close_log(void)190 static void close_log (void)
191 {
192     std_fclose (fd_debug);
193     fd_debug = NULL;
194 }
195 
196 
197 /* ------------------------------------------------------------------------- */
198 
199 
main_ArchiveDisk(void)200 int main_ArchiveDisk (void)
201 {
202     int err = 0;
203     int track;
204 
205     if ((progress_on == TRUE)
206      && ((err = hfe_WriteOpen(disk.file_name)) == 0))
207     {
208         open_log ();
209         for (track=0;
210              (track<disk.track_count)&&(progress_on!=0)&&(err==0);
211              track++)
212         {
213              gui_ProgressUpdate (((track+1) * 100)/disk.track_count);
214              if (progress_on == TRUE)
215                 if ((err = cc90_ReadTrack (current_drive, track)) == 0)
216                     err = hfe_WriteTrack ();
217         }
218         close_log ();
219         hfe_Close();
220     }
221     if (windowed_mode == 0)
222         printf ("\n");
223 
224     progress_on = FALSE;
225 
226     return err;
227 }
228 
229 
230 
main_ExtractDisk(void)231 int main_ExtractDisk (void)
232 {
233     int err = 0;
234     int track;
235 
236     if ((progress_on == TRUE)
237      && ((err = hfe_ReadOpen(disk.file_name)) == 0))
238     {
239         for (track=0;
240              (track<disk.track_count)&&(progress_on!=0)&&(err==0);
241              track++)
242         {
243             gui_ProgressUpdate (((track+1) * 100)/disk.track_count);
244             if (progress_on  == TRUE)
245                 if ((err = hfe_ReadTrack ()) == 0)
246                     err = cc90_WriteTrack (current_drive, track);
247         }
248         hfe_Close();
249     }
250     if (windowed_mode == 0)
251         printf ("\n");
252 
253     progress_on = FALSE;
254 
255     return err;
256 }
257 
258 
259 
main_ConsoleReadCommandLine(int argc,char * argv[])260 void main_ConsoleReadCommandLine (int argc, char *argv[])
261 {
262     if (read_command_line (argc, argv) != NULL)
263         console_exit_failure ();
264 }
265 
266 
267 
main_InitAll(void)268 void main_InitAll (void)
269 {
270     windowed_mode = 0;
271 
272     /* init info structure */
273     memset (&disk, 0x00, sizeof(struct DISK_INFO));
274     disk.track_size  = MFM_TRACK_LENGTH>>2;
275     disk.track_count = 80;
276     memset (&gui, 0x00, sizeof(struct GUI_INFO));
277     gui.timeout = SERIAL_TIME_OUT;
278     gui.not_thomson_side[0] = FALSE;
279     gui.not_thomson_side[1] = FALSE;
280     gui.read_retry_max = 3;
281 }
282 
283 
284 
main_FreeAll(void)285 void main_FreeAll (void)
286 {
287     /* save INI file and free strings */
288     ini_Save ();
289 
290     /* free string list */
291     std_StringListFree (file_name_list);
292     file_name_list = NULL;
293 
294     /* free file name */
295     disk.file_name = std_free (disk.file_name);
296 
297     /* free error message */
298     error_msg = std_free (error_msg);
299 
300     /* free tracks */
301     disk.data[SIDE_0] = std_free (disk.data[SIDE_0]);
302     disk.clck[SIDE_0] = std_free (disk.clck[SIDE_0]);
303     disk.data[SIDE_1] = std_free (disk.data[SIDE_1]);
304     disk.clck[SIDE_1] = std_free (disk.clck[SIDE_1]);
305 }
306 
307 
308 
main_Console(void)309 void main_Console (void)
310 {
311     int err = 0;
312     progress_on = 1;
313 
314     if (version_option == TRUE)
315     {
316         printf(PROG_NAME" version "PROG_VERSION_STRING"\n");
317     }
318     else
319     if (install_option == TRUE)
320     {
321         if (cc90_Install () < 0)
322             console_exit_failure ();
323     }
324     else
325     if (archive_option == TRUE)
326     {
327         if (console_check_file_name_list() < 0)
328             console_exit_failure ();
329        if ((err = cc90_Open()) == 0)
330             err = main_ArchiveDisk ();
331         cc90_Close();
332         if (err < 0)
333             console_exit_failure ();
334     }
335     else
336     if (extract_option == TRUE)
337     {
338         if (console_check_file_name_list() < 0)
339             console_exit_failure ();
340         if ((err = cc90_Open()) == 0)
341             err = main_ExtractDisk ();
342         cc90_Close();
343         if (err < 0)
344             console_exit_failure ();
345     }
346     else
347     {
348         main_RecordMessage (is_fr?"Argument Manquant":"Missing argument");
349         console_exit_failure ();
350     }
351 }
352