/* ************************************************************************** */ /* _____ _ */ /* p7os/main.c |_ _|__ _ _| |__ ___ _ _ */ /* | Project: p7utils | |/ _ \| | | | '_ \ / _ \ | | | */ /* | | (_) | |_| | | | | __/ |_| | */ /* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ /* Last updated: 2017/01/16 23:55:54 |___/ */ /* */ /* ************************************************************************** */ #include "main.h" #include /* ************************************************************************** */ /* 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 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; /* 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); else err = p7_init(&handle, initflags); if (err) goto fail; /* prepare */ if (!args.noprepare) { /* make the preparation thing */ printf("Uploading the Update.Exe.\n"); 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); 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 */ printf("Gathering the OS...\n"); 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); }