202 lines
5.7 KiB
C
202 lines
5.7 KiB
C
/* *****************************************************************************
|
|
* p7os/main.c -- p7os main source.
|
|
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
|
*
|
|
* This file is part of p7utils.
|
|
* p7utils is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2.0 of the License,
|
|
* or (at your option) any later version.
|
|
*
|
|
* p7utils is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with p7utils; if not, see <http://www.gnu.org/licenses/>.
|
|
* ************************************************************************** */
|
|
#include "main.h"
|
|
#include <unistd.h>
|
|
|
|
/* ************************************************************************** */
|
|
/* Error messages */
|
|
/* ************************************************************************** */
|
|
/* Couldn't initialize connexion to calculator. */
|
|
static const char error_noconnexion[] =
|
|
"Could not connect to the calculator.\n"
|
|
"- Is it plugged in and in Receive mode/OS Update?\n"
|
|
"- Have you tried changing the cable ?\n";
|
|
|
|
/* Calculator was found but program wasn't allowed to communicate with it. */
|
|
static const char error_noaccess[] =
|
|
"Could not get access to the calculator.\n"
|
|
"Install the appropriate udev rule, or run as root.\n";
|
|
|
|
/* The calculator acted in a weird way. */
|
|
static const char error_unplanned[] =
|
|
"The calculator didn't act as planned: %s.\n"
|
|
"Stop receive mode on calculator and start it again before re-running " \
|
|
QUOTE(BIN) ".\n";
|
|
|
|
/* Unsupported operation -> OS Update, not receive mode! */
|
|
static const char error_unsupported[] =
|
|
"Required operation was unsupported by the calculator.\n"
|
|
"If you did not prepare, perhaps you should prepare?\n";
|
|
|
|
/* ************************************************************************** */
|
|
/* Auxiliary functions */
|
|
/* ************************************************************************** */
|
|
/**
|
|
* osdisp:
|
|
* Nice little loading bar.
|
|
*
|
|
* Taken from `src/p7/main.c`.
|
|
* "Initialization" is when id > total (called in main).
|
|
*
|
|
* @arg id data packet ID.
|
|
* @arg total total number of packets.
|
|
*/
|
|
|
|
static int osdisp_init = 0;
|
|
static const char *osdisp_msg;
|
|
static void osdisp(p7ushort_t id, p7ushort_t total)
|
|
{
|
|
/* here's the buffer */
|
|
static char buf[50] =
|
|
"\r|---------------------------------------| 00.00%";
|
|
static char *bar = &buf[2];
|
|
|
|
/* initialize */
|
|
static int pos;
|
|
|
|
/* if is initialize, fill */
|
|
if (id > total) {
|
|
pos = 0;
|
|
puts(osdisp_msg);
|
|
/* indicate that is has been initialized */
|
|
osdisp_init = 1;
|
|
/* put initial buffer */
|
|
fputs(buf, stdout);
|
|
/* save cursor position */
|
|
fputs("\x1B[s", stdout);
|
|
/* we're done */
|
|
return ;
|
|
}
|
|
|
|
/* id and total start from 1, let them start from zero */
|
|
id--; total--;
|
|
|
|
/* modify buffer */
|
|
/* - # - */
|
|
int current = 38 * id / total;
|
|
while (pos <= current) bar[pos++] = '#';
|
|
/* - % - */
|
|
unsigned int percent = 10000 * id / total;
|
|
sprintf(&buf[43], "%02u.%02u", percent / 100, percent % 100);
|
|
|
|
/* put it */
|
|
fputs(buf, stdout);
|
|
/* force cursor position */
|
|
fputs("\x1B""8", stdout);
|
|
}
|
|
|
|
/* ************************************************************************** */
|
|
/* Main function */
|
|
/* ************************************************************************** */
|
|
/**
|
|
* main:
|
|
* User entry point of the program.
|
|
*
|
|
* @arg ac arguments count
|
|
* @arg av arguments values
|
|
* @return return code (0 if OK)
|
|
*/
|
|
|
|
#define initflags (P7_ACTIVE | P7_CHECK | P7_TERM)
|
|
int main(int ac, char **av)
|
|
{
|
|
/* parse args */
|
|
args_t args;
|
|
if (parse_args(ac, av, &args))
|
|
return (0);
|
|
|
|
/* Initialize libp7 and communication */
|
|
p7_handle_t *handle = NULL; int err;
|
|
if (args.com) err = p7_cominit(&handle, initflags, args.com,
|
|
&p7_default_settings);
|
|
else err = p7_init(&handle, initflags);
|
|
if (err) goto fail;
|
|
|
|
/* prepare */
|
|
if (!args.noprepare) {
|
|
/* make the preparation thing */
|
|
osdisp_msg = "Uploading the Update.Exe.";
|
|
if ((err = prepare_ops(handle, args.uexe, osdisp)))
|
|
goto fail;
|
|
if (osdisp_init) {
|
|
osdisp_init = 0;
|
|
puts("\b\b\b\b\b\bTransfer complete.");
|
|
}
|
|
handle = NULL;
|
|
|
|
/* was only about preparing? */
|
|
if (args.menu == mn_prepare_only)
|
|
return (0);
|
|
|
|
/* sleep a little, in case */
|
|
printf("Waiting for the Update.Exe to be setup...\n");
|
|
sleep(1);
|
|
|
|
/* re-open the handle */
|
|
if (args.com) err = p7_cominit(&handle, initflags, args.com,
|
|
&p7_default_settings);
|
|
else err = p7_init(&handle, initflags);
|
|
if (err) {
|
|
p7_exit(handle);
|
|
goto fail;
|
|
}
|
|
}
|
|
|
|
/* check according to menu */
|
|
switch (args.menu) {
|
|
/* backup the thing menu */
|
|
case mn_get:
|
|
/* get the os */
|
|
osdisp_msg = "Gathering the OS...";
|
|
err = p7_backup_romfile(handle, args.local, osdisp);
|
|
if (err) goto fail;
|
|
fclose(args.local);
|
|
break;
|
|
}
|
|
|
|
/* exit libp7 */
|
|
p7_exit(handle);
|
|
|
|
/* then we're good */
|
|
return (0);
|
|
|
|
fail:
|
|
/* interrupt loading bar */
|
|
if (osdisp_init)
|
|
puts("\b\b\b\b\b\bError !");
|
|
|
|
/* displaying error */
|
|
if (err > 0) switch (err) {
|
|
case p7_error_nocalc: log(error_noconnexion); break;
|
|
case p7_error_noaccess: log(error_noaccess); break;
|
|
case p7_error_unsupported: log(error_unsupported); break;
|
|
default: log(error_unplanned, p7_strerror(err));
|
|
}
|
|
|
|
/* closing the handle */
|
|
p7_exit(handle);
|
|
|
|
/* closing the file, removing if necessary */
|
|
if (args.localpath) {
|
|
fclose(args.local);
|
|
remove(args.localpath);
|
|
}
|
|
return (1);
|
|
}
|