How to copy files in BlackBox under Linux via Wine?

Usage of the framework, compiler and tools
Zinn
Posts: 123
Joined: Mon Nov 24, 2014 10:47 am
Location: Frankfurt am Main
Contact:

How to copy files in BlackBox under Linux via Wine?

Post by Zinn »

I have the following copy procedure in BlackBox:

Code: Select all

	PROCEDURE Copy* (IN source, destination: ARRAY OF CHAR);
		VAR res: INTEGER;
	BEGIN
		res := WinApi.CopyFileW(source, destination, 0);
		IF res # 1 THEN ShowApiError END;
	END Copy;
This procedure works well, but there is a big difference between Windows and Linux.
In Windows the destination file receives the same modified date as the source file.
In Linux the destination file has a different date. It is the date of the time when the file was copied.

I would like to have the same modified date instead. So I can add the following line to the copy procedure

Code: Select all

	PROCEDURE Copy* (IN source, destination: ARRAY OF CHAR);
		VAR res: INTEGER; done: BOOLEAN; t: LONGINT;
	BEGIN
		res := WinApi.CopyFileW(source, destination, 0);
		IF res # 1 THEN ShowApiError END;
		done := PacFiles.GetFileTime(source, t);
		IF done THEN PacFiles.SetFileTime(destination, t) END;
	END Copy;
This does not solve my problem, because in Linux only the owner of the file can change the date of the file.

In the Linux terminal I can copy a file including the last modified date with the command

Code: Select all

cp --preserve=timestamps <source> <destination>
This works also when I am not the owner of the file. I only need read access of the source and write access to the destination.

How can I do the same command with a BlackBox procedure?
User avatar
adimetrius
Posts: 68
Joined: Sun Aug 04, 2019 1:02 pm

Re: How to copy files in BlackBox under Linux via Wine?

Post by adimetrius »

Zinn,

the behaviour you're experiencing is weird and might be a bug in Wine. I've looked up the implementation of CopyFileW; it is now a wrapper around CopyFileExW, and at the end of the latter there is a specific comment and call aimed to achieve exactly what you want - for the copy to have the original's timestamp
https://source.winehq.org/git/wine.git/ ... ase/file.c

Code: Select all

 576 done:
 577     /* Maintain the timestamp of source file to destination file */
 578     SetFileTime( h2, NULL, NULL, &info.ftLastWriteTime );
 579     HeapFree( GetProcessHeap(), 0, buffer );
 580     CloseHandle( h1 );
 581     CloseHandle( h2 );
 582     return ret;
 583 }
But you're reporting that the timestamp is not preserved, so maybe you could direct a question to WineHQ?

It is weird, too, because to copy source to dest, you have to have write permissions on dest (assuming it is a folder) or dest's folder (when dest is a filename). That would entitle you to change the timestamp any way you want, so PacFiles.SetFileTime shouldn't fail.

P.S. I find it amusing that Wine source code uses a goto statement - that's what the done: label is there for! :shock:
Zinn
Posts: 123
Joined: Mon Nov 24, 2014 10:47 am
Location: Frankfurt am Main
Contact:

Re: How to copy files in BlackBox under Linux via Wine?

Post by Zinn »

Thank you Adimetrius for your answer. That will be one way.

Another solution will be to call the Linux library instead of the Windows library. Does anybody from the Linux group have a solution in this direction? Where can I find samples of using the Linux library? How to get started?

A 3rd way will be to open the terminal program and execute a command there.

I prefer a solution of calling the Linux Library, because I can detect inside BlackBox if it is running in Windows or Linux.
Then I have not to wait until Wine has been changed.
- Helmut
User avatar
adimetrius
Posts: 68
Joined: Sun Aug 04, 2019 1:02 pm

Re: How to copy files in BlackBox under Linux via Wine?

Post by adimetrius »

I was working today on a similar task - making copies of files, however under Linux version of BlackBox.
First, I tried to do it the 'native' way: looked up stackoverflow and other sources on 'how to copy files under linux"; ended with using libc function sendfile; found an example in c++ and adopted it to my BB env; after 2.5 hrs of work, I finally got it to work... only to discover that whatever I do, sendfile always copies 0 bytes for me. Always. And, I could find nothing about it on stackoverflow or in the wide big google.

Well, 'to hell with nativity', I thought, and wrote a BB platform-independent procedure. Took me 20 minutes.

Code: Select all

	IMPORT Libc := LinLibc, HostFiles, Utf, Files, AprLibc;
	PROCEDURE CopyFile (from, to: Files.Locator; IN name: Files.Name);
		CONST buflen = 1024*1024;
		VAR rd: Files.Reader; wr: Files.Writer; buf: POINTER TO ARRAY buflen OF BYTE;
		VAR chunk, length, beg: INTEGER; f, g: Files.File;
	BEGIN NEW(buf);
		f := Files.dir.Old(from, name, Files.shared); length := f.Length();
		IF f # NIL THEN rd := f.NewReader(rd);
			g := Files.dir.New(to, Files.dontAsk); wr := g.NewWriter(wr);
			beg := 0;
			REPEAT chunk := MIN(buflen, length); DEC(length, chunk); INC(beg, chunk);
				rd.ReadBytes(buf, beg, chunk); wr.WriteBytes(buf, beg, chunk)
			UNTIL length = 0;
			g.Register(name, '', Files.dontAsk, to.res);
			f.Close
		END
	END CopyFile;
Then I faced the timestamp issue; after another hour of googling and pronouncing magical spells, all to no avail, I had to look up touch.c on gnu coreutils site - the source of touch utility used to change timestamps of files from command line. That led me to discover utimensat(), which I was then able to get to work.

I made an interface module:

Code: Select all

MODULE AprLibc ["libc.so.6"];
	IMPORT Libc := LinLibc;
	TYPE TVP* = RECORD [untagged] access*, modification*: Libc.timespec_t END;
	PROCEDURE [ccall] utimensat* (fd: INTEGER; file: Libc.PtrSTR; VAR tvp: TVP; flags: SET): INTEGER;
END AprLibc.
and a BB procedure:

Code: Select all

	PROCEDURE CopyTimestamps* (from, to: Files.Locator; IN name: Files.Name);
		VAR src, dst: INTEGER; buf: ARRAY 512 OF SHORTCHAR; offset, res: INTEGER; 
			stat: Libc.stat_t; tvp: AprLibc.TVP;
	BEGIN
		Utf.StringToUtf8(from(HostFiles.Locator).path + "/" + name, buf, res);
		IF res = 0 THEN src := Libc.open(buf, Libc.O_RDONLY, {});
			IF src >= 0 THEN
				res := Libc.__xstat(Libc._STAT_VER_LINUX, buf, stat);
				IF res = 0 THEN
					Utf.StringToUtf8(to(HostFiles.Locator).path + "/" + name, buf, res);
					IF res = 0 THEN 
						tvp.access := stat.st_atim; tvp.modification := stat.st_mtim;
						res := AprLibc.utimensat(0, buf, tvp, {}); 
						IF res # 0 THEN to.res := eTimestamps END
					ELSE to.res := eUtf
					END
				ELSE from.res := eOpen
				END;
				res := Libc.close(src)
			ELSE from.res := eStat
			END
		ELSE from.res := eUtf
		END
	END CopyTimestamps;
This code works in BlackBox Cross-Platform 1.8 (which is in development phase yet) under Linux. Utf.StringToUtf8 might be the only call you'd have to adapt to your BB version.
Zinn
Posts: 123
Joined: Mon Nov 24, 2014 10:47 am
Location: Frankfurt am Main
Contact:

Re: How to copy files in BlackBox under Linux via Wine?

Post by Zinn »

Thank you very much Adimetrius for working out this topic.

Are you working with bbcb-1.8-a1.037.zip from the website https://blackbox.oberon.org/download ?
I have not running the Linux version on my computer. Is there somewhere an installation instruction ?

Can you please send me a saveset of your CopyFile and CopyTimestamps program
to my e-mail address: feedback (at) zinnamturm.eu ? Please change (at) against @ and delete the blanks.

I currently work on Linux Mint 19.3 with Wine 4.0
Soon I will change my system to Linux Mint 20 with Wine 5.0

I work BlackBox 1.7.2007 core available at the website https://www.zinnamturm.eu/downloads.htm
or the via direct download at https://www.zinnamturm.eu/pac/BlackBox-2007-core.7z

Once again thank you for your help
- Helmut
User avatar
adimetrius
Posts: 68
Joined: Sun Aug 04, 2019 1:02 pm

Re: How to copy files in BlackBox under Linux via Wine?

Post by adimetrius »

Helmut,

I've sent you what i think you requested. As far as BB version - yes, blackbox.oberon.org/download is the right page, I work with 1.8 alpha. Althought I am on the team developing this version, I think Ivan Denisov is a better person to answer any download/installation questions - he's pretty amazing, he makes sure BB is running smoothly on maybe a dozen different Linux/Unix flavors. Thanks Ivan!
User avatar
Ivan Denisov
Posts: 362
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: How to copy files in BlackBox under Linux via Wine?

Post by Ivan Denisov »

Zinn wrote:Are you working with bbcb-1.8-a1.037.zip from the website https://blackbox.oberon.org/download ?
I have not running the Linux version on my computer. Is there somewhere an installation instruction ?
Dear, Helmut
Try execute these commands from terminal one by one.

Code: Select all

wget http://deb.oberon.org/deb.oberon.org.gpg.key
sudo apt-key add deb.oberon.org.gpg.key
sudo dpkg --add-architecture i386
echo "deb http://deb.oberon.org/linux18 testing main" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install bbcb
This will install development 1.8 version of BlackBox. Some interfaces are changed.

The version which more fit with Center version is 1.7.2 and more stable is bbcb-1.7.2-b1.
To install it, use another repository.

Code: Select all

wget http://deb.oberon.org/deb.oberon.org.gpg.key
sudo apt-key add deb.oberon.org.gpg.key
sudo dpkg --add-architecture i386
echo "deb http://deb.oberon.org/linux testing main" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install bbcb
Zinn
Posts: 123
Joined: Mon Nov 24, 2014 10:47 am
Location: Frankfurt am Main
Contact:

Re: How to copy files in BlackBox under Linux via Wine?

Post by Zinn »

Thank you Ivan for repeating the instruction here. I'm blind as a bat. You have the instruction on our website. I installed the Linux version 1.8 of BlackBox and it is running on my computer. Sorry, I'm very slow about learning the Linux environment.

Now I figure out the difference between Linux and Windows:

Subsystem in Linux Version only: Cons - Dev2 - Gtk2 - Lin
Subsystem in Windows Version only: Com - Ctl - Win

Module in Linux Version only: HostDates - HostEnv - HostGnome - HostLang - (System)Unicode - (System)Utf
Module in Windows Version only: HostBitmaps - HostConsole - HostMail - HostPictures - HostPrinters

I know how to create (build) a new Windows version of BlackBox
My next step is to find out how to create (build) a new Linux version.

Thank you Ivan. You have done a create job.
- Helmut
User avatar
Ivan Denisov
Posts: 362
Joined: Tue Sep 17, 2013 12:21 am
Location: Krasnoyarsk, Russia

Re: How to copy files in BlackBox under Linux via Wine?

Post by Ivan Denisov »

Thank you Helmut, this is work of many people.

To build new version there is the instruction in the repository:
https://github.com/bbcb/bbcp

1. Download sources from GitHub

For 1.7
https://github.com/bbcb/bbcp/archive/master.zip
For 1.8
https://github.com/bbcb/bbcp/archive/dev18.zip

2. make sure that pax is installed

Code: Select all

sudo apt install pax
3. Use this commands

Code: Select all

cd BlackBox
./switch-target `uname -s` GUI
./build
./export ../`uname -s`_GUI
./switch-target none
./clean
cd ../`uname -s`_GUI
./run-BlackBox
Zinn
Posts: 123
Joined: Mon Nov 24, 2014 10:47 am
Location: Frankfurt am Main
Contact:

Re: How to copy files in BlackBox under Linux via Wine?

Post by Zinn »

Experience Report about using the Linux BB 1.8 and the Windows BB 1.7 in Wine:

Copy and Paste from Linux BB to Wine BB works, but it lost the commander (!)
Copy and Paste from Wine BB to Linux BB doesn't work directly. It works via paste into an editor and copy again from the editor.

The HZ copy works in Linux BB, it doesn't work in Wine BB.
The HZ copy sample works in Linux BB only on the local disk drive to local disk drive. It doesn't work with connected disks via /etc/fstab (e.g. smb-share to a nas device).

Anyway thank for your help. I learned at lot with your answers.
- Helmut
Post Reply