cake
/
p7utils
Archived
1
0
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
p7utils/src/p7/main.c

314 lines
8.9 KiB
C

/* ************************************************************************** */
/* _____ _ */
/* p7/main.c |_ _|__ _ _| |__ ___ _ _ */
/* | Project: p7utils | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2017/01/16 23:55:54 |___/ */
/* */
/* ************************************************************************** */
#include "main.h"
#include <stdlib.h>
#include <string.h>
#include <libp7/stream.h>
/* ************************************************************************** */
/* Error messages */
/* ************************************************************************** */
/* Couldn't initialize connexion with the calculator. */
static const char error_noconnexion[] =
"Could not connect to the calculator.\n"
"- Is it plugged in and in receive mode?\n"
"- Have you tried changing the cable?\n";
/* Calculator was disconnected. */
static const char error_disconnected[] =
"Lost connexion to the calculator!\n"
"Please reconnect the calculator, rerun receive mode and try again.\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";
/* Command was unsupported. */
static const char error_unsupported[] =
"The command is unsupported by the calculator.\n"
"- Does the calculator have mass storage?\n"
"- Does its OS allow the use of it?\n"
"- Is it in Receive Mode (and not in OS Update)?\n";
/* The device didn't exist. */
static const char error_unsupported_device[] =
"Device '%s' is not supported by the device.\n";
/* The calculator acted in an unplanned way. */
static const char error_unplanned[] =
"The calculator didn't act as planned.\n"
"Stop receive mode on calculator and start it again before re-running " \
QUOTE(BIN) ".\n"
"Error was: %s\n";
/* Requested file didn't exist. */
static const char error_noexists[] =
"Requested file didn't exist.\n";
/* Sent file cannot be empty. */
static const char error_empty[] =
"Can't send an empty file!\n";
/* Not enough space left on the calculator. */
static const char error_nospace[] =
"Not enough space on the calculator for the file you're trying to send.\n"
"If you believe there should be, try optimizing (OPT) on the calculator\n"
"(in MEMORY menu) and try again.\n";
/* ************************************************************************** */
/* Auxiliary functions */
/* ************************************************************************** */
/**
* sendfile_confirm:
* Confirm file sending.
*
* @return if the file overwriting is confirmed
*/
static int sendfile_confirm(void)
{
char line[10];
/* Print stuff */
printf("It looks like the file already exists on the calculator.\n");
printf("Overwrite ? ([n]/y) ");
/* Get the line */
if (!fgets(line, 10, stdin))
return (0);
/* Check if should overwrite */
return (*line == 'y');
}
/**
* sendfile_display:
* File sending nice display.
*
* "Initialization" is when id > total (called in main).
*
* @arg id data packet ID
* @arg total total number of data packets
*/
static int sendfile_display_initialized = 0;
static void sendfile_display(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 */
sendfile_display_initialized = 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);
}
/**
* print_file_info:
* File listing callback.
*
* @arg cookie (unused)
* @arg dir the directory in which the file is stored (NULL if root)
* @arg name the filename
* @arg size the filesize
*/
static void print_file_info(void *cookie, const char *dir, const char *name,
p7uint_t size)
{
(void)cookie;
/* initialize buffer */
static char buf[45];
/* clean buffer */
memset(buf, ' ', 28);
/* put path in buffer */
char *b = buf;
if (dir) b += sprintf(b, "%s/", dir);
if (name) b[sprintf(b, "%s", name)] = ' ';
/* put size */
sprintf(&buf[28], "%10uo", (unsigned)size);
/* put the string */
puts(buf);
}
/* ************************************************************************** */
/* Main function */
/* ************************************************************************** */
/**
* main:
* User entry point of the program.
*
* @arg ac arguments count
* @arg av arguments values
* @return return code (0 if ok)
*/
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, args.initflags, args.com);
else err = p7_init(&handle, args.initflags);
if (err) {
/* display error */
switch (err) {
case p7_error_nocalc: log(error_noconnexion); break;
case p7_error_noaccess: log(error_noaccess); break;
default: log(error_unplanned, p7_strerror(err)); break;
}
/* closing, removing if necessary */
if (args.menu == mn_send)
fclose(args.local);
if (args.menu == mn_get && args.local != stdout) {
fclose(args.local);
remove(args.localpath);
}
return (1);
}
/* Try faster serial */
/*if ((err = p7_setlink(handle, P7_B19200, P7_PARITY_NONE, P7_TWOSTOPBITS))
&& err != p7_error_unsupported) {
log(error_unplanned, p7_strerror(err));
p7_exit(handle);
return (1);
}*/
/* Check according to menu */
switch (args.menu) {
case mn_send:
/* get file size */
fseek(args.local, 0, SEEK_END);
size_t filesize = (p7uint_t)ftell(args.local);
rewind(args.local);
/* get capacity */
p7uint_t capacity;
err = p7_getfreemem(handle, args.storage, &capacity);
if (err) break;
/* optimize if required */
if (filesize > (size_t)capacity) {
printf("Not enough space on the device. Let's optimize!\n");
err = p7_optimize(handle, args.storage);
if (err) break;
}
/* send the file */
err = p7_sendfile(handle, args.local,
args.dirname, args.filename,
args.storage, 1, args.force ? NULL : &sendfile_confirm,
args.nicedisp ? &sendfile_display : NULL);
break;
case mn_get:
err = p7_reqfile(handle, args.local, args.dirname, args.filename,
args.storage, args.nicedisp && args.local != stdout
? &sendfile_display : NULL);
break;
case mn_copy:
err = p7_copy(handle, args.dirname, args.filename,
args.newdir, args.newname, args.storage);
break;
case mn_del:
err = p7_delete(handle, args.dirname, args.filename,
args.storage);
break;
case mn_ls:
err = p7_list(handle, args.storage, &print_file_info, NULL);
break;
case mn_reset:
err = p7_reset(handle, args.storage);
break;
case mn_optimize:
err = p7_optimize(handle, args.storage);
break;
case mn_info:
err = dump(handle);
break;
}
/* put error */
if (err && err != p7_error_denied_overwrite) {
if (sendfile_display_initialized)
puts("\b\b\b\b\b\bError !");
/* close the file */
if (args.local) fclose(args.local);
if (args.menu == mn_get && args.local != stdout)
remove(args.localpath);
/* put the error string */
switch (err) {
case p7_error_fullmem: log(error_nospace); break;
case p7_error_empty: log(error_empty); break;
case p7_error_notfound: log(error_noexists); break;
case p7_error_nocalc: log(error_disconnected); break;
case p7_error_unsupported: log(error_unsupported); break;
case p7_error_unsupported_device:
log(error_unsupported_device, args.storage); break;
default: log(error_unplanned, p7_strerror(err));
}
/* that doesn't mean you shouldn't exit, heh. */
p7_exit(handle);
/* return that an error has occured */
return (1);
}
if (sendfile_display_initialized)
puts("\b\b\b\b\b\bTransfer complete.");
if (args.local) fclose(args.local);
/* terminate communication and de-initialize libp7 */
p7_exit(handle);
/* Then we're good */
return (0);
}