aboutsummaryrefslogtreecommitdiffstats
path: root/sercp.c
diff options
context:
space:
mode:
authorPavel Vymetálek <pavel@vym.cz>2019-03-26 11:09:21 +0100
committerPavel Vymetálek <pavel@vym.cz>2019-03-26 11:09:21 +0100
commit59066b2124c4f3b7a873b941aa33db683a997cbc (patch)
tree8d3d9ad90a783bc091a8248dff217791445e9471 /sercp.c
parent2d5fd6762eb110f537e3bb04cb632b1885956216 (diff)
downloadsercp-pc-59066b2124c4f3b7a873b941aa33db683a997cbc.tar.gz
Add support for file time/date handlingv0.3.0
- requires esxdos v0.8.7 and .sercp v0.3 - backward compatible with .sercp v0.2 on esxdos v0.8.6 - if zero date is received actual date/time are used
Diffstat (limited to 'sercp.c')
-rw-r--r--sercp.c83
1 files changed, 53 insertions, 30 deletions
diff --git a/sercp.c b/sercp.c
index 1f4118b..5e795c9 100644
--- a/sercp.c
+++ b/sercp.c
@@ -30,6 +30,9 @@
#include <libgen.h>
#include <sys/stat.h>
#include <error.h>
+ #include <time.h>
+ #include <sys/time.h>
+ #include <utime.h>
#else
@@ -49,6 +52,9 @@
#include <signal.h>
#include <fcntl.h>
#include <poll.h>
+ #include <time.h>
+ #include <sys/time.h>
+ #include <utime.h>
#endif
@@ -57,7 +63,7 @@
#define true 1
#define TRUE 1
-const char* _version = "v0.2.3";
+const char* _version = "v0.3.0";
// SERIAL
FILE *tapout_fd = NULL;
int is_outfile = 0;
@@ -96,22 +102,22 @@ char MODEMDEVICE[64] = {
#endif
-
typedef struct {
- uint16_t block_len;
- uint8_t block_xor;
- uint8_t block_sum;
-} __attribute__((packed)) fi_sum;
+ uint16_t block_len; // legth of block
+ uint8_t block_xor; // xor of all bytes in block
+ uint8_t block_sum; // 8-bit sum of all bytes in block
+} __attribute__((packed)) fi_sum;// used as fi_blocks in fileinfo
typedef struct {
- uint16_t length; // delka dat ve fileinfo
- uint8_t h_xor; // xor bajtu fileinfa od fi_numblocks
- uint8_t h_sum; // sum bajtu fileinfa od fi_numblocks
- uint8_t fi_numblocks; // pocet bloku
- uint8_t fi_name[64]; // jmeno souboru - prozatim musi byt ve fromatu 8.3 - kvuli esxdosu
- uint8_t fi_date[8]; // nepouzito
- uint8_t fi_time[8]; // nepouzito
- fi_sum fi_blocks[256]; // delky a soucty bloku
+ uint16_t length; // length of data in fileinfo
+ uint8_t h_xor; // xor of all bytes of fileinfo
+ uint8_t h_sum; // sum of all bytes of fileinfo
+ uint8_t fi_numblocks; // number of transfered blocks
+ uint8_t fi_name[64]; // filename (8.3 format for now)
+ uint8_t fi_reserved[12];// reserved
+ uint16_t fi_time[1]; // fat file time
+ uint16_t fi_date[1]; // fat file date
+ fi_sum fi_blocks[256]; // blocks - see fi_sums above
} __attribute__((packed)) FILEINFO;
FILEINFO fileinfo;
@@ -370,14 +376,13 @@ void sercpRecv(void) {
uint16_t len;
uint16_t length = 0;
uint16_t expected_len = 0;
-// uint8_t expected_xor;
-// uint8_t expected_sum;
uint32_t overall_length = 0; // celkova delka souboru
uint32_t recv_length = 0; // zatim prijatych dat ze souboru
+ struct utimbuf f_datetime;
+ struct tm timdat;
#ifndef __WIN32
int result;
-// int _err;
- #endif
+#endif
FILEINFO *p_fileinfo = &fileinfo;
unsigned char *p_buff = buff;
tapout_fd = NULL;
@@ -387,13 +392,13 @@ void sercpRecv(void) {
memset (p_fileinfo, 0, sizeof(fileinfo));
while (is_continue) {
- #ifndef __WIN32
+#ifndef __WIN32
result = poll (spolfd_serial, 1, 200); // 200ms timeout
if (result == 0) {
// nic neprislo
continue;
}
- #endif
+#endif
switch (recv_phase) {
case 0:
// prijem fileinfo
@@ -411,9 +416,11 @@ void sercpRecv(void) {
if (length == sizeof(fileinfo)) {
memcpy((unsigned char*) p_fileinfo, buff, sizeof(fileinfo));
if (CheckFileInfo(p_fileinfo) == 0) {
-// printf("Fileinfo received\n");
overall_length = GetOverallLen(p_fileinfo);
printf("File: \"%s\" number of blocks:%d, length of file: %u\n", p_fileinfo->fi_name, p_fileinfo->fi_numblocks, overall_length);
+// printf("Recv file date: %4d-%02d-%02d\t ", ((*p_fileinfo->fi_date & 0xFE00) >> 9)+1980, ((*p_fileinfo->fi_date & 0x1E0) >> 5),* p_fileinfo->fi_date & 0x1F);
+// printf("%02d:%02d:%02d\t%4X, %4X\n", ((*p_fileinfo->fi_time ) >> 11), ((*p_fileinfo->fi_time & 0x7e0) >> 5),(*p_fileinfo->fi_time & 0x1F)*2, *p_fileinfo->fi_date, *p_fileinfo->fi_time);
+
recv_phase++; // priste se uz prijimaji bloky
block_index = 0; // zacina se prvnim blokem
p_buff = buff; // buffer na zacatek
@@ -426,7 +433,6 @@ void sercpRecv(void) {
exit (EXIT_FAILURE);
#else
-// _err = errno;
err (1, "can't open output file");
#endif
}
@@ -460,7 +466,6 @@ void sercpRecv(void) {
len = read (serial_fd, p_buff, expected_len);
sleep_ms(10);
#endif
-// printf ("read len: %d\n", len);
p_buff += len;
expected_len -= len;
length += len;
@@ -468,7 +473,6 @@ void sercpRecv(void) {
DoProgress(recv_length, overall_length, PROGRESS_PERCENT);
if (length == p_fileinfo->fi_blocks[block_index].block_len) {
// prijaty prvni block
-// printf("Prijaty blok c.%d delky: %d\n", block_index, length);
if (CheckSumBlock(p_fileinfo, block_index, buff) == 0) {
// blok je v cajku - zapsat do souboru
if (tapout_fd) fwrite(buff, length, 1, tapout_fd);
@@ -490,9 +494,24 @@ void sercpRecv(void) {
if (tapout_fd) {
fflush (tapout_fd);
fclose (tapout_fd);
+ // set date and time which is received
+ memset(&timdat, 0, sizeof(struct tm));
+ if (*p_fileinfo->fi_date != 0) {
+ timdat.tm_year = (((*p_fileinfo->fi_date & 0xFE00) >> 9) + 1980)-1900;
+ timdat.tm_mon = ((*p_fileinfo->fi_date & 0x1E0) >> 5) - 1;
+ timdat.tm_mday = *p_fileinfo->fi_date & 0x1F;
+ timdat.tm_hour = ((*p_fileinfo->fi_time ) >> 11);
+ timdat.tm_min = ((*p_fileinfo->fi_time & 0x7e0) >> 5);
+ timdat.tm_sec = (*p_fileinfo->fi_time & 0x1F)*2;
+ timdat.tm_isdst = -1;
+ f_datetime.modtime = mktime(&timdat);
+ f_datetime.actime = f_datetime.modtime;
+ utime ((char*)p_fileinfo->fi_name, &f_datetime);
+ }
}
}
+
/************************************************************************/
void sercpSend(void) {
FILE *tap_fd;
@@ -512,8 +531,7 @@ void sercpSend(void) {
#ifdef __WIN32
unsigned long ulNumBytes;
#endif
-
-
+ struct tm *timdat;
no = stat(sercp_file, &st);
if (no != 0) {
@@ -531,6 +549,11 @@ void sercpSend(void) {
return;
}
printf ("File %s, length: %ld\n", sercp_file, st.st_size);
+ timdat = localtime(&st.st_mtime);
+
+ uint16_t FatDate = ((timdat->tm_year - 80) << 9) | ((timdat->tm_mon + 1) << 5) | timdat->tm_mday;
+ uint16_t FatTime = ((timdat->tm_hour << 11) | (timdat->tm_min << 5) | (timdat->tm_sec >> 1));
+
memset (p_fileinfo, 0, sizeof(fileinfo)); // smazat fileinfo
basec = strdup (sercp_file);
@@ -546,11 +569,13 @@ void sercpSend(void) {
}
memcpy(p_fileinfo->fi_name, bname, strlen(bname));
+ memcpy(p_fileinfo->fi_date, &FatDate, sizeof(FatDate));
+ memcpy(p_fileinfo->fi_time, &FatTime, sizeof(FatTime));
+// printf("Sent file date: %4d-%02d-%02d\t%4X, %4X\n", ((FatDate & 0xFE00) >> 9)+1980, ((FatDate & 0x1E0) >> 5), FatDate & 0x1F, FatDate, FatTime);
file_len = (uint32_t) st.st_size;
while (file_len) {
len = fread(buff, 1, 16384, tap_fd); // precti 16kiB dat
CountSumBlock(p_fileinfo, num_blocks, buff, len);
-// printf ("Blok c. %d, delka: %d\n", num_blocks, len);
file_len -= len;
num_blocks++;
}
@@ -564,7 +589,6 @@ void sercpSend(void) {
tcdrain(serial_fd);
#endif
printf("Fileinfo sent with filename: %s\n", bname);
- // TODO Cekat pauzu mezi bloky
sleep_ms(wait_ms);
rewind(tap_fd); // prenaseny soubor na zacatek
@@ -601,7 +625,6 @@ void sercpSend(void) {
} else {
printf("\nend...\n");
}
-
fclose(tap_fd);
}
@@ -713,7 +736,7 @@ void CloseUart() {
/************************************************************************/
int main(int argc, char** argv, char** env)
{
-#ifndef __WIN32
+ #ifndef __WIN32
// osetreni breaku ^C v unixech
saterm.sa_handler = signal_handler_sigterm;
saterm.sa_flags = 0;