1 unit rfs_utils;
2 {
3 DESCRIPTION : Unit providing UI-neutral routines to be used in Raw File
4 Split and Raw File Join
5
6 REQUIREMENTS : FPC
7
8 EXTERNAL DATA : ---
9
10 MEMORY USAGE : ---
11
12 DISPLAY MODE : ---
13
14 REFERENCES : ---
15
16 REMARK : ---
17
18 Version Date Author Modification
19 ------- -------- ------- ------------------------------------------
20 0.10 20060816 G.Tani Initial version
21 0.11 20060917 G.Tani removed *_VER; P_RELEASE constant in pea_utils
22 is used to keep track of release level;
23 0.12 20080704 G.Tani Enabled utf8
24 0.13 20200508 G.Tani Added SHA3_256, SHA3_512, BLAKE2S, BLAKE2B algorithms
25
26 (C) Copyright 2006 Giorgio Tani giorgio.tani.software@gmail.com
27 The program is released under GNU LGPL http://www.gnu.org/licenses/lgpl.txt
28
29 This library is free software; you can redistribute it and/or
30 modify it under the terms of the GNU Lesser General Public
31 License as published by the Free Software Foundation; either
32 version 3 of the License, or (at your option) any later version.
33
34 This library is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37 Lesser General Public License for more details.
38
39 You should have received a copy of the GNU Lesser General Public
40 License along with this library; if not, write to the Free Software
41 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
42 }
43
44 {$mode objfpc}{$H+}
45 {$INLINE ON}
46
47 interface
48
49 uses SysUtils;
50
51 const
52 SUCCESS = 0;
53 INCOMPLETE_FUNCTION = 1;
54 UNKNOWN_VOLUME_CONTROL_ALGORITHM = 2;
55 NOT_RFS_HEADER = 3;
56
57 {
58 generate RFS 4 byte .check file header
59 }
rfs_create_checkfile_hdrnull60 function rfs_create_checkfile_hdr ( volume_control_algorithm:ansistring; //algorithm to error check each volume
61 var hdr_data:array of byte //buffer for header data
62 ):integer;
63
64 {
65 read RFS 4 byte .check file header
66 }
rfs_parse_archive_headernull67 function rfs_parse_archive_header ( read_data:array of byte; //buffer containig the header matherial
68 var volume_algo:ansistring //control algorithm for volumes
willnull69 ):integer; //note that the function will exit at all error condition (excluded INCOMPLETE_FUNCTION); in this way it will always be returned the code of the first error encountered
70
71 {
72 decode volume control algorithm
73 }
decode_rfs_volume_control_algonull74 function decode_rfs_volume_control_algo ( volume_algo:ansistring; //control algorithm
75 var authsize:byte //authentication tag size
76 ):integer;
77
78 {
79 update volume name following RFS volume naming convention
80 }
81 procedure update_rfs_filename ( fname:ansistring; //name to update
82 i:integer; //counter (updated externally)
83 var newname:ansistring); //updated name: input name + 3 digit human readable counter
84
85 implementation
86
rfs_create_checkfile_hdrnull87 function rfs_create_checkfile_hdr ( volume_control_algorithm:ansistring; //algorithm to error check each volume
88 var hdr_data:array of byte //buffer for header data
89 ):integer;
90 begin
91 rfs_create_checkfile_hdr:=INCOMPLETE_FUNCTION; //generic error code: the subroutine is jet not completed (useful if the function somehow cannot complete)
92 hdr_data[0]:=114; //r
93 hdr_data[1]:=102; //f
94 hdr_data[2]:=115; //s
95 //byte 3: control model for each single volume, to allow identification of corrupted chunks (i.e. to request resending, or to not trust to try to open them)
96 if (upcase(volume_control_algorithm)='NOALGO') then hdr_data[3]:=$00
97 else
98 if (upcase(volume_control_algorithm)='ADLER32') then hdr_data[3]:=$01
99 else
100 if (upcase(volume_control_algorithm)='CRC32') then hdr_data[3]:=$02
101 else
102 if (upcase(volume_control_algorithm)='CRC64') then hdr_data[3]:=$03
103 else
104 if (upcase(volume_control_algorithm)='MD5') then hdr_data[3]:=$10
105 else
106 if (upcase(volume_control_algorithm)='RIPEMD160') then hdr_data[3]:=$11
107 else
108 if (upcase(volume_control_algorithm)='SHA1') then hdr_data[3]:=$12
109 else
110 if (upcase(volume_control_algorithm)='SHA256') then hdr_data[3]:=$13
111 else
112 if (upcase(volume_control_algorithm)='SHA512') then hdr_data[3]:=$14
113 else
114 if (upcase(volume_control_algorithm)='WHIRLPOOL') then hdr_data[3]:=$15
115 else
116 if (upcase(volume_control_algorithm)='SHA3_256') then hdr_data[3]:=$16
117 else
118 if (upcase(volume_control_algorithm)='SHA3_512') then hdr_data[3]:=$17
119 else
120 if (upcase(volume_control_algorithm)='BLAKE2S') then hdr_data[3]:=$18
121 else
122 if (upcase(volume_control_algorithm)='BLAKE2B') then hdr_data[3]:=$19
123 else rfs_create_checkfile_hdr:=UNKNOWN_VOLUME_CONTROL_ALGORITHM;
124 rfs_create_checkfile_hdr:=SUCCESS;
125 end;
126
rfs_parse_archive_headernull127 function rfs_parse_archive_header ( read_data:array of byte; //buffer containig the header matherial
128 var volume_algo:ansistring //control algorithm for volumes
willnull129 ):integer; //note that the function will exit at all error condition (excluded INCOMPLETE_FUNCTION); in this way it will always be returned the code of the first error encountered
130 begin
131 rfs_parse_archive_header:=INCOMPLETE_FUNCTION;
ifnull132 if ((read_data[0]=114) and (read_data[1]=102) and (read_data[2]=115)) then
133 begin
134 case read_data[3] of
135 0: volume_algo:='NOALGO'; //hex 00
136 1: volume_algo:='ADLER32'; //hex 01
137 2: volume_algo:='CRC32'; //hex 02
138 3: volume_algo:='CRC64'; //hex 03
139 16: volume_algo:='MD5'; //hex 10
140 17: volume_algo:='RIPEMD160'; //hex 11
141 18: volume_algo:='SHA1'; //hex 12
142 19: volume_algo:='SHA256'; //hex 13
143 20: volume_algo:='SHA512'; //hex 14
144 21: volume_algo:='WHIRLPOOL'; //hex 15
145 22: volume_algo:='SHA3_256'; //hex 16
146 23: volume_algo:='SHA3_512'; //hex 17
147 24: volume_algo:='BLAKE2S'; //hex 18
148 25: volume_algo:='BLAKE2B'; //hex 19
149 else
150 begin
151 rfs_parse_archive_header:=UNKNOWN_VOLUME_CONTROL_ALGORITHM;
152 exit;
153 end;
154 end;
155 end
156 else rfs_parse_archive_header:=NOT_RFS_HEADER;
thennull157 if rfs_parse_archive_header=INCOMPLETE_FUNCTION then rfs_parse_archive_header:=SUCCESS;
158 end;
159
decode_rfs_volume_control_algonull160 function decode_rfs_volume_control_algo ( volume_algo:ansistring; //control algorithm
161 var authsize:byte //authentication tag size
162 ):integer;
163 begin
164 decode_rfs_volume_control_algo:=INCOMPLETE_FUNCTION;
authsizenull165 authsize:=255;
166 if upcase(volume_algo)='NOALGO' then authsize:=0;
167 if upcase(volume_algo)='ADLER32' then authsize:=4;
168 if upcase(volume_algo)='CRC32' then authsize:=4;
169 if upcase(volume_algo)='CRC64' then authsize:=8;
170 if upcase(volume_algo)='MD5' then authsize:=16;
171 if upcase(volume_algo)='RIPEMD160' then authsize:=20;
172 if upcase(volume_algo)='SHA1' then authsize:=20;
173 if upcase(volume_algo)='SHA256' then authsize:=32;
174 if upcase(volume_algo)='SHA512' then authsize:=64;
175 if upcase(volume_algo)='WHIRLPOOL' then authsize:=64;
176 if upcase(volume_algo)='SHA3_256' then authsize:=32;
177 if upcase(volume_algo)='SHA3_512' then authsize:=64;
178 if upcase(volume_algo)='BLAKE2S' then authsize:=32;
179 if upcase(volume_algo)='BLAKE2B' then authsize:=64;
180 if authsize=255 then decode_rfs_volume_control_algo:=UNKNOWN_VOLUME_CONTROL_ALGORITHM;
thennull181 if decode_rfs_volume_control_algo=INCOMPLETE_FUNCTION then decode_rfs_volume_control_algo:=SUCCESS;
182 end;
183
184 procedure update_rfs_filename ( fname:ansistring; //name to update
185 i:integer; //counter (updated externally)
186 var newname:ansistring); //updated name: input name + 3 digit human readable counter
187 begin
188 if i <10 then newname:=fname+'.00'+inttostr(i)
189 else
190 if i<100 then newname:=fname+'.0'+inttostr(i)
191 else newname:=fname+'.'+inttostr(i);
192 end;
193
194 end.
195