Started implementing Windows filesystem as well, as a proof of concept

This commit is contained in:
Thomas Touhey 2017-07-02 04:39:43 +02:00
parent 563d6102ac
commit 036314140e
19 changed files with 643 additions and 39 deletions

View File

@ -73,13 +73,19 @@ CASIO_EXTERN int CASIO_EXPORT casio_opencom_windows
/* ************************************************************************* */
/* Built-in filesystems */
/* ************************************************************************* */
/* Make a local POSIX filesystem interface. */
/* Make a POSIX filesystem interface. */
# if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
CASIO_EXTERN int CASIO_EXPORT casio_open_posix_fs
OF((casio_filesystem_t **casio__filesystem));
OF((casio_fs_t **casio__filesystem));
# else
# define LIBCASIO_DISABLED_POSIX_FS
# endif
/* Make a Windows API filesystem interface. */
# ifndef LIBCASIO_DISABLED_WINDOWS
CASIO_EXTERN int CASIO_EXPORT casio_open_windows_fs
OF((casio_fs_t **casio__filesystem));
# endif
/* ************************************************************************* */
/* Built-in serial devices listing */
/* ************************************************************************* */

View File

@ -23,16 +23,16 @@
CASIO_BEGIN_NAMESPACE
/* forward structure declarations (don't mind) */
struct casio_filesystem_s;
typedef struct casio_filesystem_s casio_filesystem_t;
struct casio_fs_s;
typedef struct casio_fs_s casio_fs_t;
struct casio_fsfuncs_s;
typedef struct casio_fsfuncs_s casio_fsfuncs_t;
typedef struct casio_fsfuncs_s casio_fsfuncs_t;
struct casio_pathnode_s;
typedef struct casio_pathnode_s casio_pathnode_t;
typedef struct casio_pathnode_s casio_pathnode_t;
struct casio_path_s;
typedef struct casio_path_s casio_path_t;
typedef struct casio_path_s casio_path_t;
struct casio_stat_s;
typedef struct casio_stat_s casio_stat_t;
typedef struct casio_stat_s casio_stat_t;
/* ************************************************************************* */
/* Filesystem file path */
/* ************************************************************************* */
@ -171,22 +171,31 @@ CASIO_BEGIN_DECLS
/* Open a custom filesystem. */
CASIO_EXTERN int CASIO_EXPORT casio_open_fs
OF((casio_filesystem_t **casio__filesystem,
OF((casio_fs_t **casio__filesystem,
void *casio__cookie, const casio_fsfuncs_t *casio__funcs));
/* Manipulate native paths. */
CASIO_EXTERN int CASIO_EXPORT casio_make_native_path
OF((casio_filesystem_t *casio__filesystem,
OF((casio_fs_t *casio__filesystem,
void **casio__native_path, casio_path_t *casio__path));
CASIO_EXTERN void CASIO_EXPORT casio_free_native_path
OF((casio_filesystem_t *casio__filesystem,
OF((casio_fs_t *casio__filesystem,
void *casio__native_path));
/* Make a directory. */
CASIO_EXTERN int CASIO_EXPORT casio_makedir
OF((casio_filesystem_t *casio__fs, casio_path_t *casio__path));
OF((casio_fs_t *casio__fs, void *casio__path));
CASIO_EXTERN int CASIO_EXPORT casio_makedir_path
OF((casio_fs_t *casio__fs, casio_path_t *casio__path));
/* Delete an element. */
CASIO_EXTERN int CASIO_EXPORT casio_delete
OF((casio_fs_t *casio__fs, void *casio__path));
CASIO_EXTERN int CASIO_EXPORT casio_delete_path
OF((casio_fs_t *casio__fs, casio_path_t *casio__path));
CASIO_END_DECLS
CASIO_END_NAMESPACE

View File

@ -194,11 +194,6 @@ CASIO_EXTERN int CASIO_EXPORT casio_upload_and_run_file
casio_link_progress_t *casio__disp, void *casio__pcookie));
# endif
/* Make the MCS interface (don't use it unless you know what you're doing). */
CASIO_EXTERN int CASIO_EXPORT casio_open_seven_mcs
OF((casio_mcs_t **casio__mcs, casio_link_t *casio__link));
CASIO_END_DECLS
CASIO_END_NAMESPACE
# include "protocol/legacy.h"

View File

@ -182,6 +182,7 @@ typedef struct casio_mcscell_s {
* Here is the main structure. Don't be afraid, it doesn't bite. */
typedef struct casio_mcshead_s {
# define casio_mcshead_for casio_mcshead_flags
unsigned long casio_mcshead_flags;
/* file main information */

View File

@ -420,6 +420,18 @@ CASIO_EXTERN int CASIO_EXPORT casio_seven_open_data_stream
OF((casio_stream_t **casio__stream,
casio_link_t *casio__link, casio_off_t casio__size,
casio_link_progress_t *casio__disp, void *casio__dcookie));
/* ************************************************************************* */
/* Protocol 7.00 high-level abstractions */
/* ************************************************************************* */
/* Make the MCS interface. */
CASIO_EXTERN int CASIO_EXPORT casio_open_seven_mcs
OF((casio_mcs_t **casio__mcs, casio_link_t *casio__link));
/* Make the filesystem interface. */
CASIO_EXTERN int CASIO_EXPORT casio_open_seven_fs
OF((casio_fs_t **casio__filesystem, casio_link_t *casio__link));
CASIO_END_DECLS
CASIO_END_NAMESPACE

View File

@ -1,5 +1,5 @@
/* ****************************************************************************
* fs/builtin/posix/open.c -- open a POSIX filesystem.
* fs/builtin/posix/make.c -- open a POSIX filesystem.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
@ -35,7 +35,7 @@ CASIO_LOCAL casio_fsfuncs_t posix_fs_funcs = {
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_open_posix_fs(casio_filesystem_t **fs)
int CASIO_EXPORT casio_open_posix_fs(casio_fs_t **fs)
{
return (casio_open_fs(fs, NULL, &posix_fs_funcs));
}

View File

@ -73,6 +73,7 @@ int CASIO_EXPORT casio_make_posix_path(void *cookie,
node = node->casio_pathnode_next;
if (node) *path++ = '/';
}
*path = 0;
/* No error has occured! */
return (0);

View File

@ -0,0 +1,35 @@
/* ****************************************************************************
* fs/builtin/windows/make.c -- make a Windows filesystem.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "windows.h"
#ifndef LIBCASIO_DISABLED_WINDOWS
/**
* casio_open_windows_fs:
* Open a Windows filesystem interface.
*
* @arg fs the filesystem to make.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_open_windows_fs(casio_fs_t **fs)
{
return (0);
}
#endif

View File

@ -0,0 +1,169 @@
/* ****************************************************************************
* fs/builtin/windows/topath.c -- make a Windows path.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
*
* Based on this documentation:
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx
* ************************************************************************* */
#include "windows.h"
#include <ctype.h>
#ifndef LIBCASIO_DISABLED_WINDOWS
/**
* validate_name:
* Validate element name.
*
* We'll check that names respect the short name formats, also called the 8.3.
* Folder names are 8 max chars, and file names are 8 max chars of name
* plus 3 max chars of extensions.
*
* TODO: check for filesystems supporting long file names.
*
* @arg name the name.
* @arg size the name size.
* @arg flags the validation flags.
* @return if it is validated (0 if not).
*/
CASIO_LOCAL int validate_name(const char *name, size_t size,
unsigned int flags)
{
int i;
const char *nm;
/* Check the short format. */
i = 8; if (i >= size) i = size;
/* - Look for the dot marking the extension. */
for (; i >= 0 && name[i] != '.'; i--);
if (i < 0) {
/* No extension; check if the file is 8 chars or under. */
if (size > 8) return (casio_error_invalid);
} else {
/* Check if there is a dot after the limit for the extension. */
if (memchr(&name[i], '.', size - i)) return (casio_error_invalid);
/* Check if the extension is longer than 3 chars. */
if (size > i + 3) return (casio_error_invalid);
}
/* Look for reserved names. */
if (size == 3) {
if (!memcmp(name, "CON") || !memcmp(name, "PRN")
|| !memcmp(name, "AUX") || !memcmp(name, "NUL"))
return (0);
} else if (size == 4) {
if ((!memcmp(name, "COM") && name[3] >= '1' && name[3] <= '9')
|| (!memcmp(name, "LPT") && name[3] >= '1' && name[3] <= '8'))
return (0);
}
/* Look for reserved characters. */
for (i = size; i; i--, name++) {
if (*name < 0x20 || memchr("<>:\"/\\|?*", *name, 9))
return (0);
}
/* We're good! */
return (1);
}
/**
* casio_make_windows_path:
* Make a Windows path.
*
* @arg cookie the filesystem cookie (unused).
* @arg ppath the native path to make.
* @arg array the abstract path.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_make_windows_path(void *cookie,
void *ppath, casio_path_t *array)
{
size_t length = 0;
char *path;
casio_pathnode_t *node;
if (array->casio_path_device) {
if (array->casio_path_device[1]
|| !isupper(array->casio_path_device[0]))
return (casio_error_invalid);
length += 2; /* <drive letter>: */
}
if (~array->casio_path_flags & casio_pathflag_rel)
length++; /* initial backslash */
node = array->casio_path_nodes;
if (!node) return (casio_error_invalid);
while (node) {
if (!validate_name(node->casio_pathnode_name,
node->casio_pathnode_size))
return (casio_error_invalid);
length += node->casio_pathnode_size;
node = node->casio_pathnode_size;
if (node) length++; /* '\\' */
if (length > 259)
return (casio_error_invalid);
}
/* Allocate the path. */
*ppath = casio_alloc(length + 1, 1);
path = *ppath; if (!path) return (casio_error_alloc);
/* Fill the path. */
if (array->casio_path_device) {
*path++ = array->casio_path_device[0];
*path++ = ':';
}
if (~array->casio_path_flags & casio_pathflag_rel)
*path++ = '\\';
node = array->casio_path_nodes;
while (node) {
size_t nodesize = node->casio_pathnode_size;
memcpy(path, node->casio_pathnode_name, nodesize);
path += nodesize;
node = node->casio_pathnode_next;
if (node) *path++ = '\\';
}
*path = 0;
return (0);
}
/**
* casio_free_windows_path:
* Free a Windows path.
*
* @arg cookie the filesystem cookie (unused).
* @arg path the native path to free.
*/
void CASIO_EXPORT casio_free_windows_path(void *cookie,
void *native_path)
{
(void)cookie;
free(native_path);
}
#endif

View File

@ -0,0 +1,33 @@
/* ****************************************************************************
* fs/builtin/windows/windows.h -- Windows filesystem internals.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#ifndef LOCAL_FS_BUILTIN_WINDOWS_H
# define LOCAL_FS_BUILTIN_WINDOWS_H 1
# include "../../../internals.h"
# ifndef LIBCASIO_DISABLED_WINDOWS
/* Path conversions. */
CASIO_EXTERN int CASIO_EXPORT casio_make_windows_path
OF((void *casio__cookie, void **casio__native_path,
casio_path_t *casio__array));
CASIO_EXTERN void CASIO_EXPORT casio_free_windows_path
OF((void *casio__cookie, void *casio__native_path));
# endif
#endif /* LOCAL_FS_BUILTIN_WINDOWS_H */

69
src/fs/delete.c Normal file
View File

@ -0,0 +1,69 @@
/* ****************************************************************************
* fs/delete.c -- delete an element from a libcasio filesystem.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "fs.h"
/**
* casio_delete:
* Delete from a filesystem, using a native path.
*
* @arg fs the filesystem.
* @arg nat the native path.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_delete(casio_fs_t *fs, void *path)
{
int err; casio_fs_del_t *delete;
/* Get the callback. */
delete = fs->casio_fs_funcs.casio_fsfuncs_del;
if (!delete) return (casio_error_op);
/* Make the operation. */
err = (*delete)(fs->casio_fs_cookie, path);
return (err);
}
/**
* casio_delete_path:
* Delete from a filesystem, using an abstract path.
*
* @arg fs the filesystem.
* @arg path the abstract path.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_delete_path(casio_fs_t *fs, casio_path_t *path)
{
int err; void *nat;
casio_fs_del_t *delete;
/* Get the function. */
delete = fs->casio_fs_funcs.casio_fsfuncs_del;
if (!delete) return (casio_error_op);
/* Make the native path. */
err = casio_make_native_path(fs, &nat, path);
if (err) return (err);
/* Make the operation. */
err = (*delete)(fs->casio_fs_cookie, nat);
casio_free_native_path(fs, nat);
return (err);
}

View File

@ -20,9 +20,9 @@
# define LOCAL_FS_H 1
# include "../internals.h"
struct casio_filesystem_s {
void *casio_filesystem_cookie;
casio_fsfuncs_t casio_filesystem_functions;
struct casio_fs_s {
void *casio_fs_cookie;
casio_fsfuncs_t casio_fs_funcs;
};
#endif /* LOCAL_FS_H */

View File

@ -1,5 +1,5 @@
/* ****************************************************************************
* fs/path.c -- make a directory on a libcasio filesystem.
* fs/makedir.c -- make a directory on a libcasio filesystem.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
@ -20,28 +20,51 @@
/**
* casio_makedir:
* Make a directory.
* Make a directory using a native path.
*
* @arg fs the filesystem.
* @arg path the path of the directory to make.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_makedir(casio_filesystem_t *fs, casio_path_t *path)
int CASIO_EXPORT casio_makedir(casio_fs_t *fs, void *path)
{
casio_fs_makedir_t *makedir;
int err;
/* Get the callback. */
makedir = fs->casio_fs_funcs.casio_fsfuncs_makedir;
if (!makedir) return (casio_error_op);
/* Make the operation. */
err = (*makedir)(fs->casio_fs_cookie, path);
return (err);
}
/**
* casio_makedir_path:
* Make a directory using an abstract path.
*
* @arg fs the filesystem.
* @arg path the path of the directory to make.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_makedir_path(casio_fs_t *fs, casio_path_t *path)
{
casio_fs_makedir_t *makedir;
int err; void *nat = NULL;
/* Get the callback. */
makedir = fs->casio_filesystem_functions.casio_fsfuncs_makedir;
makedir = fs->casio_fs_funcs.casio_fsfuncs_makedir;
if (!makedir) return (casio_error_op);
/* Get the native path. */
err = casio_make_native_path(fs, &nat, path);
if (err) return (err);
/* Make the directory, free the native path, return. */
err = (*makedir)(fs->casio_filesystem_cookie, nat);
/* Make the directory. */
err = (*makedir)(fs->casio_fs_cookie, nat);
casio_free_native_path(fs, nat);
return (err);
}

View File

@ -28,18 +28,18 @@
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_open_fs(casio_filesystem_t **pfs,
int CASIO_EXPORT casio_open_fs(casio_fs_t **pfs,
void *cookie, const casio_fsfuncs_t *funcs)
{
int err; casio_filesystem_t *fs;
int err; casio_fs_t *fs;
/* Allocate the filesystem. */
*pfs = malloc(sizeof(casio_filesystem_t)); fs = *pfs;
*pfs = malloc(sizeof(casio_fs_t)); fs = *pfs;
if (!fs) { err = casio_error_alloc; goto fail; }
/* Copy the data into it. */
fs->casio_filesystem_cookie = cookie;
memcpy(&fs->casio_filesystem_functions, funcs, sizeof(casio_fsfuncs_t));
fs->casio_fs_cookie = cookie;
memcpy(&fs->casio_fs_funcs, funcs, sizeof(casio_fsfuncs_t));
return (0);
fail:

View File

@ -28,17 +28,17 @@
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_make_native_path(casio_filesystem_t *fs,
int CASIO_EXPORT casio_make_native_path(casio_fs_t *fs,
void **nat, casio_path_t *path)
{
casio_fs_makepath_t *makepath;
/* Get the callback. */
makepath = fs->casio_filesystem_functions.casio_fsfuncs_makepath;
makepath = fs->casio_fs_funcs.casio_fsfuncs_makepath;
if (!makepath) return (casio_error_op);
/* Make the native path. */
return ((*makepath)(fs->casio_filesystem_cookie, nat, path));
return ((*makepath)(fs->casio_fs_cookie, nat, path));
}
/**
@ -49,14 +49,14 @@ int CASIO_EXPORT casio_make_native_path(casio_filesystem_t *fs,
* @arg nat the native path to free.
*/
void CASIO_EXPORT casio_free_native_path(casio_filesystem_t *fs, void *nat)
void CASIO_EXPORT casio_free_native_path(casio_fs_t *fs, void *nat)
{
casio_fs_freepath_t *freepath;
/* Get the callback. */
freepath = fs->casio_filesystem_functions.casio_fsfuncs_freepath;
freepath = fs->casio_fs_funcs.casio_fsfuncs_freepath;
if (!freepath) return ;
/* Free the native path. */
(*freepath)(fs->casio_filesystem_cookie, nat);
(*freepath)(fs->casio_fs_cookie, nat);
}

View File

@ -0,0 +1,51 @@
/* ****************************************************************************
* link/seven_fs/delete.c -- delete an element from a Protocol 7.00 filesystem.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "seven_fs.h"
/**
* casio_sevenfs_delete:
* Delete a file from a Protocol 7.00 filesystem.
*
* @arg cookie the cookie.
* @arg path the path.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_sevenfs_delete(sevenfs_cookie_t *cookie,
sevenfs_path_t *path)
{
int err; casio_link_t *handle = cookie;
const char *dir, *file, *dev;
/* Make the vars. */
dir = path->sevenfs_path_dir == 0xFF ? NULL
: &path->sevenfs_path_data[path->sevenfs_path_dir];
file = &path->sevenfs_path_data[path->sevenfs_path_file];
dev = &path->sevenfs_path_data[path->sevenfs_path_dev];
msg((ll_info, "Sending the deletion command."));
err = casio_seven_send_cmdfls_delfile(handle, dir, file, dev);
if (err) return (err);
if (response.casio_seven_packet_type == casio_seven_type_nak)
return (casio_error_notfound);
if (response.casio_seven_packet_type != casio_seven_type_ack)
return (casio_error_unknown);
return (0);
}

45
src/link/seven_fs/open.c Normal file
View File

@ -0,0 +1,45 @@
/* ****************************************************************************
* link/seven_fs/open.c -- open a Protocol 7.00 filesystem.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "seven_fs.h"
/* Callbacks. */
CASIO_LOCAL casio_fsfuncs_t sevenfs_callbacks = {
NULL,
(casio_fs_makepath_t*)&casio_make_sevenfs_path,
(casio_fs_freepath_t*)&casio_free_sevenfs_path,
NULL, NULL,
(casio_fs_del_t*)&casio_sevenfs_delete,
NULL, NULL, NULL
};
/**
* casio_open_seven_fs:
* Open a Protocol 7.00 filesystem.
*
* @arg fs the filesystem to open.
* @arg link the link above which to access the file system.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_open_seven_fs(casio_fs_t **fs,
casio_link_t *link)
{
/* Open the filesystem. (no need for cookie allocating for now) */
return (casio_open_fs(fs, link, &sevenfs_callbacks));
}

View File

@ -0,0 +1,49 @@
/* ****************************************************************************
* link/seven_fs/seven_fs.h -- Protocol 7.00 filesystem internals.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#ifndef LOCAL_LINK_SEVEN_FS_H
# define LOCAL_LINK_SEVEN_FS_H 1
# include "../usage/usage.h"
/* The cookie is the `casio_link_t` pointer. */
typedef casio_link_t sevenfs_cookie_t;
/* Native "path" management.
* This structure will probably not be allocated every time. */
typedef struct {
unsigned char sevenfs_path_dir;
unsigned char sevenfs_path_file;
unsigned char sevenfs_path_dev;
unsigned char sevenfs_path__align;
char sevenfs_path_data[24];
} sevenfs_path_t;
CASIO_EXTERN int CASIO_EXPORT casio_make_sevenfs_path
OF((sevenfs_cookie_t *casio__cookie, sevenfs_path_t **casio__native_path,
casio_path_t *casio__path));
CASIO_EXTERN void CASIO_EXPORT casio_free_sevenfs_path
OF((sevenfs_cookie_t *casio__cookie, sevenfs_path_t *casio__native_path));
/* Delete a file. */
CASIO_EXTERN int CASIO_EXPORT casio_sevenfs_delete
OF((sevenfs_cookie_t *casio__cookie, sevenfs_path_t *casio__path));
#endif /* LOCAL_LINK_SEVEN_FS_H */

106
src/link/seven_fs/topath.c Normal file
View File

@ -0,0 +1,106 @@
/* ****************************************************************************
* link/seven_fs/topath.c -- make a Protocol 7.00 filesystem "native" path.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "seven_fs.h"
/**
* casio_make_sevenfs_path:
* Make a Protocol 7.00 filesystem native path.
*
* @arg cookie the cookie (unused).
* @arg ppath the path to make.
* @arg array the path array.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_make_sevenfs_path(sevenfs_cookie_t *cookie,
sevenfs_path_t **ppath, casio_path_t *array)
{
sevenfs_path_t *path;
const char *dirname, *filename;
size_t dirsz, filesz;
char *data; int off;
casio_pathnode_t *node;
/* Check the device. */
if (!memcmp(array->casio_path_device, "fls0", 4)
|| !memcmp(array->casio_path_device, "crd0", 4))
return (casio_error_invalid);
/* Get directory name and file name. */
if (!array->casio_path_nodes)
return (casio_error_invalid);
node = array->casio_path_nodes;
if (!node) return (casio_error_invalid);
if (node->casio_pathnode_next) {
dirsz = node->casio_pathnode_size + 1;
if (dirsz == 1 || dirsz > 9) return (casio_error_invalid);
dirname = (const char*)node->casio_pathnode_name;
node = node->casio_pathnode_next;
} else {
dirname = NULL;
dirsz = 0;
}
if (node->casio_pathnode_next) {
/* too deep! */
return (casio_error_invalid);
}
filesz = node->casio_pathnode_size + 1;
if (filesz == 1 || filesz > 9) return (casio_error_invalid);
filename = (const char*)node->casio_pathnode_name;
/* Make the node. */
*ppath = casio_alloc(offsetof(sevenfs_path_t, sevenfs_path_data)
+ 4 + dirsz + filesz, 1);
path = *ppath; if (!path) return (casio_error_alloc);
/* Copy the data into the node. */
data = path->sevenfs_path_data; off = 0;
if (dirname) {
memcpy(data, dirname, dirsz - 1);
data[dirsz - 1] = 0;
path->sevenfs_path_dir = off;
data += dirsz; off += dirsz;
} else
path->sevenfs_path_dir = 0xFF;
memcpy(data, filename, filesz - 1);
data[filesz - 1] = 0;
path->sevenfs_path_file = off;
data += filesz; off += filesz;
memcpy(data, array->casio_path_device, 3);
data[3] = 0;
path->sevenfs_path_dev = off;
/* No error! */
return (0);
}
/**
* casio_free_sevenfs_path:
* Free a Protocol 7.00 filesystem path.
*
* @arg cookie the cookie (unused).
* @arg path the native path.
*/
void CASIO_EXPORT casio_free_sevenfs_path(sevenfs_cookie_t *cookie,
sevenfs_path_t *path)
{
(void)cookie;
free(path);
}