From 59066b2124c4f3b7a873b941aa33db683a997cbc Mon Sep 17 00:00:00 2001 From: Pavel Vymetálek Date: Tue, 26 Mar 2019 11:09:21 +0100 Subject: Add support for file time/date handling - 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 --- TODO | 5 ++-- sercp.c | 83 +++++++++++++++++++++++++++++++++++++++++------------------------ 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/TODO b/TODO index a1a50bd..074c8e8 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ 2019-03-16 - - add support for handling time/date of files - + + add support for handling time/date of files + * info at https://docs.microsoft.com/en-us/windows/desktop/api/Winbase/nf-winbase-filetimetodosdatetime + 2019-01-22 - udělat do progressbaru značky po 16kB pro lepší orientaci v blocích :-) diff --git a/sercp.c b/sercp.c index 1f4118b..5e795c9 100644 --- a/sercp.c +++ b/sercp.c @@ -30,6 +30,9 @@ #include #include #include + #include + #include + #include #else @@ -49,6 +52,9 @@ #include #include #include + #include + #include + #include #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; -- cgit