diff options
| author | Pavel Vymetálek <pavel@vym.cz> | 2019-03-26 11:09:21 +0100 | 
|---|---|---|
| committer | Pavel Vymetálek <pavel@vym.cz> | 2019-03-26 11:09:21 +0100 | 
| commit | 59066b2124c4f3b7a873b941aa33db683a997cbc (patch) | |
| tree | 8d3d9ad90a783bc091a8248dff217791445e9471 | |
| parent | 2d5fd6762eb110f537e3bb04cb632b1885956216 (diff) | |
| download | sercp-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
| -rw-r--r-- | TODO | 5 | ||||
| -rw-r--r-- | sercp.c | 83 | 
2 files changed, 56 insertions, 32 deletions
| @@ -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 :-) @@ -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; | 
