;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015-2020, 2022-2023 Efraim Flashner ;;; Copyright © 2017 Ricardo Wurmus ;;; Copyright © 2018, 2019, 2020 Tobias Geerinckx-Rice ;;; Copyright © 2018, 2021 Ludovic Courtès ;;; Copyright © 2018, 2019, 2020 Nicolas Goaziou ;;; Copyright © 2019 Clément Lassieur ;;; Copyright © 2020 Jakub Kądziołka ;;; Copyright © 2021 Stefan Reichör ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU Guix is free software; you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 3 of the License, or (at ;;; your option) any later version. ;;; ;;; GNU Guix is distributed in the hope that it will be useful, but ;;; WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with GNU Guix. If not, see . (define-module (gnu packages sync) #:use-module ((guix licenses) #:prefix license:) #:use-module (guix build-system cmake) #:use-module (guix build-system copy) #:use-module (guix build-system gnu) #:use-module (guix build-system go) #:use-module (guix build-system meson) #:use-module (guix build-system qt) #:use-module (guix gexp) #:use-module (guix utils) #:use-module (guix download) #:use-module (guix git-download) #:use-module (guix packages) #:use-module (gnu packages) #:use-module (gnu packages acl) #:use-module (gnu packages adns) #:use-module (gnu packages autotools) #:use-module (gnu packages bash) #:use-module (gnu packages check) #:use-module (gnu packages compression) #:us
Patch for version 3.01, taken from upstream at
https://sourceforge.net/projects/cdrtools/files/cdrtools-3.01-fix-20151126-mkisofs-isoinfo.patch

--- cdrtools-3.01.orig/mkisofs/diag/isoinfo.c	2015-07-22 20:36:45.000000000 +0000
+++ cdrtools-3.01/mkisofs/diag/isoinfo.c	2015-11-17 19:35:40.000000000 +0000
@@ -1,8 +1,8 @@
-/* @(#)isoinfo.c	1.95 15/07/22 joerg */
+/* @(#)isoinfo.c	1.100 15/11/17 joerg */
 #include <schily/mconfig.h>
 #ifndef	lint
 static	UConst char sccsid[] =
-	"@(#)isoinfo.c	1.95 15/07/22 joerg";
+	"@(#)isoinfo.c	1.100 15/11/17 joerg";
 #endif
 /*
  * File isodump.c - dump iso9660 directory information.
@@ -148,8 +148,10 @@ LOCAL char	er_id[256];
 LOCAL int	su_version = 0;
 LOCAL int	rr_version = 0;
 LOCAL int	aa_version = 0;
+LOCAL int	cl_extent = 0;
 LOCAL int	ucs_level = 0;
 LOCAL BOOL	iso9660_inodes = FALSE;
+LOCAL uid_t	myuid;
 
 #ifdef	USE_FIND
 LOCAL findn_t	*find_node;		/* syntaxtree from find_parse()	*/
@@ -208,6 +210,9 @@ LOCAL	void	extract		__PR((char *rootname
 LOCAL	void	extract_file	__PR((int f,
 					struct iso_directory_record * idr,
 					char *fname));
+LOCAL	void	parse_cl_dir	__PR((struct iso_directory_record *idr,
+					int extent));
+LOCAL	BOOL	parse_de	__PR((struct iso_directory_record *idr));
 LOCAL	void	parse_dir	__PR((char * rootname, int extent, int len));
 LOCAL	void	usage		__PR((int excode));
 EXPORT	int	main		__PR((int argc, char *argv[]));
@@ -459,7 +464,6 @@ parse_rr(pnt, len, cont_flag)
 	int slen;
 	int xlen;
 	int ncount;
-	int cl_extent;
 	int pl_extent;
 	int cont_extent, cont_offset, cont_size;
 	int flag1, flag2;
@@ -469,7 +473,7 @@ parse_rr(pnt, len, cont_flag)
 
 	symlinkname[0] = 0;
 
-	cont_extent = cont_offset = cont_size = 0;
+	cl_extent = cont_extent = cont_offset = cont_size = 0;
 
 	ncount = 0;
 	flag1 = -1;
@@ -714,6 +718,7 @@ struct todo
 };
 
 LOCAL struct todo	*todo_idr = NULL;
+LOCAL struct todo	**todo_pp = &todo_idr;
 
 LOCAL char		*months[12] = {"Jan", "Feb", "Mar", "Apr",
 				"May", "Jun", "Jul",
@@ -962,8 +967,14 @@ static	BOOL		isfirst = TRUE;
 	close(f);
 	return;
 setmode:
-	fchmodat(AT_FDCWD, fname, fstat_buf.st_mode, AT_SYMLINK_NOFOLLOW);
 	fchownat(AT_FDCWD, fname, fstat_buf.st_uid, fstat_buf.st_gid, AT_SYMLINK_NOFOLLOW);
+	if (myuid != 0 && S_ISDIR(fstat_buf.st_mode)) {
+		/*
+		 * Temporary hack until we have a dirstack like star.
+		 */
+		fstat_buf.st_mode |= S_IWUSR;
+	}
+	fchmodat(AT_FDCWD, fname, fstat_buf.st_mode, AT_SYMLINK_NOFOLLOW);
 	times[0].tv_sec = fstat_buf.st_atime;
 	times[0].tv_nsec = stat_ansecs(&fstat_buf);
 	times[1].tv_sec = fstat_buf.st_mtime;
@@ -1001,6 +1012,143 @@ extract_file(f, idr, fname)
 	}
 }
 
+
+LOCAL void
+parse_cl_dir(idr, extent)
+	struct iso_directory_record	*idr;
+	int				extent;
+{
+	char				cl_name_buf[256*3];
+
+	strlcpy(cl_name_buf, name_buf, sizeof (cl_name_buf));
+#ifdef	USE_SCG
+	readsecs(extent - sector_offset, idr, 1);
+#else
+	lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
+	read(fileno(infile), idr, 2048);
+#endif
+
+	if (parse_de(idr) && use_rock)
+		dump_rr(idr);
+	strlcpy(name_buf, cl_name_buf, sizeof (name_buf));
+}
+
+LOCAL BOOL
+parse_de(idr)
+	struct iso_directory_record	*idr;
+{
+	unsigned char	uc;
+
+	if (idr->length[0] == 0)
+		return (FALSE);
+	memset(&fstat_buf, 0, sizeof (fstat_buf));
+	found_rr = 0;
+	name_buf[0] = xname[0] = 0;
+	fstat_buf.st_size = (off_t)(unsigned)isonum_733((unsigned char *)idr->size);
+	if (idr->flags[0] & 2)
+		fstat_buf.st_mode |= S_IFDIR;
+	else
+		fstat_buf.st_mode |= S_IFREG;
+	if (idr->name_len[0] == 1 && idr->name[0] == 0)
+		strcpy(name_buf, ".");
+	else if (idr->name_len[0] == 1 && idr->name[0] == 1)
+		strcpy(name_buf, "..");
+	else {
+		switch (ucs_level) {
+		case 3:
+		case 2:
+		case 1:
+			/*
+			 * Unicode name.  Convert as best we can.
+			 */
+			{
+			int	j;
+				name_buf[0] = '\0';
+#ifdef	USE_ICONV
+			if (use_iconv(unls)) {
+				int	u;
+				char	*to = name_buf;
+
+				for (j = 0, u = 0; j < (int)idr->name_len[0] / 2; j++) {
+					char	*ibuf = (char *)&idr->name[j*2];
+					size_t	isize = 2;		/* UCS-2 character size */
+					size_t	osize = 4;
+
+					if (iconv(unls->sic_uni2cd, (__IC_CONST char **)&ibuf, &isize,
+							(char **)&to, &osize) == -1) {
+						int	err = geterrno();
+
+						if ((err == EINVAL || err == EILSEQ) &&
+						    osize == 4) {
+							*to = '_';
+							u += 1;
+							to++;
+						}
+					} else {
+						u += 4 - osize;
+						to = &name_buf[u];
+					}
+				}
+				j = u;
+			} else
+#endif
+			for (j = 0; j < (int)idr->name_len[0] / 2; j++) {
+				UInt16_t	unichar;
+
+				unichar = (idr->name[j*2] & 0xFF) * 256 +
+					    (idr->name[j*2+1] & 0xFF);
+
+				/*
+				 * Get the backconverted char
+				 */
+				if (unls)
+					uc = sic_uni2c(unls, unichar);
+				else
+					uc = unichar > 255 ? '_' : unichar;
+
+				name_buf[j] = uc ? uc : '_';
+			}
+			name_buf[j] = '\0';
+			}
+			break;
+		case 0:
+			/*
+			 * Normal non-Unicode name.
+			 */
+			strncpy(name_buf, idr->name, idr->name_len[0]);
+			name_buf[idr->name_len[0]] = 0;
+			break;
+		default:
+			/*
+			 * Don't know how to do these yet.  Maybe they are the same
+			 * as one of the above.
+			 */
+			exit(1);
+		}
+	}
+	memcpy(date_buf, idr->date, 9);
+	/*
+	 * Always first set up time stamps and file modes from
+	 * ISO-9660. This is used as a fallback in case that
+	 * there is no related Rock Ridge based data.
+	 */
+	fstat_buf.st_atime =
+	fstat_buf.st_mtime =
+	fstat_buf.st_ctime = iso9660_time(date_buf, NULL, FALSE);
+	fstat_buf.st_mode |= S_IRUSR|S_IXUSR |
+		    S_IRGRP|S_IXGRP |
+		    S_IROTH|S_IXOTH;
+	fstat_buf.st_nlink = 1;
+	fstat_buf.st_ino = 0;
+	fstat_buf.st_uid = 0;
+	fstat_buf.st_gid = 0;
+	if (iso9660_inodes) {
+		fstat_buf.st_ino = (unsigned long)
+		    isonum_733((unsigned char *)idr->extent);
+	}
+	return (TRUE);
+}
+
 LOCAL void
 parse_dir(rootname, extent, len)
 	char	*rootname;
@@ -1012,12 +1160,13 @@ parse_dir(rootname, extent, len)
 	struct iso_directory_record * idr;
 	struct iso_directory_record	didr;
 	struct stat			dstat;
-	unsigned char	uc;
+	unsigned char	cl_buffer[2048];
 	unsigned char	flags = 0;
 	Llong		size = 0;
 	int		sextent = 0;
 	int	rlen;
 	int	blen;
+	int	rr_flags = 0;
 static	char	*n = 0;
 static	int	nlen = 0;
 
@@ -1039,115 +1188,23 @@ static	int	nlen = 0;
 		i = 0;
 		while (1 == 1) {
 			idr = (struct iso_directory_record *) &buffer[i];
-			if (idr->length[0] == 0) break;
-			memset(&fstat_buf, 0, sizeof (fstat_buf));
-			found_rr = 0;
-			name_buf[0] = xname[0] = 0;
-			fstat_buf.st_size = (off_t)(unsigned)isonum_733((unsigned char *)idr->size);
-			if (idr->flags[0] & 2)
-				fstat_buf.st_mode |= S_IFDIR;
-			else
-				fstat_buf.st_mode |= S_IFREG;
-			if (idr->name_len[0] == 1 && idr->name[0] == 0)
-				strcpy(name_buf, ".");
-			else if (idr->name_len[0] == 1 && idr->name[0] == 1)
-				strcpy(name_buf, "..");
-			else {
-				switch (ucs_level) {
-				case 3:
-				case 2:
-				case 1:
-					/*
-					 * Unicode name.  Convert as best we can.
-					 */
-					{
-					int	j;
-
-					name_buf[0] = '\0';
-#ifdef	USE_ICONV
-					if (use_iconv(unls)) {
-						int	u;
-						char	*to = name_buf;
-
-						for (j = 0, u = 0; j < (int)idr->name_len[0] / 2; j++) {
-							char	*ibuf = (char *)&idr->name[j*2];
-							size_t	isize = 2;		/* UCS-2 character size */
-							size_t	osize = 4;
-
-							if (iconv(unls->sic_uni2cd, (__IC_CONST char **)&ibuf, &isize,
-									(char **)&to, &osize) == -1) {
-								int	err = geterrno();
-
-								if ((err == EINVAL || err == EILSEQ) &&
-								    osize == 4) {
-									*to = '_';
-									u += 1;
-									to++;
-								}
-							} else {
-								u += 4 - osize;
-								to = &name_buf[u];
-							}
-						}
-						j = u;
-					} else
-#endif
-					for (j = 0; j < (int)idr->name_len[0] / 2; j++) {
-						UInt16_t	unichar;
-
-						unichar = (idr->name[j*2] & 0xFF) * 256 +
-							    (idr->name[j*2+1] & 0xFF);
-
-						/*
-						 * Get the backconverted char
-						 */
-						if (unls)
-							uc = sic_uni2c(unls, unichar);
-						else
-							uc = unichar > 255 ? '_' : unichar;
+			if (idr->length[0] == 0)
+				break;
+			parse_de(idr);
+			if (use_rock) {
+				rr_flags = dump_rr(idr);
 
-						name_buf[j] = uc ? uc : '_';
-					}
-					name_buf[j] = '\0';
-					}
-					break;
-				case 0:
+				if (rr_flags & RR_FLAG_CL) {
 					/*
-					 * Normal non-Unicode name.
+					 * Need to reparse the child link
+					 * but note that we parse "CL/."
+					 * so we get no usable file name.
 					 */
-					strncpy(name_buf, idr->name, idr->name_len[0]);
-					name_buf[idr->name_len[0]] = 0;
-					break;
-				default:
-					/*
-					 * Don't know how to do these yet.  Maybe they are the same
-					 * as one of the above.
-					 */
-					exit(1);
-				}
+					idr = (struct iso_directory_record *) cl_buffer;
+					parse_cl_dir(idr, cl_extent);
+				} else if (rr_flags & RR_FLAG_RE)
+					goto cont;	/* skip rr_moved */
 			}
-			memcpy(date_buf, idr->date, 9);
-			/*
-			 * Always first set up time stamps and file modes from
-			 * ISO-9660. This is used as a fallback in case that
-			 * there is no related Rock Ridge based data.
-			 */
-			fstat_buf.st_atime =
-			fstat_buf.st_mtime =
-			fstat_buf.st_ctime = iso9660_time(date_buf, NULL, FALSE);
-			fstat_buf.st_mode |= S_IRUSR|S_IXUSR |
-				    S_IRGRP|S_IXGRP |
-				    S_IROTH|S_IXOTH;
-			fstat_buf.st_nlink = 1;
-			fstat_buf.st_ino = 0;
-			fstat_buf.st_uid = 0;
-			fstat_buf.st_gid = 0;
-			if (iso9660_inodes) {
-				fstat_buf.st_ino = (unsigned long)
-				    isonum_733((unsigned char *)idr->extent);
-			}
-			if (use_rock)
-				dump_rr(idr);
 			if (Xtract &&
 			    (idr->flags[0] & 2) != 0 &&
 			    idr->name_len[0] == 1 &&
@@ -1170,30 +1227,30 @@ static	int	nlen = 0;
 				n[rlen] = '\0';
 
 			if ((idr->flags[0] & 2) != 0 &&
-			    (idr->name_len[0] != 1 ||
+			    ((rr_flags & RR_FLAG_CL) ||
+			    idr->name_len[0] != 1 ||
 			    (idr->name[0] != 0 && idr->name[0] != 1))) {
 				/*
 				 * This is a plain directory (neither "xxx/."
 				 * nor "xxx/..").
 				 * Add this directory to the todo list.
 				 */
-				td = todo_idr;
-				if (td != NULL) {
-					while (td->next != NULL)
-						td = td->next;
-					td->next = (struct todo *) malloc(sizeof (*td));
-					td = td->next;
-				} else {
-					todo_idr = td = (struct todo *) malloc(sizeof (*td));
-				}
+				td = (struct todo *) malloc(sizeof (*td));
+				if (td == NULL)
+					comerr(_("No memory.\n"));
 				td->next = NULL;
 				td->extent = isonum_733((unsigned char *)idr->extent);
 				td->length = isonum_733((unsigned char *)idr->size);
 				td->name = (char *) malloc(strlen(rootname)
 								+ strlen(name_buf) + 2);
+				if (td->name == NULL)
+					comerr(_("No memory.\n"));
 				strcpy(td->name, rootname);
 				strcat(td->name, name_buf);
 				strcat(td->name, "/");
+
+				*todo_pp = td;
+				todo_pp = &td->next;
 			} else {
 				if (xtract && strcmp(xtract, n) == 0) {
 					extract_file(STDOUT_FILENO, idr, "stdout");
@@ -1253,6 +1310,7 @@ static	int	nlen = 0;
 				if ((idr->flags[0] & ISO_MULTIEXTENT) == 0)
 					size = 0;
 			}
+		cont:
 			i += buffer[i];
 			if (i > 2048 - offsetof(struct iso_directory_record, name[0])) break;
 		}
@@ -1381,12 +1439,13 @@ main(argc, argv)
 		usage(0);
 	if (prvers) {
 		printf(_("isoinfo %s (%s-%s-%s) Copyright (C) 1993-1999 %s (C) 1999-2015 %s\n"),
-					VERSION,
+					"3.02a02",
 					HOST_CPU, HOST_VENDOR, HOST_OS,
 					_("Eric Youngdale"),
 					_("Joerg Schilling"));
 		exit(0);
 	}
+	myuid = getuid();
 #ifdef	USE_FIND
 	if (do_find) {
 		finda_t	fa;
--- cdrtools-3.01.orig/mkisofs/udf.c	2013-04-24 20:45:18.000000000 +0000
+++ cdrtools-3.01/mkisofs/udf.c	2015-11-25 22:07:30.000000000 +0000
@@ -1,15 +1,15 @@
-/* @(#)udf.c	1.42 13/04/24 Copyright 2001-2013 J. Schilling */
+/* @(#)udf.c	1.43 15/11/25 Copyright 2001-2015 J. Schilling */
 #include <schily/mconfig.h>
 #ifndef lint
 static	UConst char sccsid[] =
-	"@(#)udf.c	1.42 13/04/24 Copyright 2001-2013 J. Schilling";
+	"@(#)udf.c	1.43 15/11/25 Copyright 2001-2015 J. Schilling";
 #endif
 /*
  * udf.c - UDF support for mkisofs
  *
  * Written by Ben Rudiak-Gould (2001).
  *
- * Copyright 2001-2013 J. Schilling.
+ * Copyright 2001-2015 J. Schilling.
  */
 /*
  * This program is free software; you can redistribute it and/or modify
@@ -98,7 +98,7 @@ static	UConst char sccsid[] =
 extern	int	use_sparcboot;
 
 extern struct directory *root;
-extern time_t		begun;
+extern struct timeval	tv_begun;
 
 static unsigned lba_main_seq;
 static unsigned lba_main_seq_copy;
@@ -110,7 +110,7 @@ static unsigned lba_end_anchor_vol_desc;
 static unsigned num_udf_files;
 static unsigned num_udf_directories;
 
-static unsigned volume_set_id[2];
+static unsigned volume_set_id[2] = { 0, 0 };
 
 #define	UDF_MAIN_SEQ_LENGTH (16)
 #define	UDF_INTEG_SEQ_LENGTH (2)
@@ -723,7 +723,7 @@ set_primary_vol_desc(buf, lba)
 	/*pvd->volume_abstract;*/
 	/*pvd->volume_copyright_notice;*/
 	/*pvd->application_ident;*/
-	set_timestamp_from_time_t(&pvd->recording_date_and_time, begun);
+	set_timestamp_from_time_t(&pvd->recording_date_and_time, tv_begun.tv_sec);
 	set_impl_ident(&pvd->impl_ident);
 	set_tag(&pvd->desc_tag, UDF_TAGID_PRIMARY_VOLUME_DESC, lba, 512);
 }
@@ -831,7 +831,7 @@ set_logical_vol_integrity_desc(buf, lba)
 	udf_logical_volume_integrity_desc *lvid =
 				(udf_logical_volume_integrity_desc *)buf;
 
-	set_timestamp_from_time_t(&lvid->recording_date, begun);
+	set_timestamp_from_time_t(&lvid->recording_date, tv_begun.tv_sec);
 	set32(&lvid->integrity_type, UDF_INTEGRITY_TYPE_CLOSE);
 	/*lvid->next_integrity_extent;*/
 	set64(&lvid->logical_volume_contents_use.unique_id,
@@ -859,7 +859,7 @@ set_file_set_desc(buf, rba)
 {
 	udf_file_set_desc *fsd = (udf_file_set_desc *)buf;
 
-	set_timestamp_from_time_t(&fsd->recording_date_and_time, begun);
+	set_timestamp_from_time_t(&fsd->recording_date_and_time, tv_begun.tv_sec);
 	set16(&fsd->interchange_level, 3);
 	set16(&fsd->maximum_interchange_level, 3);
 	set32(&fsd->character_set_list, 1);
@@ -1986,8 +1986,10 @@ udf_main_seq_write(out)
 	 * volume_set_id needs to be set to a (64-bit) "unique" number.
 	 * This will have to do for now.
 	 */
-	volume_set_id[0] = begun;
-	volume_set_id[1] = (unsigned)clock();	/* XXX Maybe non-portable */
+	if (volume_set_id[0] == 0) {
+		volume_set_id[0] = tv_begun.tv_sec;
+		volume_set_id[1] = (unsigned)tv_begun.tv_usec;
+	}
 
 	memset(buf, 0, sizeof (buf));
 	set_primary_vol_desc(buf, last_extent_written++);
--- cdrtools-3.01.orig/mkisofs/mkisofs.c	2015-01-01 14:19:51.000000000 +0000
+++ cdrtools-3.01/mkisofs/mkisofs.c
@@ -69 +69 @@ int		path_ind;
-char	version_string[] = VERSION;
+char	version_string[] = "3.01-fix-20151126";
(bin (string-append out "/bin")) (man (string-append out "/share/man/man1"))) (install-file "lsyncd" bin) (install-file "../source/doc/manpage/lsyncd.1" man) #t)))))) (native-inputs (list lua-5.2)) (home-page "https://github.com/axkibe/lsyncd") (synopsis "Synchronize local directories with remote targets") (description "Lsyncd watches a local directory trees event monitor interface (inotify or fsevents). It aggregates and combines events for a few seconds and then spawns one (or more) process(es) to synchronize the changes. By default this is rsync, which must be installed on all source and target machines. Lsyncd is thus a light-weight live mirror solution that is comparatively easy to install not requiring new file systems or block devices and does not hamper local file system performance.") (license license:gpl2+))) (define-public usync (let ((revision "1") (commit "09a8059a1adc22666d3ecf7872e22e6846c3ac9e")) (package (name "usync") (version (git-version "0" revision commit)) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/ebzzry/usync") (commit commit))) (file-name (git-file-name name version)) (sha256 (base32 "16i1q8f0jmfd43rb8d70l2b383vr5ib4kh7iq3yd345q7xjz9c2j")))) (build-system copy-build-system) (inputs (list scsh)) (propagated-inputs (list rsync unison)) (arguments `(#:install-plan '(("usync" "bin/usync")) #:phases (modify-phases %standard-phases (add-before 'install 'patch-usync-shebang (lambda _ (substitute* "usync" (("/usr/bin/env scsh") (which "scsh")))))))) (home-page "https://github.com/ebzzry/usync") (synopsis "Command line site-to-site synchronization tool") (description "@command{usync} is a simple site-to-site synchronization program written in @command{scsh}. It makes use of @command{unison} and @command{rsync} for bi- and uni-directional synchronizations.") (license license:expat)))) (define-public casync (let ((commit "99559cd1d8cea69b30022261b5ed0b8021415654") (revision "0")) (package (name "casync") (version (git-version "2" revision commit)) (home-page "https://github.com/systemd/casync/") (source (origin (method git-fetch) (uri (git-reference (url home-page) (commit commit))) (sha256 (base32 "139g82rkwv1kzss6crfmw3p01xnyjzz66b1ckprpbfncxb24047w")) (file-name (string-append name "-" version "-checkout")))) (build-system meson-build-system) (arguments `(#:configure-flags (let ((out (assoc-ref %outputs "out"))) (list (string-append "-Dudevrulesdir=" out "/lib/udev/rules.d"))))) (native-inputs (list pkg-config python python-sphinx rsync)) ;for tests (inputs (list xz ;for liblzma `(,zstd "lib") curl acl libselinux eudev fuse-2 openssl zlib)) (synopsis "File synchronization and backup system") (description "casync is a @dfn{content-addressable data synchronizer} that can be used as the basis of a backup system. It is: @itemize @item A combination of the rsync algorithm and content-addressable storage; @item An efficient way to store and retrieve multiple related versions of large file systems or directory trees; @item An efficient way to deliver and update OS, VM, IoT and container images over the Internet in an HTTP and CDN friendly way; @item An efficient backup system. @end itemize\n") (license license:lgpl2.1+)))) (define-public rclone (package (name "rclone") (version "1.52.3") (source (origin (method url-fetch) (uri (string-append "https://github.com/rclone/rclone/releases/download/" "v" version "/rclone-v" version ".tar.gz")) (sha256 (base32 "1pdhsxzc5ch2brfylghc602h9ba3x5dshxm3vcaldrgfac0rx0zl")))) ;; FIXME: Rclone bundles some libraries Guix already provides. Need to ;; un-bundle them. (build-system go-build-system) (arguments '(#:import-path "github.com/rclone/rclone" #:install-source? #f)) (synopsis "@code{rsync} for cloud storage") (description "@code{Rclone} is a command line program to sync files and directories to and from different cloud storage providers. Features include: @itemize @item MD5/SHA1 hashes checked at all times for file integrity @item Timestamps preserved on files @item Partial syncs supported on a whole file basis @item Copy mode to just copy new/changed files @item Sync (one way) mode to make a directory identical @item Check mode to check for file hash equality @item Can sync to and from network, e.g., two different cloud accounts @item Optional encryption (Crypt) @item Optional cache (Cache) @item Optional FUSE mount (rclone mount) @end itemize") (home-page "https://rclone.org/") (license license:expat)))