diff --git a/include/libcasio/stream.h b/include/libcasio/stream.h index 5a94c05..77feebb 100644 --- a/include/libcasio/stream.h +++ b/include/libcasio/stream.h @@ -100,7 +100,7 @@ typedef int casio_stream_setattrs_t typedef int casio_stream_settm_t OF((void *, const casio_timeouts_t *)); -typedef int casio_stream_read_t +typedef size_t casio_stream_read_t OF((void *, unsigned char *, size_t)); typedef int casio_stream_write_t OF((void *, const unsigned char *, size_t)); @@ -359,7 +359,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_get_lasterr /* Read and write data from and to a stream. */ -CASIO_EXTERN int CASIO_EXPORT casio_read +CASIO_EXTERN size_t CASIO_EXPORT casio_read OF((casio_stream_t *casio__stream, void *casio__dest, size_t casio__size)); CASIO_EXTERN int CASIO_EXPORT casio_write diff --git a/lib/file/file.h b/lib/file/file.h index f818d3d..ec14301 100644 --- a/lib/file/file.h +++ b/lib/file/file.h @@ -29,12 +29,14 @@ # define READ(CASIO__TO, CASIO__SZ) /* normal read */ { \ int READ_err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)); \ - if (READ_err) return (READ_err); } -# define FREAD(CASIO__TO, CASIO__SZ) /* fail-less read */ \ - err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)); -# define GREAD(CASIO__TO, CASIO__SZ) /* read with goto fail */ \ - if ((err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)))) \ - goto fail; + if (READ_err == -1) return (errno); } +# define FREAD(CASIO__TO, CASIO__SZ) /* fail-less read */ { \ + casio_read(buffer, (CASIO__TO), (CASIO__SZ)); \ + err = errno; } +# define GREAD(CASIO__TO, CASIO__SZ) /* read with goto fail */ { \ + casio_read(buffer, (CASIO__TO), (CASIO__SZ)); \ + if ((err = errno)) \ + goto fail; } /* Read using size of the object. */ diff --git a/lib/internals.h b/lib/internals.h index 2823301..de00678 100644 --- a/lib/internals.h +++ b/lib/internals.h @@ -26,6 +26,7 @@ # include # include # include +# include # include "utils/endian.h" # include "log/log.h" diff --git a/lib/link/seven/dataflow.c b/lib/link/seven/dataflow.c index 3286976..ab158df 100644 --- a/lib/link/seven/dataflow.c +++ b/lib/link/seven/dataflow.c @@ -64,8 +64,10 @@ int CASIO_EXPORT casio_seven_send_buffer(casio_link_t *handle, /* Read the big block. */ toread = min(BUFSIZE, size); - err = casio_read(buffer, buf + 8, toread); - if (err) return (casio_error_noread); + toread = casio_read(buffer, buf + 8, toread); + if (toread == (size_t)-1) { + return (casio_error_noread); + } size -= toread; /* Send each block. */ @@ -95,7 +97,7 @@ int CASIO_EXPORT casio_seven_send_buffer(casio_link_t *handle, /* Unshift. */ if (handle->casio_link_flags & casio_linkflag_shifted) err = casio_seven_unshift(handle); - + return (0); fail: return (err); } diff --git a/lib/link/seven/datastream.c b/lib/link/seven/datastream.c index 2ffc850..ea8ef2c 100644 --- a/lib/link/seven/datastream.c +++ b/lib/link/seven/datastream.c @@ -51,15 +51,16 @@ typedef struct { * @arg cookie the cookie. * @arg data the data to read. * @arg size the size of the data to read. - * @return the error code (0 if ok). + * @return the size written and -1 if error (error code is in errno). */ -CASIO_LOCAL int casio_seven_data_read(seven_data_cookie_t *cookie, +CASIO_LOCAL size_t casio_seven_data_read(seven_data_cookie_t *cookie, unsigned char *data, size_t size) { int err; size_t tocopy; casio_link_t *handle = cookie->_link; - unsigned int lastsize; + unsigned int lastsize = 0; + size_t copiedsize = 0; /* Check if the stream is faulty. */ if (cookie->_faulty) @@ -71,20 +72,26 @@ CASIO_LOCAL int casio_seven_data_read(seven_data_cookie_t *cookie, if (tocopy) { memcpy(data, &cookie->_current[cookie->_pos], tocopy); cookie->_pos += tocopy; - data += tocopy; size -= tocopy; + data += tocopy; size -= tocopy; copiedsize += tocopy; - if (!size) return (0); + if (size == 0) return (size); } /* Check if we have already finished. */ - if (cookie->_total && cookie->_id == cookie->_total) - return (casio_error_eof); + if (cookie->_total && cookie->_id == cookie->_total) { + errno = casio_error_eof; + return (-1); + } /* Receive packets. */ while (size) { /* Send the ack and get the answer. */ err = casio_seven_send_ack(handle, 1); if (err) goto fail; + /* If swap roles there is the end of file */ + if (response.casio_seven_packet_type == casio_seven_type_swp) { + return copiedsize; + } if (response.casio_seven_packet_type != casio_seven_type_data) { msg((ll_error, "Packet wasn't a data packet, wtf?")); err = casio_error_unknown; @@ -111,6 +118,7 @@ CASIO_LOCAL int casio_seven_data_read(seven_data_cookie_t *cookie, /* Increment and copy. */ lastsize = response.casio_seven_packet_data_size; + copiedsize += lastsize; if (size >= lastsize) { memcpy(data, response.casio_seven_packet_data, lastsize); data += lastsize; size -= lastsize; @@ -122,14 +130,15 @@ CASIO_LOCAL int casio_seven_data_read(seven_data_cookie_t *cookie, memcpy(data, response.casio_seven_packet_data, size); memcpy(&cookie->_current[size], &response.casio_seven_packet_data[size], lastsize - size); - return (0); + return copiedsize; } - return (0); + return copiedsize; fail: /* XXX: tell the distant device we have a problem? */ cookie->_faulty = 1; - return (err); + errno = err; + return (-1); } /** diff --git a/lib/link/seven/receive.c b/lib/link/seven/receive.c index 109bf19..43754ad 100644 --- a/lib/link/seven/receive.c +++ b/lib/link/seven/receive.c @@ -176,8 +176,8 @@ CASIO_LOCAL const char *gettermstring(casio_seven_term_t code) #define buffer handle->casio_link_recv_buffer #define COMPLETE_PACKET(N) { \ int COMP_PACKET_err = casio_read(handle->casio_link_stream, \ - &buffer[received], (size_t)(N)); \ - received += (N); if (COMP_PACKET_err) return (COMP_PACKET_err); } + &buffer[received], (size_t)N); \ + received += COMP_PACKET_err; if (COMP_PACKET_err == -1) return (errno); } CASIO_LOCAL int casio_seven_decode(casio_link_t *handle, int scralign) { diff --git a/lib/link/seven/scsi.c b/lib/link/seven/scsi.c index fd3dfff..86ea65a 100644 --- a/lib/link/seven/scsi.c +++ b/lib/link/seven/scsi.c @@ -83,10 +83,11 @@ typedef struct { * Read and write from the stream. * --- */ -CASIO_LOCAL int seven_scsi_read(seven_scsi_cookie_t *cookie, +CASIO_LOCAL size_t seven_scsi_read(seven_scsi_cookie_t *cookie, unsigned char *buffer, size_t size) { casio_scsi_t scsi; int err; + size_t copiedsize = 0; /* Empty what's already in the buffer. */ @@ -95,12 +96,14 @@ CASIO_LOCAL int seven_scsi_read(seven_scsi_cookie_t *cookie, memcpy(buffer, cookie->ptr, size); cookie->ptr += size; cookie->left -= size; - return (0); + copiedsize += cookie->left; + return copiedsize; } memcpy(buffer, cookie->ptr, cookie->left); buffer += cookie->left; size -= cookie->left; + copiedsize += cookie->left; reset_cookie(cookie); } @@ -125,8 +128,10 @@ CASIO_LOCAL int seven_scsi_read(seven_scsi_cookie_t *cookie, scsi.casio_scsi_data = poll_data; scsi.casio_scsi_data_len = 16; - if ((err = casio_scsi_request(cookie->stream, &scsi))) - return (err); + if ((err = casio_scsi_request(cookie->stream, &scsi))) { + errno = err; + return (-1); + } mem((ll_info, poll_data, 16)); @@ -176,8 +181,10 @@ CASIO_LOCAL int seven_scsi_read(seven_scsi_cookie_t *cookie, scsi.casio_scsi_data = cookie->ptr; scsi.casio_scsi_data_len = avail; - if ((err = casio_scsi_request(cookie->stream, &scsi))) - return (err); + if ((err = casio_scsi_request(cookie->stream, &scsi))) { + errno = err; + return (-1); + } } if (to == buffer) { @@ -189,11 +196,12 @@ CASIO_LOCAL int seven_scsi_read(seven_scsi_cookie_t *cookie, memcpy(buffer, cookie->ptr, size); cookie->ptr += size; cookie->left -= size; + copiedsize += size; size = 0; } } while (size); - return (0); + return copiedsize; } CASIO_LOCAL int seven_scsi_write(seven_scsi_cookie_t *cookie, diff --git a/lib/link/seven_fs/list.c b/lib/link/seven_fs/list.c index cc56876..fed50be 100644 --- a/lib/link/seven_fs/list.c +++ b/lib/link/seven_fs/list.c @@ -46,7 +46,7 @@ int CASIO_EXPORT casio_sevenfs_list(sevenfs_cookie_t *cookie, sevenfs_path_t *pa } else if (response.casio_seven_packet_type == casio_seven_type_nak && response.casio_seven_packet_code == casio_seven_err_other) { msg((ll_fatal, "Invalid filesystem")); - return (casio_error_device); // FIXME : unsupported device error + return (casio_error_device); } else if (response.casio_seven_packet_type != casio_seven_type_ack) { msg((ll_fatal, "Didn't receive ack or known error...")); return (casio_error_unknown); diff --git a/lib/link/seven_fs/open.c b/lib/link/seven_fs/open.c index f4bb649..6a82ab0 100644 --- a/lib/link/seven_fs/open.c +++ b/lib/link/seven_fs/open.c @@ -29,7 +29,7 @@ CASIO_LOCAL casio_fsfuncs_t sevenfs_callbacks = { (casio_fs_del_t*)&casio_sevenfs_delete, NULL, (casio_fs_list_t*)&casio_sevenfs_list, - NULL, + (casio_fs_open_t*)&casio_sevenfs_open, (casio_fs_optim_t*)&casio_sevenfs_optimize }; @@ -48,3 +48,182 @@ int CASIO_EXPORT casio_open_seven_fs(casio_fs_t **fs, /* Open the filesystem. (no need for cookie allocating for now) */ return (casio_open_fs(fs, link, &sevenfs_callbacks)); } + +/** + * casio_sevenfs_open_read + * Open a file in read mode + * + * @arg cookie the sevenfs cookie + * @arg path the path to th file + * @arg stream pointer to a pointer who contain the stream + */ + +CASIO_LOCAL int casio_sevenfs_open_read(sevenfs_cookie_t *cookie, sevenfs_path_t *path, + casio_stream_t **stream) +{ + casio_link_t *handle = cookie; int err; + char *dirname = (path->sevenfs_path_dir != 0xFF) ? &path->sevenfs_path_data[path->sevenfs_path_dir] : NULL; + char *filename = &path->sevenfs_path_data[path->sevenfs_path_file]; + char *devname = &path->sevenfs_path_data[path->sevenfs_path_dev]; + + /* Make checks */ + chk_required_filename(filename); + chk_dirname(dirname); + chk_handle(handle); + chk_active(handle); + + + /* Send command packet */ + msg((ll_info, "Sending file transfer request")); + if ((err = casio_seven_send_cmdfls_reqfile(handle, dirname, filename, devname))) { + msg((ll_fatal, "Couldn't send file transfer request/didn't receive answer")); + return (err); + } + + /* Check response packet */ + if (response.casio_seven_packet_type == casio_seven_type_nak + && response.casio_seven_packet_code == casio_seven_err_other) { + msg((ll_fatal, "Requested file doesn't exist")); + err = casio_error_notfound; + return (err); + } else if (response.casio_seven_packet_type != casio_seven_type_ack) { + msg((ll_fatal, "Didn't receive ack or known error...")); + return (casio_error_unknown); + } + + /* Send swap roles */ + msg((ll_info, "Sending roleswap")); + if ((err = casio_seven_send_roleswp(handle))) + { + msg((ll_fatal, "Couldn't swap roles")); + return (err); + } else if (response.casio_seven_packet_type != casio_seven_type_cmd + || response.casio_seven_packet_code != 0x45) + { + msg((ll_fatal, "Didn't receive the excepted command")); + return (casio_error_unknown); + } + + return casio_seven_open_data_stream(stream, handle, response.casio_seven_packet_filesize, NULL, NULL); +} + +/** + * casio_sevenfs_open_write + * Open a file in write mode + * + * @arg cookie the sevenfs cookie + * @arg path the path to th file + * @arg size size of the file + * @arg stream pointer to a pointer who contain the stream + * @return the error (0 if okey) + */ + +CASIO_LOCAL int casio_sevenfs_open_write(sevenfs_cookie_t *cookie, sevenfs_path_t *path, + casio_off_t size, casio_stream_t **stream) +{ + casio_link_t *handle = cookie; int err; + char *dirname = &path->sevenfs_path_data[path->sevenfs_path_dir]; + char *filename = &path->sevenfs_path_data[path->sevenfs_path_file]; + char *devname = &path->sevenfs_path_data[path->sevenfs_path_dev]; + + /* Make checks */ + chk_required_filename(filename); + chk_dirname(dirname); + chk_handle(handle); + chk_active(handle); + + return (0); + +} + +/** + * casio_sevenfs_open: + * Open a file. + * + * @arg cookie the sevenfs cookie + * @arg path the path to the file + * @arg size size of the file if WRITE (NULL if READ) + * @arg mode the open mode + * @arg stream pointer to a pointer who contain the stream + * @return the error (0 if okey) + */ + +int CASIO_EXPORT casio_sevenfs_open(sevenfs_cookie_t *cookie, sevenfs_path_t *path, + casio_off_t size, casio_openmode_t mode, casio_stream_t **stream) +{ + casio_link_t *handle = cookie; int err; + char *dirname = &path->sevenfs_path_data[path->sevenfs_path_dir]; + char *filename = &path->sevenfs_path_data[path->sevenfs_path_file]; + char *devname = &path->sevenfs_path_data[path->sevenfs_path_dev]; + + /* Make checks (not really required) */ + chk_required_filename(filename); + chk_dirname(dirname); + chk_handle(handle); + chk_active(handle); + + if ((mode & CASIO_OPENMODE_WRITE)) + { + + } else if ((mode & CASIO_OPENMODE_READ)) + { + return (casio_sevenfs_open_read(cookie, path, stream)); + } + +#if 0 + /* Send command packet */ + msg((ll_info, "Sending file transfer request")); + if ((err = casio_seven_send_cmdfls_reqfile(handle, dirname, filename, devname))) { + msg((ll_fatal, "Couldn't send file transfer request/didn't receive answer")); + return (err); + } + + /* Check response */ + if (response.casio_seven_packet_type == casio_seven_type_nak + && response.casio_seven_packet_code == casio_seven_err_other) + { + /* If file doesn't exist and we want read : error */ + if ((mode & CASIO_OPENMODE_READ)) { + msg((ll_fatal, "Requested file doesn't exist")); + return (casio_error_notfound); + } + } else if (response.casio_seven_packet_type != casio_seven_type_ack) { + msg((ll_fatal, "Didn't receive ack or known error...")); + return (casio_error_unknown); + } + + + /* Check what happened if it is an error packet */ + if (response.casio_seven_packet_type == casio_seven_type_nak) + { + switch (response.casio_seven_packet_type) + { + + /* Calc need overwrite confirmation */ + case casio_seven_err_overwrite: + + break; + + /* Calc denie overwrite or err other */ + case casio_seven_err_dont_overwrite: + case casio_seven_err_other: + msg((ll_error, "Overwrite impossible")); + err = casio_error_device; + return (err); + break; + + /* Memory full */ + case casio_seven_err_fullmem: + msg((ll_error, "Calc mem is full")); + err = casio_error_fullmem; + return (err); + break; + + /* stfu warning */ + case casio_seven_err_resend: break; + } + } + + msg((ll_info, "WE CAN")); +#endif +} diff --git a/lib/link/seven_fs/seven_fs.h b/lib/link/seven_fs/seven_fs.h index f11e001..0b2f7f7 100644 --- a/lib/link/seven_fs/seven_fs.h +++ b/lib/link/seven_fs/seven_fs.h @@ -57,4 +57,10 @@ CASIO_EXTERN int CASIO_EXPORT casio_sevenfs_list OF((sevenfs_cookie_t *casio__cookie, sevenfs_path_t *casio__path, casio_fs_list_func_t *casio__callback, void *casio__cbcookie)); +/* Open a stream with a casio fs file */ + +CASIO_EXTERN int CASIO_EXPORT casio_sevenfs_open + OF((sevenfs_cookie_t *casio__cookie, sevenfs_path_t *casio__path, + casio_off_t casio__size, casio_openmode_t casio__mode, casio_stream_t **casio__stream)); + #endif /* LOCAL_LINK_SEVEN_FS_H */ diff --git a/lib/link/seven_fs/topath.c b/lib/link/seven_fs/topath.c index 826eedd..59e4498 100644 --- a/lib/link/seven_fs/topath.c +++ b/lib/link/seven_fs/topath.c @@ -53,7 +53,7 @@ int CASIO_EXPORT casio_make_sevenfs_path(sevenfs_cookie_t *cookie, 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); + if (dirsz == 1 || dirsz > 13) return (casio_error_invalid); dirname = (const char*)node->casio_pathnode_name; node = node->casio_pathnode_next; } else { @@ -66,7 +66,7 @@ int CASIO_EXPORT casio_make_sevenfs_path(sevenfs_cookie_t *cookie, return (casio_error_invalid); } filesz = node->casio_pathnode_size + 1; - if (filesz == 1 || filesz > 9) return (casio_error_invalid); + if (filesz == 1 || filesz > 13) return (casio_error_invalid); filename = (const char*)node->casio_pathnode_name; /* Make the node. */ diff --git a/lib/mcsfile/mcsfile.h b/lib/mcsfile/mcsfile.h index 336751f..8d68e99 100644 --- a/lib/mcsfile/mcsfile.h +++ b/lib/mcsfile/mcsfile.h @@ -28,12 +28,14 @@ # define READ(CASIO__TO, CASIO__SZ) /* normal read */ { \ int READ_err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)); \ - if (READ_err) return (READ_err); } -# define FREAD(CASIO__TO, CASIO__SZ) /* fail-less read */ \ - err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)); -# define GREAD(CASIO__TO, CASIO__SZ) /* read with goto fail */ \ - if ((err = casio_read(buffer, (CASIO__TO), (CASIO__SZ)))) \ - goto fail; + if (READ_err == -1) return (errno); } +# define FREAD(CASIO__TO, CASIO__SZ) /* fail-less read */ { \ + casio_read(buffer, (CASIO__TO), (CASIO__SZ)); \ + err = errno; } +# define GREAD(CASIO__TO, CASIO__SZ) /* read with goto fail */ { \ + casio_read(buffer, (CASIO__TO), (CASIO__SZ)); \ + if ((err = errno)) \ + goto fail; } /* Read using size of the object. */ diff --git a/lib/stream/builtin/csum32.c b/lib/stream/builtin/csum32.c index a071582..3e3a439 100644 --- a/lib/stream/builtin/csum32.c +++ b/lib/stream/builtin/csum32.c @@ -38,23 +38,26 @@ struct thecookie { * @arg cookie the cookie. * @arg data the data pointer. * @arg size the data size. - * @return the error code (0 if ok). + * @return the size written and -1 if error (error code is in errno). */ -CASIO_LOCAL int csum32_read(struct thecookie *cookie, +CASIO_LOCAL size_t csum32_read(struct thecookie *cookie, unsigned char *dest, size_t size) { int err; /* Make the call. */ - err = casio_read(cookie->_stream, dest, size); - if (err) return (err); + size = casio_read(cookie->_stream, dest, size); + if (size == (size_t)-1) { + errno = errno; + return (-1); + } /* Make the checksum. */ *cookie->_checksum = casio_checksum32(dest, size, *cookie->_checksum); - return (0); + return size; } /** diff --git a/lib/stream/builtin/file.c b/lib/stream/builtin/file.c index 50c9188..b3deb5d 100644 --- a/lib/stream/builtin/file.c +++ b/lib/stream/builtin/file.c @@ -46,13 +46,14 @@ typedef struct { * @arg cookie the cookie. * @arg data the data pointer * @arg size the data size. - * @return the error code (0 if ok). + * @return the size written and -1 if error (error code is in errno). */ -CASIO_LOCAL int casio_file_read(file_cookie_t *cookie, +CASIO_LOCAL size_t casio_file_read(file_cookie_t *cookie, unsigned char *dest, size_t size) { size_t recv; + size_t copiedsize = 0; /* Main receiving loop. */ @@ -66,6 +67,7 @@ CASIO_LOCAL int casio_file_read(file_cookie_t *cookie, dest = (void*)((char*)dest + recv); size -= recv; + copiedsize += recv; /* Check the error. */ @@ -90,7 +92,8 @@ CASIO_LOCAL int casio_file_read(file_cookie_t *cookie, /* End of file. */ msg((ll_error, "encountered an end of file")); - return (casio_error_eof); + errno = casio_error_eof; + return (-1); case EINTR: /* alarm */ case ETIMEDOUT: @@ -100,21 +103,24 @@ CASIO_LOCAL int casio_file_read(file_cookie_t *cookie, /* A timeout has occurred. */ msg((ll_error, "timeout received")); - return (casio_error_timeout); + errno = casio_error_timeout; + return (-1); case ENODEV: case EPIPE: case ESPIPE: /* A device error has occured. */ msg((ll_error, "calculator was disconnected")); - return (casio_error_nocalc); + errno = casio_error_nocalc; + return (-1); default: msg((ll_fatal, "errno was %d: %s", errno, strerror(errno))); - return (casio_error_unknown); + errno = casio_error_unknown; + return (-1); } - return (0); + return copiedsize; } /** diff --git a/lib/stream/builtin/libusb/libusb.h b/lib/stream/builtin/libusb/libusb.h index b3cad60..75196b9 100644 --- a/lib/stream/builtin/libusb/libusb.h +++ b/lib/stream/builtin/libusb/libusb.h @@ -58,7 +58,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_libusb_settm /* Character device callbacks. */ -CASIO_EXTERN int CASIO_EXPORT casio_libusb_read +CASIO_EXTERN size_t CASIO_EXPORT casio_libusb_read OF((cookie_libusb_t *casio__cookie, unsigned char *casio__dest, size_t casio__size)); CASIO_EXTERN int CASIO_EXPORT casio_libusb_write diff --git a/lib/stream/builtin/libusb/read.c b/lib/stream/builtin/libusb/read.c index 34d727f..9859394 100644 --- a/lib/stream/builtin/libusb/read.c +++ b/lib/stream/builtin/libusb/read.c @@ -26,14 +26,15 @@ * @arg vcookie the cookie (voided) * @arg data the data pointer. * @arg size the data size. - * @return the error code (0 if ok). + * @return the size written and -1 if error (error code is in errno). */ -int CASIO_EXPORT casio_libusb_read(cookie_libusb_t *cookie, +size_t CASIO_EXPORT casio_libusb_read(cookie_libusb_t *cookie, unsigned char *dest, size_t size) { int libusberr; size_t tocopy; + size_t copiedsize = 0; /* Transmit what's already in the buffer. */ @@ -45,6 +46,7 @@ int CASIO_EXPORT casio_libusb_read(cookie_libusb_t *cookie, cookie->_start += tocopy; dest += tocopy; size -= tocopy; + copiedsize += tocopy; } /* Main receiving loop. */ @@ -64,15 +66,18 @@ int CASIO_EXPORT casio_libusb_read(cookie_libusb_t *cookie, case LIBUSB_ERROR_NO_DEVICE: case LIBUSB_ERROR_IO: msg((ll_error, "The calculator is not here anymore :(")); - return (casio_error_nocalc); + errno = casio_error_nocalc; + return (-1); case LIBUSB_ERROR_TIMEOUT: - return (casio_error_timeout); + errno = casio_error_timeout; + return (-1); default: msg((ll_fatal, "libusb error was %d: %s", libusberr, libusb_strerror(libusberr))); - return (casio_error_unknown); + errno = casio_error_unknown; + return (-1); } /* Get the current size to copy. */ @@ -87,13 +92,17 @@ int CASIO_EXPORT casio_libusb_read(cookie_libusb_t *cookie, dest += tocopy; size -= tocopy; + /* Increment the total copied size */ + + copiedsize += tocopy; + /* Correct start and end points. */ cookie->_start = tocopy; cookie->_end = (size_t)recv - 1; } - return (0); + return copiedsize; } #endif diff --git a/lib/stream/builtin/limited.c b/lib/stream/builtin/limited.c index 6b847bf..d07a84d 100644 --- a/lib/stream/builtin/limited.c +++ b/lib/stream/builtin/limited.c @@ -37,35 +37,39 @@ typedef struct { * @arg vcookie the cookie (uncasted). * @arg data the data pointer. * @arg size the data size. - * @return the error code (0 if ok). + * @return the size written and -1 if error (error code is in errno). */ -CASIO_LOCAL int casio_limited_read(void *vcookie, unsigned char *dest, +CASIO_LOCAL size_t casio_limited_read(void *vcookie, unsigned char *dest, size_t size) { int err; limited_cookie_t *cookie = (void*)vcookie; - size_t left; + size_t left; size_t copiedsize; if (size > cookie->_left) { /* First, skip the required bytes. */ left = cookie->_left; cookie->_left = 0; - if ((err = casio_skip(cookie->_stream, left))) - return (err); + if ((err = casio_skip(cookie->_stream, left))) { + errno = err; + return (-1); + } /* Once the skip is done successfully, we return that we * have an EOF. */ - - return (casio_error_eof); + errno = casio_error_eof; + return (-1); } - if ((err = casio_read(cookie->_stream, dest, size))) { + size = casio_read(cookie->_stream, dest, size); + if (size == (size_t)-1) { cookie->_left = 0; /* XXX: depends on the error? */ - return (err); + errno = errno; + return (-1); } cookie->_left -= size; - return (0); + return size; } /** diff --git a/lib/stream/builtin/memory.c b/lib/stream/builtin/memory.c index ea4936c..33fa8e6 100644 --- a/lib/stream/builtin/memory.c +++ b/lib/stream/builtin/memory.c @@ -35,24 +35,27 @@ typedef struct { * @arg vcookie the cookie (uncasted) * @arg data the data pointer. * @arg size the data size. - * @return the error code (0 if ok). + * @return the size written and -1 if error (error code is in errno). */ -CASIO_LOCAL int casio_memory_read(void *vcookie, unsigned char *dest, size_t size) +CASIO_LOCAL size_t casio_memory_read(void *vcookie, unsigned char *dest, size_t size) { memory_cookie_t *cookie = (void*)vcookie; - if (((size_t)-1 - cookie->_offset) < size) /* overflow */ - return (casio_error_read); + if (((size_t)-1 - cookie->_offset) < size) { /* overflow */ + errno = casio_error_read; + return (-1); + } if (cookie->_offset + (casio_off_t)size > cookie->_size) { cookie->_offset = cookie->_size - 1; - return (casio_error_eof); + errno = casio_error_eof; + return (-1); } memcpy(dest, &cookie->_memory[cookie->_offset], size); cookie->_offset += size; - return (0); + return size; } /** diff --git a/lib/stream/builtin/streams/read.c b/lib/stream/builtin/streams/read.c index 74e86e0..2f61377 100644 --- a/lib/stream/builtin/streams/read.c +++ b/lib/stream/builtin/streams/read.c @@ -26,13 +26,14 @@ * @arg cookie the cookie. * @arg data the data pointer. * @arg size the data size. - * @return the error code (0 if ok). + * @return the size written and -1 if error (error code is in errno). */ -int CASIO_EXPORT casio_streams_read(streams_cookie_t *cookie, +size_t CASIO_EXPORT casio_streams_read(streams_cookie_t *cookie, unsigned char *dest, size_t size) { int fd = cookie->_readfd; + size_t copiedsize = 0; /* Transmit what's already in the buffer. */ @@ -44,6 +45,7 @@ int CASIO_EXPORT casio_streams_read(streams_cookie_t *cookie, cookie->_start += tocopy; dest += tocopy; size -= tocopy; + copiedsize += tocopy; } /* Main receiving loop. */ @@ -67,7 +69,8 @@ int CASIO_EXPORT casio_streams_read(streams_cookie_t *cookie, default: msg((ll_fatal, "error was %d: %s", errno, strerror(errno))); - return (casio_error_unknown); + errno = casio_error_unknown; + return (-1); } /* Get the current size to copy. */ @@ -81,13 +84,17 @@ int CASIO_EXPORT casio_streams_read(streams_cookie_t *cookie, dest += tocopy; size -= tocopy; + /* Increment total size copied */ + + copiedsize += tocopy; + /* Correct start and end points. */ cookie->_start = tocopy; cookie->_end = (size_t)recv - 1; } - return (0); + return copiedsize; } #endif diff --git a/lib/stream/builtin/streams/streams.h b/lib/stream/builtin/streams/streams.h index d04b078..d884a1c 100644 --- a/lib/stream/builtin/streams/streams.h +++ b/lib/stream/builtin/streams/streams.h @@ -51,7 +51,7 @@ CASIO_EXTERN int CASIO_EXPORT casio_streams_settm /* Character device callbacks. */ -CASIO_EXTERN int CASIO_EXPORT casio_streams_read +CASIO_EXTERN size_t CASIO_EXPORT casio_streams_read OF((streams_cookie_t *casio__cookie, unsigned char *casio__dest, size_t casio__size)); CASIO_EXTERN int CASIO_EXPORT casio_streams_write diff --git a/lib/stream/read.c b/lib/stream/read.c index 42b5fd6..c49a9d8 100644 --- a/lib/stream/read.c +++ b/lib/stream/read.c @@ -25,28 +25,39 @@ * @arg stream the stream to read from. * @arg dest the destination buffer. * @arg size the amount of bytes to read. - * @return the error code (0 if ok). + * @return the size written and -1 if error (error code is in errno). */ -int CASIO_EXPORT casio_read(casio_stream_t *stream, void *dest, size_t size) +size_t CASIO_EXPORT casio_read(casio_stream_t *stream, void *dest, size_t size) { - int err; + int err = casio_error_ok; /* check if we can read */ failure(~stream->casio_stream_mode & CASIO_OPENMODE_READ, casio_error_read) /* read */ - if (!size) return (0); - err = (*getcb(stream, read))(stream->casio_stream_cookie, dest, size); - if (err) { + if (size == 0) { + errno = err; + return (0); + } + size = (*getcb(stream, read))(stream->casio_stream_cookie, dest, size); + + if (size == (size_t)-1) { + err = errno; + if (err == casio_error_eof) { + msg((ll_info, "Stream reading get to the end (EOF)")); + goto fail; + } msg((ll_error, "Stream reading failure: %s", casio_strerror(err))); goto fail; } /* move the cursor and return */ - stream->casio_stream_offset += size; - err = 0; + if(size != 1) { + stream->casio_stream_offset += size; + } fail: stream->casio_stream_lasterr = err; - return (err); + errno = err; + return size; } diff --git a/lib/stream/seek.c b/lib/stream/seek.c index 376221c..c688d0d 100644 --- a/lib/stream/seek.c +++ b/lib/stream/seek.c @@ -63,9 +63,11 @@ int CASIO_EXPORT casio_seek(casio_stream_t *stream, casio_off_t offset, size_t rd = min(to_skip, 128); /* Read that much from the stream. */ - - if ((err = casio_read(stream, buf, rd))) + size_t readed = casio_read(stream, buf, rd); + if (readed == (size_t)-1) { + err = errno; goto fail; + } to_skip -= rd; } while (to_skip); diff --git a/src/p7/main.c b/src/p7/main.c index 1185b27..1794a6b 100644 --- a/src/p7/main.c +++ b/src/p7/main.c @@ -250,7 +250,8 @@ int main(int ac, char **av) /* Check according to menu */ - casio_path_t path; + casio_path_t path = { 0 }; + casio_stream_t *fileStream = NULL; switch (args.menu) { #if 0 case mn_send: @@ -277,12 +278,6 @@ int main(int ac, char **av) args.storage, 1, args.force ? NULL : &sendfile_confirm, args.nicedisp ? &sendfile_display : NULL); break; - case mn_get: - err = casio_reqfile(handle, args.local, - args.dirname, args.filename, - args.storage, args.nicedisp && args.local != stdout - ? &sendfile_display : NULL); - break; case mn_copy: err = casio_copy(handle, args.dirname, args.filename, args.newdir, args.newname, args.storage); @@ -295,15 +290,59 @@ int main(int ac, char **av) err = casio_reset(handle, args.storage); break; #endif + case mn_get: + // Initialize the path + path.casio_path_device = args.storage; + + // Make the node + casio_make_pathnode(&path.casio_path_nodes, strlen(args.filename)); + memcpy(path.casio_path_nodes->casio_pathnode_name, args.filename, strlen(args.filename)); + // Set flags + path.casio_path_flags = casio_pathflag_rel; + + // Open 7.00 fs and open file in read only + if ((err = casio_open_seven_fs(&fs, handle)) + || (err = casio_open(fs, &fileStream, &path, 0, CASIO_OPENMODE_READ))) + break; + + char buffer[CASIO_SEVEN_MAX_RAWDATA_SIZE]; + FILE *file = fopen(args.filename, "wb"); + + if(!file) { + fprintf(stderr, "Couldn't open in write mode %s", args.filename); + err = casio_error_unknown; + break; + } + size_t size; + do + { + size = casio_read(fileStream, buffer, sizeof(buffer)); + if(size == (size_t)-1) + err = errno; + if(err == casio_error_eof) + fwrite(buffer, 1, size, file); + } while (err == 0); + + /* All good so close streams and clear error */ + err = 0; + fclose(file); + casio_close(fileStream); + + break; + case mn_list: + // Initialize the path path.casio_path_device = args.storage; casio_make_pathnode(&path.casio_path_nodes, 1); path.casio_path_flags = casio_pathflag_rel; + + // Open 7.00 fs and list if ((err = casio_open_seven_fs(&fs, handle)) || (err = casio_list(fs, &path, print_file_info, NULL))) break; break; + case mn_optimize: if ((err = casio_open_seven_fs(&fs, handle)) || (err = casio_optimize(fs, args.storage))) diff --git a/src/p7/main.h b/src/p7/main.h index 2242152..f48fe23 100644 --- a/src/p7/main.h +++ b/src/p7/main.h @@ -20,6 +20,7 @@ # define MAIN_H # include # include +# include /* Menus */ typedef enum { diff --git a/src/p7os/procs/fxremote_flash.c b/src/p7os/procs/fxremote_flash.c index 2eac84c..7fdc13c 100644 --- a/src/p7os/procs/fxremote_flash.c +++ b/src/p7os/procs/fxremote_flash.c @@ -60,7 +60,7 @@ struct data_copy_block { static int send_sector(casio_link_t *handle, casio_stream_t *buffer, unsigned long addr, unsigned long size) { - int err, buf_err; + int err; osdisp_t osdisp_cookie; /* Sending the data to the Update.Exe's. */ @@ -83,7 +83,8 @@ static int send_sector(casio_link_t *handle, casio_stream_t *buffer, /* Prepare the block. */ block.destination = casio_be32toh(buf); block.length = casio_be32toh(len); - if ((buf_err = casio_read(buffer, block.data, len))) { + len = casio_read(buffer, block.data, len); + if (len == (size_t)-1) { osdisp_interrupt(&osdisp_cookie); return (casio_error_read); } diff --git a/src/p7os/procs/std_prepare.c b/src/p7os/procs/std_prepare.c index 6663169..5e13a80 100644 --- a/src/p7os/procs/std_prepare.c +++ b/src/p7os/procs/std_prepare.c @@ -55,7 +55,7 @@ int prepare(args_t *args) /* Sleep while the software on the calculator sets up the * communication interface. */ printf("Waiting for the Update.Exe to set up the communication...\n"); - casio_sleep(1000); + casio_sleep(3000); err = 0; fail: diff --git a/tools/osrecover.sh4 b/tools/osrecover.sh4 new file mode 100644 index 0000000..f9e16a2 Binary files /dev/null and b/tools/osrecover.sh4 differ