1 
2 /***************************************************************************
3  *                    __            __ _ ___________                       *
4  *                    \ \          / /| |____   ____|                      *
5  *                     \ \        / / | |    | |                           *
6  *                      \ \  /\  / /  | |    | |                           *
7  *                       \ \/  \/ /   | |    | |                           *
8  *                        \  /\  /    | |    | |                           *
9  *                         \/  \/     |_|    |_|                           *
10  *                                                                         *
11  *                           Wiimms ISO Tools                              *
12  *                         http://wit.wiimm.de/                            *
13  *                                                                         *
14  ***************************************************************************
15  *                                                                         *
16  *   This file is part of the WIT project.                                 *
17  *   Visit http://wit.wiimm.de/ for project details and sources.           *
18  *                                                                         *
19  *   Copyright (c) 2009-2013 by Dirk Clemens <wiimm@wiimm.de>              *
20  *                                                                         *
21  ***************************************************************************
22  *                                                                         *
23  *   This program is free software; you can redistribute it and/or modify  *
24  *   it under the terms of the GNU General Public License as published by  *
25  *   the Free Software Foundation; either version 2 of the License, or     *
26  *   (at your option) any later version.                                   *
27  *                                                                         *
28  *   This program is distributed in the hope that it will be useful,       *
29  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
30  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
31  *   GNU General Public License for more details.                          *
32  *                                                                         *
33  *   See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt       *
34  *                                                                         *
35  ***************************************************************************/
36 
37 #ifndef WIT_LIB_STD_H
38 #define WIT_LIB_STD_H 1
39 
40 #define _GNU_SOURCE 1
41 
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #include <stdio.h>
46 #include <time.h>
47 
48 #include "types.h"
49 #include "system.h"
50 #include "lib-error.h"
51 #include "libwbfs/file-formats.h"
52 
53 //
54 ///////////////////////////////////////////////////////////////////////////////
55 ///////////////                     some defs                   ///////////////
56 ///////////////////////////////////////////////////////////////////////////////
57 
58 #if defined(RELEASE) && RELEASE>1
59     #undef EXTENDED_ERRORS
60 #elif defined(DEBUG) || defined(TEST)
61     #undef EXTENDED_ERRORS
62     #define EXTENDED_ERRORS 1		// undef | 1 | 2
63 #endif
64 
65 #ifndef EXTENDED_IO_FUNC
66     #define EXTENDED_IO_FUNC 1		// 0 | 1
67 #endif
68 
69 #if !HAVE_FALLOCATE && !HAVE_POSIX_FALLOCATE && !__APPLE__
70     #undef  NO_PREALLOC
71     #define NO_PREALLOC 1
72 #endif
73 
74 ///////////////////////////////////////////////////////////////////////////////
75 
76 #ifdef NEW_FEATURES // [[2do]]
77  #define WDF2_ENABLED		  2	// 0:off, 1:read only, 2:write support
78  #define WDF_VERSION		  1	// default version
79  #define WDF_ALIGN		  1	// default alignment for WDF v2
80  #define WDF_ALIGN_TEXT		"1"
81  #define WDF_MAX_ALIGN		GiB	// max allowed WDF alignment
82  #define WDF_MAX_ALIGN_TEXT	"1 GiB"
83 #else
84  #define WDF2_ENABLED		  0
85  #define WDF_VERSION		  1	// default version
86  #define WDF_ALIGN		  1	// default alignment for WDF v2
87  #define WDF_ALIGN_TEXT		"1"
88  #define WDF_MAX_ALIGN		GiB	// max allowed WDF alignment
89  #define WDF_MAX_ALIGN_TEXT	"1 GiB"
90 #endif
91 
92 ///////////////////////////////////////////////////////////////////////////////
93 
94 typedef enum enumProgID
95 {
96 	PROG_UNKNOWN,
97 	PROG_WIT,
98 	PROG_WWT,
99 	PROG_WDF,
100 	PROG_WFUSE,
101 
102 } enumProgID;
103 
104 typedef enum enumRevID
105 {
106 	REVID_UNKNOWN		= 0x00000000,
107 	REVID_WIIMM		= 0x10000000,
108 	REVID_WIIMM_TRUNK	= 0x20000000,
109 
110 } enumRevID;
111 
112 ///////////////////////////////////////////////////////////////////////////////
113 
114 #define TRACE_SEEK_FORMAT "%-20.20s fd=%d,%p %9llx%s\n"
115 #define TRACE_RDWR_FORMAT "%-20.20s fd=%d,%p %9llx..%9llx %8zx%s\n"
116 
117 #define FILE_PRELOAD_SIZE	0x800
118 #define MIN_SPARSE_HOLE_SIZE	4096 // bytes
119 #define MAX_SPLIT_FILES		100
120 #define MIN_SPLIT_SIZE		100000000
121 #define ISO_SPLIT_DETECT_SIZE	(4ull*GiB)
122 
123 #define DEF_SPLIT_SIZE		4000000000ull //  4 GB (not GiB)
124 #define DEF_SPLIT_SIZE_ISO	0xffff8000ull //  4 GiB - 32 KiB
125 #define DEF_SPLIT_FACTOR	         0ull // not set
126 #define DEF_SPLIT_FACTOR_ISO	    0x8000ull // 32 KiB
127 
128 #define DEF_RECURSE_DEPTH	 10
129 #define MAX_RECURSE_DEPTH	100
130 
131 //
132 ///////////////////////////////////////////////////////////////////////////////
133 ///////////////                       Setup                     ///////////////
134 ///////////////////////////////////////////////////////////////////////////////
135 
136 void SetupLib ( int argc, char ** argv, ccp p_progname, enumProgID prid );
137 void CloseAll();
138 
139 typedef enumError (*check_opt_func) ( int argc, char ** argv, bool mode );
140 
141 enumError CheckEnvOptions ( ccp varname, check_opt_func );
142 
143 //
144 ///////////////////////////////////////////////////////////////////////////////
145 ///////////////                  EXTENDED_ERRORS                ///////////////
146 ///////////////////////////////////////////////////////////////////////////////
147 
148 #undef XPARM
149 #undef XCALL
150 #undef XERROR0
151 #undef XERROR1
152 
153 #if EXTENDED_IO_FUNC
154 
155  #define XPARM ccp func, ccp file, uint line,
156  #define XCALL func,file,line,
157  #define XERROR0 func,file,line,0
158  #define XERROR1 func,file,line,errno
159 
160  #define ResetFile(f,r)		XResetFile	(__FUNCTION__,__FILE__,__LINE__,f,r)
161  #define ClearFile(f,r)		XClearFile	(__FUNCTION__,__FILE__,__LINE__,f,r)
162  #define CloseFile(f,r)		XCloseFile	(__FUNCTION__,__FILE__,__LINE__,f,r)
163  #define SetFileTime(f,s)	XSetFileTime	(__FUNCTION__,__FILE__,__LINE__,f,s)
164  #define OpenFile(f,n,i)	XOpenFile	(__FUNCTION__,__FILE__,__LINE__,f,n,i)
165  #define OpenFileModify(f,n,i)	XOpenFileModify	(__FUNCTION__,__FILE__,__LINE__,f,n,i)
166  #define CheckCreated(f,d,e)	XCheckCreated	(__FUNCTION__,__FILE__,__LINE__,f,d,e)
167  #define CreateFile(f,n,i,o)	XCreateFile	(__FUNCTION__,__FILE__,__LINE__,f,n,i,o)
168  #define OpenStreamFile(f)	XOpenStreamFile	(__FUNCTION__,__FILE__,__LINE__,f)
169  #define SetupSplitFile(f,m,s)	XSetupSplitFile	(__FUNCTION__,__FILE__,__LINE__,f,m,s)
170  #define CreateSplitFile(f,i)	XCreateSplitFile(__FUNCTION__,__FILE__,__LINE__,f,i)
171  #define FindSplitFile(f,i,o)	XFindSplitFile	(__FUNCTION__,__FILE__,__LINE__,f,i,o)
172  #define PrintErrorFT(f,m)	XPrintErrorFT	(__FUNCTION__,__FILE__,__LINE__,f,m)
173  #define AnalyzeWH(f,h,p)	XAnalyzeWH	(__FUNCTION__,__FILE__,__LINE__,f,h,p)
174  #define TellF(f)		XTellF		(__FUNCTION__,__FILE__,__LINE__,f)
175  #define SeekF(f,o)		XSeekF		(__FUNCTION__,__FILE__,__LINE__,f,o)
176  #define SetSizeF(f,s)		XSetSizeF	(__FUNCTION__,__FILE__,__LINE__,f,s)
177  #define PreallocateF(f,o,s)	XPreallocateF	(__FUNCTION__,__FILE__,__LINE__,f,o,s)
178  #define ReadF(f,b,c)		XReadF		(__FUNCTION__,__FILE__,__LINE__,f,b,c)
179  #define WriteF(f,b,c)		XWriteF		(__FUNCTION__,__FILE__,__LINE__,f,b,c)
180  #define ReadAtF(f,o,b,c)	XReadAtF	(__FUNCTION__,__FILE__,__LINE__,f,o,b,c)
181  #define WriteAtF(f,o,b,c)	XWriteAtF	(__FUNCTION__,__FILE__,__LINE__,f,o,b,c)
182  #define WriteZeroAtF(f,o,c)	XWriteZeroAtF	(__FUNCTION__,__FILE__,__LINE__,f,o,c)
183  #define ZeroAtF(f,o,c)		XZeroAtF	(__FUNCTION__,__FILE__,__LINE__,f,o,c)
184  #define CreateOutFile(o,f,m,w)	XCreateOutFile	(__FUNCTION__,__FILE__,__LINE__,o,f,m,w)
185  #define CloseOutFile(o,s)	XCloseOutFile	(__FUNCTION__,__FILE__,__LINE__,o,s)
186  #define RemoveOutFile(o)	XRemoveOutFile	(__FUNCTION__,__FILE__,__LINE__,o)
187 
188 #else
189 
190  #define XPARM
191  #define XCALL
192  #define XERROR0 __FUNCTION__,__FILE__,__LINE__,0
193  #define XERROR1 __FUNCTION__,__FILE__,__LINE__,errno
194 
195  #define ResetFile(f,r)		XResetFile	(f,r)
196  #define ClearFile(f,r)		XClearFile	(f,r)
197  #define CloseFile(f,r)		XCloseFile	(f,r)
198  #define SetFileTime(f,s)	XSetFileTime	(f,s)
199  #define OpenFile(f,n,i)	XOpenFile	(f,n,i)
200  #define OpenFileModify(f,n,i)	XOpenFileModify	(f,n,i)
201  #define CheckCreated(f,d,e)	XCheckCreated	(f,d,e)
202  #define CreateFile(f,n,i,o)	XCreateFile	(f,n,i,o)
203  #define OpenStreamFile(f)	XOpenStreamFile	(f)
204  #define SetupSplitFile(f,m,s)	XSetupSplitFile	(f,m,s)
205  #define CreateSplitFile(f,i)	XCreateSplitFile(f,i)
206  #define FindSplitFile(f,i,o)	XFindSplitFile	(f,i,o)
207  #define PrintErrorFT(f,m)	XPrintErrorFT	(f,m)
208  #define AnalyzeWH(f,h,p)	XAnalyzeWH	(f,h,p)
209  #define TellF(f)		XTellF		(f)
210  #define SeekF(f,o)		XSeekF		(f,o)
211  #define SetSizeF(f,s)		XSetSizeF	(f,s)
212  #define PreallocateF(f,o,s)	XPreallocateF	(f,o,s)
213  #define ReadF(f,b,c)		XReadF		(f,b,c)
214  #define WriteF(f,b,c)		XWriteF		(f,b,c)
215  #define ReadAtF(f,o,b,c)	XReadAtF	(f,o,b,c)
216  #define WriteAtF(f,o,b,c)	XWriteAtF	(f,o,b,c)
217  #define WriteZeroAtF(f,o,c)	XWriteZeroAtF	(f,o,c)
218  #define ZeroAtF(f,o,c)		XZeroAtF	(f,o,c)
219  #define CreateOutFile(o,f,m,w)	XCreateOutFile	(o,f,m,w)
220  #define CloseOutFile(o,s)	XCloseOutFile	(o,s)
221  #define RemoveOutFile(o)	XRemoveOutFile	(o)
222 
223 #endif
224 
225 //
226 ///////////////////////////////////////////////////////////////////////////////
227 ///////////////			terminal cap			///////////////
228 ///////////////////////////////////////////////////////////////////////////////
229 
230 extern u32 opt_width;
231 int ScanOptWidth ( ccp source ); // returns '1' on error, '0' else
232 
233 int GetTermWidth ( int default_value, int min_value );
234 int GetTermWidthFD ( int fd, int default_value, int min_value );
235 
236 //
237 ///////////////////////////////////////////////////////////////////////////////
238 ///////////////			    timer			///////////////
239 ///////////////////////////////////////////////////////////////////////////////
240 
241 u32 GetTimerMSec();
242 ccp PrintMSec ( char * buf, int bufsize, u32 msec, bool PrintMSec );
243 
244 //
245 ///////////////////////////////////////////////////////////////////////////////
246 ///////////////			 device support			///////////////
247 ///////////////////////////////////////////////////////////////////////////////
248 
249 u32 GetHSS ( int fd, u32 default_value );
250 off_t GetBlockDevSize ( int fd );
251 
252 //
253 ///////////////////////////////////////////////////////////////////////////////
254 ///////////////			commands			///////////////
255 ///////////////////////////////////////////////////////////////////////////////
256 
257 #define COMMAND_NAME_MAX 100
258 
259 typedef struct CommandTab_t
260 {
261     s64			id;		// id
262     ccp			name1;		// first name
263     ccp			name2;		// NULL or second name
264     s64			opt;		// option
265 
266 } CommandTab_t;
267 
268 typedef s64 (*CommandCallbackFunc)
269 (
270     void		* param,	// NULL or user defined parameter
271     ccp			name,		// normalized name of option
272     const CommandTab_t	* cmd_tab,	// valid pointer to command table
273     const CommandTab_t	* cmd,		// valid pointer to found command
274     char		prefix,		// 0 | '-' | '+' | '='
275     s64			result		// current value of result
276 );
277 
278 const CommandTab_t * ScanCommand
279 (
280     int			* res_abbrev,	// NULL or pointer to result 'abbrev_count'
281     ccp			arg,		// argument to scan
282     const CommandTab_t	* cmd_tab	// valid pointer to command table
283 );
284 
285 s64 ScanCommandList
286 (
287     ccp			arg,		// argument to scan
288     const CommandTab_t	* cmd_tab,	// valid pointer to command table
289     CommandCallbackFunc	func,		// NULL or calculation function
290     bool		allow_prefix,	// allow '-' | '+' | '=' as prefix
291     u32			max_number,	// allow numbers < 'max_number' (0=disabled)
292     s64			result		// start value for result
293 );
294 
295 enumError ScanCommandListFunc
296 (
297     ccp			arg,		// argument to scan
298     const CommandTab_t	* cmd_tab,	// valid pointer to command table
299     CommandCallbackFunc	func,		// calculation function
300     void		* param,	// used define parameter for 'func'
301     bool		allow_prefix	// allow '-' | '+' | '=' as prefix
302 );
303 
304 s64 ScanCommandListMask
305 (
306     ccp			arg,		// argument to scan
307     const CommandTab_t	* cmd_tab	// valid pointer to command table
308 );
309 
310 void PrintCommandError
311 (
312     const CommandTab_t	* cmd_tab,	// NULL or pointer to command table
313     ccp			cmd_arg,	// analyzed command
314     int			cmd_stat,	// status of ScanCommand()
315     ccp			object		// NULL or object for error messages
316 					//	default= 'command'
317 );
318 
319 //
320 ///////////////////////////////////////////////////////////////////////////////
321 ///////////////			Open File Mode			///////////////
322 ///////////////////////////////////////////////////////////////////////////////
323 
324 typedef enum enumIOMode
325 {
326 	IOM_IS_WBFS_PART	= 0x01, // is a WBFS partition
327 	IOM_IS_IMAGE		= 0x02, // is a disc image (PLAIN, WDF, CISO, ...)
328 	IOM_IS_WIA		= 0x04, // is a WIA file
329 
330 	IOM__IS_MASK		= 0x07,
331 	IOM__IS_DEFAULT		= 0,
332 
333 	IOM_FORCE_STREAM	= IOM__IS_MASK + 1,
334 	IOM_NO_STREAM		= 0
335 
336 } enumIOMode;
337 
338 extern int opt_direct;
339 extern enumIOMode opt_iomode;
340 void ScanIOMode ( ccp arg );
341 
342 //-----------------------------------------------------------------------------
343 
344 typedef enum enumOFT // open file mode
345 {
346     OFT_UNKNOWN,		// not specified yet
347 
348     OFT_PLAIN,			// plain (ISO) file
349     OFT_WDF,			// WDF file
350     OFT_CISO,			// CISO file
351     OFT_WBFS,			// WBFS disc
352     OFT_WIA,			// WIA file
353     OFT_FST,			// file system
354 
355     OFT__N,			// number of variants
356     OFT__DEFAULT = OFT_WBFS	// default value
357 
358 } enumOFT;
359 
360 //-----------------------------------------------------------------------------
361 
362 typedef enum attribOFT // OFT attributes
363 {
364     OFT_A_READ		= 0x01,		// format can be read
365     OFT_A_WRITE		= 0x02,		// format can be written
366     OFT_A_MODIFY	= 0x04,		// format can be modified
367     OFT_A_EXTEND	= 0x08,		// format can be extended
368     OFT_A_FST		= 0x10,		// format is an extracted file system
369     OFT_A_COMPR		= 0x20,		// format uses compression
370     OFT_A_NOSIZE	= 0x40,		// format has no file size info
371     OFT_A_LOADER	= 0x80,		// used by USB/SD loaders
372 
373 } attribOFT;
374 
375 //-----------------------------------------------------------------------------
376 
377 typedef struct OFT_info_t
378 {
379     enumOFT		oft;	// = index
380     attribOFT		attrib;	// attributes
381     enumIOMode		iom;	// preferred IO mode
382 
383     ccp			name;	// name
384     ccp			option;	// option to force output format
385     ccp			ext1;	// standard file extension (maybe an empty string)
386     ccp			ext2;	// NULL or alternative file extension
387     ccp			info;	// short text info
388 
389 } OFT_info_t;
390 
391 //-----------------------------------------------------------------------------
392 
393 extern const OFT_info_t oft_info[OFT__N+1];
394 extern const CommandTab_t ImageTypeTab[];
395 extern enumOFT output_file_type;
396 extern uint opt_wdf_version;
397 extern uint opt_wdf_align;
398 extern int opt_truncate;
399 
400 enumOFT CalcOFT ( enumOFT force, ccp fname_dest, ccp fname_src, enumOFT def );
401 
402 //
403 ///////////////////////////////////////////////////////////////////////////////
404 ///////////////			Memory Map			///////////////
405 ///////////////////////////////////////////////////////////////////////////////
406 
407 typedef struct MemMapItem_t
408 {
409     u64		off;		// offset
410     u64		size;		// size
411     u8		overlap;	// system info: item overlaps other items
412     u8		index;		// user defined index
413     char	info[62];	// user defined info text
414 
415 } MemMapItem_t;
416 
417 //-----------------------------------------------------------------------------
418 
419 typedef struct MemMap_t
420 {
421     MemMapItem_t ** field;	// pointer to the item field
422     uint	used;		// number of used titles in the item field
423     uint	size;		// number of allocated pointer in 'field'
424     u64		begin;		// first address
425 
426 } MemMap_t;
427 
428 //-----------------------------------------------------------------------------
429 //	Memory maps allow duplicate entries.
430 //	The off+size pair is used as key.
431 //	The entries are sorted by off and size (small values first).
432 //-----------------------------------------------------------------------------
433 
434 void InitializeMemMap ( MemMap_t * mm );
435 void ResetMemMap ( MemMap_t * mm );
436 
437 MemMapItem_t * FindMemMap
438 (
439     // returns NULL or the pointer to the one! matched key (={off,size})
440 
441     MemMap_t		* mm,
442     off_t		off,
443     off_t		size
444 );
445 
446 uint InsertMemMapIndex
447 (
448     // returns the index of the new item
449 
450     MemMap_t		* mm,		// mem map pointer
451     off_t		off,		// offset of area
452     off_t		size		// size of area
453 );
454 
455 MemMapItem_t * InsertMemMap
456 (
457     // returns a pointer to a new item (never NULL)
458 
459     MemMap_t		* mm,		// mem map pointer
460     off_t		off,		// offset of area
461     off_t		size		// size of area
462 );
463 
464 MemMapItem_t * InsertMemMapTie
465 (
466     // returns a pointer to a new or existing item (never NULL)
467 
468     MemMap_t		* mm,		// mem map pointer
469     off_t		off,		// offset of area
470     off_t		size		// size of area
471 );
472 
473 void InsertMemMapWrapper
474 (
475     void		* param,	// user defined parameter
476     u64			offset,		// offset of object
477     u64			size,		// size of object
478     ccp			info		// info about object
479 );
480 
481 struct wd_disc_t;
482 void InsertDiscMemMap
483 (
484     MemMap_t		* mm,		// valid memore map pointer
485     struct wd_disc_t	* disc		// valid disc pointer
486 );
487 
488 // Remove all entires with key. Return number of delete entries
489 //uint RemoveMemMap ( MemMap_t * mm, off_t off, off_t size );
490 
491 // Return the index of the found or next item
492 uint FindMemMapHelper ( MemMap_t * mm, off_t off, off_t size );
493 
494 // Calculate overlaps. Return number of items with overlap.
495 uint CalCoverlapMemMap ( MemMap_t * mm );
496 
497 // Print out memory map
498 void PrintMemMap ( MemMap_t * mm, FILE * f, int indent, ccp info_head );
499 
500 //
501 ///////////////////////////////////////////////////////////////////////////////
502 ///////////////			   File Map			///////////////
503 ///////////////////////////////////////////////////////////////////////////////
504 
505 typedef struct FileMapItem_t
506 {
507     u64		src_off;	// offset of source
508     u64		dest_off;	// offset of dest
509     u64		size;		// size
510 
511 } FileMapItem_t;
512 
513 //-----------------------------------------------------------------------------
514 
515 typedef struct FileMap_t
516 {
517     FileMapItem_t * field;	// pointer to the item field
518     uint	used;		// number of used titles in the item field
519     uint	size;		// number of allocated pointer in 'field'
520 
521 } FileMap_t;
522 
523 //-----------------------------------------------------------------------------
524 
525 void InitializeFileMap ( FileMap_t * mm );
526 void ResetFileMap ( FileMap_t * mm );
527 
528 const FileMapItem_t * AppendFileMap
529 (
530     // returns the modified or appended item
531 
532     FileMap_t	*fm,		// file map pointer
533     u64		src_off,	// offset of source
534     u64		dest_off,	// offset of dest
535     u64		size		// size
536 );
537 
538 uint CombineFileMaps
539 (
540     FileMap_t		*fm,	 // resulting filemap
541     bool		init_fm, // true: initialize 'fm', false: reset 'fm'
542     const FileMap_t	*fm1,	 // first source filemap
543     const FileMap_t	*fm2	 // second source filemap
544 );
545 
546 //
547 ///////////////////////////////////////////////////////////////////////////////
548 ///////////////			file support			///////////////
549 ///////////////////////////////////////////////////////////////////////////////
550 // [[2do]] [[ft-id]]
551 
552 typedef enum enumFileType
553 {
554     // 1. file types
555 
556 	FT_UNKNOWN	=      0,  // not analyzed yet
557 
558 	FT_ID_DIR	= 0x0001,  // is a directory
559 	FT_ID_FST	= 0x0002,  // is a directory with a FST
560 	FT_ID_WBFS	= 0x0004,  // file is a WBFS
561 	FT_ID_GC_ISO	= 0x0008,  // file is a GC ISO image
562 	FT_ID_WII_ISO	= 0x0010,  // file is a WII ISO image
563 
564 	// special files
565 
566 	FT_ID_DOL	= 0x0020,  // file is a DOL file
567 	FT_ID_CERT_BIN	= 0x0040,  // 'cert.bin' like file
568 	FT_ID_TIK_BIN	= 0x0080,  // 'ticket.bin' like file
569 	FT_ID_TMD_BIN	= 0x0100,  // 'tmd.bin' like file
570 	FT_ID_HEAD_BIN	= 0x0200,  // 'header.bin' like file
571 	FT_ID_BOOT_BIN	= 0x0400,  // 'boot.bin' like file
572 	FT_ID_FST_BIN	= 0x0800,  // 'fst.bin' like file
573 	FT_ID_PATCH	= 0x1000,  // wit patch file
574 	FT_ID_OTHER	= 0x2000,  // unknown file
575 
576 	 FT__SPC_MASK	= 0x3fe0,  // mask of all special files
577 	 FT__ID_MASK	= 0x3fff,  // mask of all 'FT_ID_' values
578 
579     // 2. attributes
580 
581 	FT_A_ISO	= 0x00010000,  // file is some kind of an ISO image
582 	FT_A_GC_ISO	= 0x00020000,  // file is some kind of a GC ISO image
583 	FT_A_WII_ISO	= 0x00040000,  // file is some kind of a WII ISO image
584 
585 	FT_A_WDISC	= 0x00100000,  // flag: specific disc of a WBFS file
586 	FT_A_WDF	= 0x00200000,  // flag: file is a packed WDF
587 	FT_A_WIA	= 0x00400000,  // flag: file is a packed WIA
588 	FT_A_CISO	= 0x00800000,  // flag: file is a packed CISO
589 	FT_A_REGFILE	= 0x01000000,  // flag: file is a regular file
590 	FT_A_BLOCKDEV	= 0x02000000,  // flag: file is a block device
591 	FT_A_CHARDEV	= 0x04000000,  // flag: file is a block device
592 	FT_A_SEEKABLE	= 0x08000000,  // flag: using of seek() is possible
593 	FT_A_WRITING	= 0x10000000,  // is opened for writing
594 	FT_A_PART_DIR	= 0x20000000,  // FST is a partition
595 
596 	 FT__A_MASK	= 0x3ff70000,  // mask of all 'FT_A_' values
597 
598     // 3. mask of all 'FT_ values
599 
600 	 FT__MASK	= FT__ID_MASK | FT__A_MASK,
601 
602 } enumFileType;
603 
604 //-----------------------------------------------------------------------------
605 
606 typedef struct FileCache_t
607 {
608 	off_t	off;			// file offset
609 	size_t	count;			// size of cached data
610 	ccp	data;			// pointer to cached data (alloced)
611 	struct FileCache_t * next;	// NULL or pointer to next element
612 
613 } FileCache_t;
614 
615 //-----------------------------------------------------------------------------
616 
617 typedef struct FileAttrib_t
618 {
619 	// attributes of a (virtual) file
620 
621 	off_t  size;	// size
622 	time_t itime;	// itime
623 	time_t mtime;	// mtime
624 	time_t ctime;	// ctime
625 	time_t atime;	// atime
626 
627 } FileAttrib_t;
628 
629 //---------------
630 
631 struct WDiscInfo_t;
632 struct wbfs_inode_info_t;
633 
634 FileAttrib_t * NormalizeFileAttrib
635 (
636     FileAttrib_t	* fa		// valid attribute
637 );
638 
639 FileAttrib_t * MaxFileAttrib
640 (
641     FileAttrib_t	* dest,		// valid source and destination attribute
642     const FileAttrib_t	* src		// NULL or second source attribute
643 );
644 
645 FileAttrib_t * CopyFileAttrib
646 (
647     FileAttrib_t	* dest,		// valid destination attribute
648     const FileAttrib_t	* src		// valid source attribute
649 );
650 
651 FileAttrib_t * CopyFileAttribStat
652 (
653     FileAttrib_t	* dest,		// valid destination attribute
654     const struct stat	* src,		// NULL or source
655     bool		maximize	// true store max values to 'dest'
656 );
657 
658 FileAttrib_t * CopyFileAttribDiscInfo
659 		( FileAttrib_t * dest, const struct WDiscInfo_t * src );
660 FileAttrib_t * CopyFileAttribInode
661 		( FileAttrib_t * dest, const struct wbfs_inode_info_t * src, off_t size );
662 
663 
664 //-----------------------------------------------------------------------------
665 
666 typedef struct File_t
667 {
668     //--- file handles and status
669 
670     int		fd;			// file handle, -1=invalid
671     FILE	* fp;			// stream handle, 0=invalid
672     struct stat st;			// file status after OpenFile()
673     int		active_open_flags;	// active open flags.
674     enumFileType ftype;			// the type of the file
675     bool	is_reading;		// file opened in read mode;
676     bool	is_writing;		// file opened in write mode;
677     bool	is_stdfile;		// file is stdin or stdout
678     bool	seek_allowed;		// seek is allowed
679 					// (regular file or block device)
680     id6_t	id6_src;		// ID6 of the src iso image
681     id6_t	id6_dest;		// patched ID6 for output
682     int		slot;			// >=0: slot number for WBFS
683 
684 
685     //--- virtual file atributes, initialized by a copy of 'struct stat st'
686 
687     FileAttrib_t fatt;	// size, itime, mtime, ctime, atime
688 
689 
690     //--- file names, alloced
691 
692     ccp		fname;			// current virtual filename
693     ccp		path;			// not NULL: path of real file (not realpath)
694     ccp		rename;			// not NULL: rename rename to fname if closed
695     ccp		outname;		// not NULL: hint for a good output filename
696 					// outname is without path/directory
697 					// or extension
698 
699     //--- options set by user, not resetted by ResetFile()
700 
701     int		open_flags;		// proposed open flags; if zero then ignore
702     bool	disable_errors;		// don't print error messages
703     bool	create_directory;	// create direcotries automatically
704     bool	allow_direct_io;	// allow the usage of O_DIRECT
705     int		already_created_mode;	// 0:ignore, 1:warn, 2:error+abort
706 
707 
708     //--- error codes
709 
710     enumError	last_error;		// error code of last operation
711     enumError	max_error;		// max error code since open/create
712 
713 
714     //--- offset handling
715 
716     off_t	file_off;		// current real file offset
717     off_t	cur_off;		// current virtual file offset
718     off_t	max_off;		// max file offset
719     off_t	prealloc_size;		// if >0: size of preallocation
720     int		read_behind_eof;	// 0: disallow
721 					// 1: allow + print warning + switch to '2'
722 					// 2: allow silently
723 
724     //--- read cache
725 
726     bool	is_caching;		// true if cache is active
727     FileCache_t	* cache;		// data cache
728     FileCache_t	* cur_cache;		// pointer to current cache entry
729     off_t	cache_info_off;		// info for cache missed message
730     size_t	cache_info_size;	// info for cache missed message
731 
732 
733     //--- prealloc map
734 
735     bool	prealloc_done;		// true if preallocation was done
736     MemMap_t	prealloc_map;		// store prealloc areas until first write
737 
738 
739     //--- split file support
740 
741     struct File_t **split_f;		// list with pointers to the split files
742     int		split_used;		// number of used split files in 'split_f'
743     off_t	split_off;		// if split file: offset in combined file
744     off_t	split_filesize;		// if split file: size of split file
745 					// max file size for new files
746     ccp		split_fname_format;	// format with '%01u' at the end for 'fname'
747     ccp		split_rename_format;	// format with '%01u' at the end for 'rename'
748 
749 
750     //--- wbfs vars
751 
752     u32		sector_size;		// size of one hd sector, default = 512
753 
754 
755     //--- statistics
756 
757     u32		tell_count;		// number of successfull tell operations
758     u32		seek_count;		// number of successfull seek operations
759     u32		setsize_count;		// number of successfull set-size operations
760     u32		read_count;		// number of successfull read operations
761     u32		write_count;		// number of successfull write operations
762     u64		bytes_read;		// number of bytes read
763     u64		bytes_written;		// number of bytes written
764 
765 } File_t;
766 
767 //-----------------------------------------------------------------------------
768 
769 // initialize, reset and close files
770 void InitializeFile	( File_t * f );
771 enumError XResetFile	( XPARM File_t * f, bool remove_file );
772 enumError XClearFile	( XPARM File_t * f, bool remove_file );
773 enumError XCloseFile	( XPARM File_t * f, bool remove_file );
774 enumError XSetFileTime	( XPARM File_t * f, FileAttrib_t * set_time );
775 
776 // open files
777 enumError XOpenFile       ( XPARM File_t * f, ccp fname, enumIOMode iomode );
778 enumError XOpenFileModify ( XPARM File_t * f, ccp fname, enumIOMode iomode );
779 enumError XCreateFile     ( XPARM File_t * f, ccp fname, enumIOMode iomode, int overwrite );
780 enumError XCheckCreated   ( XPARM             ccp fname, bool disable_errors, enumError err_code );
781 enumError XOpenStreamFile ( XPARM File_t * f );
782 enumError XSetupSplitFile ( XPARM File_t *f, enumOFT oft, off_t file_size );
783 enumError XCreateSplitFile( XPARM File_t *f, uint split_idx );
784 enumError XFindSplitFile  ( XPARM File_t *f, uint * index, off_t * off );
785 
786 // copy filedesc
787 void CopyFD ( File_t * dest, File_t * src );
788 
789 // read cache support
790 void ClearCache		 ( File_t * f );
791 void DefineCachedArea    ( File_t * f, off_t off, size_t count );
792 void DefineCachedAreaISO ( File_t * f, bool head_only );
793 
794 struct WDF_Head_t;
795 enumError XAnalyzeWH ( XPARM File_t * f, struct WDF_Head_t * wh, bool print_err );
796 
797 enumError StatFile ( struct stat * st, ccp fname, int fd );
798 
799 //-----------------------------------------------------------------------------
800 // file io with error messages
801 
802 enumError XTellF	 ( XPARM File_t * f );
803 enumError XSeekF	 ( XPARM File_t * f, off_t off );
804 enumError XSetSizeF	 ( XPARM File_t * f, off_t size );
805 enumError XPreallocateF	 ( XPARM File_t * f, off_t off, off_t size );
806 enumError XReadF	 ( XPARM File_t * f,                  void * iobuf, size_t count );
807 enumError XWriteF	 ( XPARM File_t * f,            const void * iobuf, size_t count );
808 enumError XReadAtF	 ( XPARM File_t * f, off_t off,       void * iobuf, size_t count );
809 enumError XWriteAtF	 ( XPARM File_t * f, off_t off, const void * iobuf, size_t count );
810 enumError XWriteZeroAtF	 ( XPARM File_t * f, off_t off,                     size_t count );
811 enumError XZeroAtF	 ( XPARM File_t * f, off_t off,                     size_t count );
812 
813 //-----------------------------------------------------------------------------
814 // wrapper functions
815 
816 int WrapperReadSector  ( void * handle, u32 lba, u32 count, void * iobuf );
817 int WrapperWriteSector ( void * handle, u32 lba, u32 count, void * iobuf );
818 
819 //-----------------------------------------------------------------------------
820 // split file support
821 
822 int CalcSplitFilename ( char * buf, size_t buf_size, ccp path, enumOFT oft );
823 char * AllocSplitFilename ( ccp path, enumOFT oft );
824 
825 //-----------------------------------------------------------------------------
826 // filename generation
827 
828 char * NormalizeFileName ( char * buf, char * buf_end, ccp source, bool allow_slash );
829 
830 uint ReduceToPathAndType
831 (
832     char	*buf,		// valid return buffer
833     uint	buf_size,	// size of 'buf'
834     ccp		fname		// source: file name
835 );
836 
837 void SetFileName      ( File_t * f, ccp source, bool allow_slash );
838 void GenFileName      ( File_t * f, ccp path, ccp name, ccp title, ccp id6, ccp ext );
839 void GenDestFileName  ( File_t * f, ccp dest, ccp default_name, ccp ext, bool rm_std_ext );
840 void GenImageFileName ( File_t * f, ccp dest, ccp default_name, enumOFT oft );
841 
842 //-----------------------------------------------------------------------------
843 // etc
844 
845 int    GetFD ( const File_t * f );
846 FILE * GetFP ( const File_t * f );
847 char   GetFT ( const File_t * f );
848 
849 bool IsOpenF ( const File_t * f );
850 bool IsSplittedF ( const File_t * f );
851 
852 bool IsDirectory ( ccp fname, bool answer_if_empty );
853 enumError CreatePath ( ccp fname );
854 
855 typedef enum enumFileMode { FM_OTHER, FM_PLAIN, FM_BLKDEV, FM_CHRDEV } enumFileMode;
856 enumFileMode GetFileMode ( mode_t mode );
857 ccp GetFileModeText ( enumFileMode mode, bool longtext, ccp fail_text );
858 
859 #ifdef __CYGWIN__
860     int IsWindowsDriveSpec ( ccp src );
861     int NormalizeFilenameCygwin ( char * buf, size_t bufsize, ccp source );
862     char * AllocNormalizedFilenameCygwin ( ccp source );
863 #endif
864 
865 void SetDest ( ccp arg, bool mkdir );
866 
867 s64 GetFileSize
868 (
869     ccp			path1,		// NULL or part 1 of path
870     ccp			path2,		// NULL or part 2 of path
871     s64			not_found_val,	// return value if no regular file found
872     FileAttrib_t	* fatt,		// not NULL: store file attributes
873     bool		fatt_max	// true: store max values to 'fatt'
874 );
875 
876 enumError LoadFile
877 (
878     ccp			path1,		// NULL or part #1 of path
879     ccp			path2,		// NULL or part #2 of path
880     size_t		skip,		// skip num of bytes before reading
881     void		* data,		// destination buffer, size = 'size'
882     size_t		size,		// size to read
883     bool		silent,		// true: suppress printing of error messages
884     FileAttrib_t	* fatt,		// not NULL: store file attributes
885     bool		fatt_max	// true: store max values to 'fatt'
886 );
887 
888 enumError LoadFileAlloc
889 (
890     ccp			path1,		// NULL or part #1 of path
891     ccp			path2,		// NULL or part #2 of path
892     size_t		skip,		// skip num of bytes before reading
893     u8			** res_data,	// result: free existing data, store ptr to alloc data
894 					// always one more byte is alloced and set to NULL
895     size_t		*  res_size,	// result: size of 'res_data'
896     size_t		max_size,	// >0: a file size limit
897     bool		silent,		// true: suppress printing of error messages
898     FileAttrib_t	* fatt,		// not NULL: store file attributes
899     bool		fatt_max	// true: store max values to 'fatt'
900 );
901 
902 enumError CheckCreateFile
903 (
904     // returns:
905     //   ERR_WARNING:		source is "-" (stdout) => 'st' is zeroed
906     //   ERR_ALREADY_EXISTS:	file already exists
907     //   ERR_WRONG_FILE_TYPE:	file exists and file type is wrong
908     //   ERR_OK:		file not exist or can be overwritten
909 
910     ccp		fname,		// filename to open
911     bool	detect_stdout,	// true: detect "-" as stdout
912     bool	overwrite,	// true: overwriting is allowed
913     bool	silent,		// true: suppress error messages
914     struct stat	*st		// not NULL: store file status here
915 );
916 
917 enumError SaveFile
918 (
919     ccp			path1,		// NULL or part #1 of path
920     ccp			path2,		// NULL or part #2 of path
921     bool		overwrite,	// true: overwrite existing files
922     bool		create_dir,	// true: create path automatically
923     const void		* data,		// pointer to data
924     size_t		size,		// size of 'data'
925     bool		silent		// true: suppress error messages
926 );
927 
928 //-----------------------------------------------------------------------------
929 
930 void ClearFileID
931 (
932     File_t		* f
933 );
934 
935 void SetFileID
936 (
937     File_t		* f,
938     const void		* new_id,
939     int			id_length
940 );
941 
942 bool SetPatchFileID
943 (
944     File_t		* f,
945     const void		* new_id,
946     int			id_length
947 );
948 
949 //-----------------------------------------------------------------------------
950 
951 void mark_used ( ccp name, ... );
952 #define MARK_USED(...) mark_used(0,__VA_ARGS__)
953 
954 void option_deprecated ( ccp name );
955 void option_ignored ( ccp name );
956 
957 //-----------------------------------------------------------------------------
958 
959 bool HaveFileSystemMapSupport();
960 
961 enumError GetFileSystemMap
962 (
963     FileMap_t		* fm,		// file map
964     bool		init_fm,	// true: initialize 'fm', false: reset 'fm'
965     File_t		* file		// file to analyze
966 );
967 
968 //
969 ///////////////////////////////////////////////////////////////////////////////
970 ///////////////		    preallocation options		///////////////
971 ///////////////////////////////////////////////////////////////////////////////
972 
973 typedef enum PreallocMode
974 {
975     PREALLOC_OFF,	// preallocation is disabled
976     PREALLOC_SMART,	// enable smart preallocation
977     PREALLOC_ALL,	// preallocate the whole dest file
978 
979     PREALLOC_DEFAULT	 = PREALLOC_ALL, // default
980     PREALLOC_OPT_DEFAULT = PREALLOC_ALL  // default if --prealloc is set without param
981 
982 } PreallocMode;
983 
984 extern PreallocMode prealloc_mode;
985 int ScanPreallocMode ( ccp arg );
986 
987 //
988 ///////////////////////////////////////////////////////////////////////////////
989 ///////////////			string functions		///////////////
990 ///////////////////////////////////////////////////////////////////////////////
991 
992 ccp PathCatPP  ( char * buf, size_t bufsize, ccp path1, ccp path2 );
993 ccp PathCatPPE ( char * buf, size_t bufsize, ccp path1, ccp path2, ccp ext );
994 char * SetupDirPath ( char * buf, size_t bufsize, ccp src_path );
995 
996 int PathCMP ( ccp path1, ccp path2 );
997 int NintendoCMP ( ccp path1, ccp path2 );
998 
999 //-----
1000 
1001 int NormalizeIndent ( int indent );
1002 
1003 //-----
1004 
1005 int CheckIDHelper // helper for all other id functions
1006 (
1007 	const void	* id,		// valid pointer to test ID
1008 	int		max_len,	// max length of ID, a NULL terminates ID too
1009 	bool		allow_any_len,	// if false, only length 4 and 6 are allowed
1010 	bool		ignore_case,	// lower case letters are allowed
1011 	bool		allow_point	// the wildcard '.' is allowed
1012 );
1013 
1014 int CheckID // check up to 7 chars for ID4|ID6
1015 (
1016 	const void	* id,		// valid pointer to test ID
1017 	bool		ignore_case,	// lower case letters are allowed
1018 	bool		allow_point	// the wildcard '.' is allowed
1019 );
1020 
1021 bool CheckID4 // check exact 4 chars
1022 (
1023 	const void	* id,		// valid pointer to test ID
1024 	bool		ignore_case,	// lower case letters are allowed
1025 	bool		allow_point	// the wildcard '.' is allowed
1026 );
1027 
1028 bool CheckID6 // check exact 6 chars
1029 (
1030 	const void	* id,		// valid pointer to test ID
1031 	bool		ignore_case,	// lower case letters are allowed
1032 	bool		allow_point	// the wildcard '.' is allowed
1033 );
1034 
1035 int CountIDChars // count number of valid ID chars, max = 1000
1036 (
1037 	const void	* id,		// valid pointer to test ID
1038 	bool		ignore_case,	// lower case letters are allowed
1039 	bool		allow_point	// the wildcard '.' is allowed
1040 );
1041 
1042 char * ScanID	    ( char * destbuf7, int * destlen, ccp source );
1043 
1044 //-----
1045 
1046 char * ScanNumU32   ( ccp arg, u32 * p_stat, u32 * p_num,            u32 min, u32 max );
1047 char * ScanRangeU32 ( ccp arg, u32 * p_stat, u32 * p_n1, u32 * p_n2, u32 min, u32 max );
1048 
1049 //-----
1050 
1051 extern const u8 HexTab[256];
1052 
1053 char * ScanHexHelper
1054 (
1055     void	* buf,		// valid pointer to result buf
1056     int		buf_size,	// number of byte to read
1057     int		* bytes_read,	// NULL or result: number of read bytes
1058     ccp		arg,		// source string
1059     int		err_level	// error level (print message):
1060 				//	 = 0: don't print errors
1061 				//	>= 1: print syntax errors
1062 				//	>= 2: msg if bytes_read<buf_size
1063 				//	>= 3: msg if arg contains more characters
1064 );
1065 
1066 //-----------------------------------------------------------------------------
1067 
1068 enumError ScanHex
1069 (
1070     void	* buf,		// valid pointer to result buf
1071     int		buf_size,	// number of byte to read
1072     ccp		arg		// source string
1073 );
1074 
1075 //-----------------------------------------------------------------------------
1076 
1077 enumError ScanHexSilent
1078 (
1079     void	* buf,		// valid pointer to result buf
1080     int		buf_size,	// number of byte to read
1081     ccp		arg		// source string
1082 );
1083 
1084 //-----------------------------------------------------------------------------
1085 
1086 void PutLines
1087 (
1088     FILE	* f,		// valid output stream
1089     int		indent,		// indent of output
1090     int		fw,		// field width of output
1091     int		first_line,	// length without prefix of already printed first line
1092     ccp		prefix,		// NULL or prefix for each line
1093     ccp		text		// text to print
1094 );
1095 
1096 void PrintLines
1097 (
1098     FILE	* f,		// valid output stream
1099     int		indent,		// indent of output
1100     int		fw,		// field width of output
1101     int		first_line,	// length without prefix of already printed first line
1102     ccp		prefix,		// NULL or prefix for each line
1103     ccp		format,		// format string for vsnprintf()
1104     ...				// arguments for 'vsnprintf(format,...)'
1105 
1106 )  __attribute__ ((__format__(__printf__,6,7)));
1107 
1108 //
1109 ///////////////////////////////////////////////////////////////////////////////
1110 ///////////////			    scan number			///////////////
1111 ///////////////////////////////////////////////////////////////////////////////
1112 
1113 char * ScanS32
1114 (
1115     // return 'source' on error
1116 
1117     s32		*res_num,		// not NULL: store result (only on success)
1118     ccp		source,			// NULL or source text
1119     uint	default_base		// base for numbers without '0x' prefix
1120 					//  0: C like with octal support
1121 					// 10: standard value for decimal numbers
1122 					// 16: standard value for hex numbers
1123 );
1124 
ScanU32(u32 * res_num,ccp source,uint default_base)1125 static inline char * ScanU32 ( u32 *res_num, ccp source, uint default_base )
1126 	{ return ScanS32((s32*)res_num,source,default_base); }
1127 
1128 //-----------------------------------------------------------------------------
1129 
1130 char * ScanS64
1131 (
1132     // return 'source' on error
1133 
1134     s64		*res_num,		// not NULL: store result (only on success)
1135     ccp		source,			// NULL or source text
1136     uint	default_base		// base for numbers without '0x' prefix
1137 					//  0: C like with octal support
1138 					// 10: standard value for decimal numbers
1139 					// 16: standard value for hex numbers
1140 );
1141 
ScanU64(u64 * res_num,ccp source,uint default_base)1142 static inline char * ScanU64 ( u64 *res_num, ccp source, uint default_base )
1143 	{ return ScanS64((s64*)res_num,source,default_base); }
1144 
1145 //
1146 ///////////////////////////////////////////////////////////////////////////////
1147 ///////////////                     scan size                   ///////////////
1148 ///////////////////////////////////////////////////////////////////////////////
1149 
1150 u64 ScanSizeFactor ( char ch_factor, int force_base );
1151 
1152 char * ScanSizeTerm ( double * num, ccp source,
1153 		      u64 default_factor, int force_base );
1154 
1155 char * ScanSize ( double * num, ccp source,
1156 		  u64 default_factor1, u64 default_factor2, int force_base );
1157 
1158 char * ScanSizeU32 ( u32 * num, ccp source,
1159 		     u64 default_factor1, u64 default_factor2, int force_base );
1160 
1161 char * ScanSizeU64 ( u64 * num, ccp source,
1162 		     u64 default_factor1, u64 default_factor2, int force_base );
1163 
1164 enumError ScanSizeOpt
1165 	( double * num, ccp source,
1166 	  u64 default_factor1, u64 default_factor2, int force_base,
1167 	  ccp opt_name, u64 min, u64 max, bool print_err );
1168 
1169 enumError ScanSizeOptU64
1170 	( u64 * num, ccp source, u64 default_factor1, int force_base,
1171 	  ccp opt_name, u64 min, u64 max, u32 multiple, u32 pow2, bool print_err );
1172 
1173 enumError ScanSizeOptU32
1174 	( u32 * num, ccp source, u64 default_factor1, int force_base,
1175 	  ccp opt_name, u64 min, u64 max, u32 multiple, u32 pow2, bool print_err );
1176 
1177 //-----------------------------------------------------------------------------
1178 
1179 extern int opt_split;
1180 extern u64 opt_split_size;
1181 
1182 // returns '1' on error, '0' else
1183 int ScanOptSplitSize ( ccp source );
1184 int ScanOptRDepth ( ccp source );
1185 
1186 //
1187 ///////////////////////////////////////////////////////////////////////////////
1188 ///////////////                     sort mode                   ///////////////
1189 ///////////////////////////////////////////////////////////////////////////////
1190 
1191 typedef enum SortMode
1192 {
1193 	SORT_NONE,		// == 0
1194 	SORT_ID,
1195 	SORT_NAME,
1196 	SORT_TITLE,
1197 	SORT_PATH,			// sort path stable with PathCMP()
1198 	SORT_NINTENDO,			// sort path stable with NintendoCMP()
1199 	SORT_FILE,
1200 	SORT_SIZE,
1201 	SORT_OFFSET,
1202 	SORT_REGION,
1203 	SORT_WBFS,
1204 	SORT_NPART,
1205 	SORT_FRAG,
1206 	 SORT_ITIME,
1207 	 SORT_MTIME,
1208 	 SORT_CTIME,
1209 	 SORT_ATIME,
1210 	 SORT_TIME,
1211 	SORT_DEFAULT,			// max value!
1212 	 SORT__MODE_MASK	= 0x1f,
1213 
1214 	SORT_REVERSE		= 0x20,
1215 	SORT__MASK		= SORT_REVERSE | SORT__MODE_MASK,
1216 
1217 	SORT__ERROR		= -1 // not a mode but an error message
1218 
1219 } SortMode;
1220 
1221 extern SortMode sort_mode;
1222 SortMode ScanSortMode ( ccp arg );
1223 int ScanOptSort ( ccp arg );
1224 
1225 //
1226 ///////////////////////////////////////////////////////////////////////////////
1227 ///////////////			options show + unit		///////////////
1228 ///////////////////////////////////////////////////////////////////////////////
1229 
1230 typedef enum ShowMode
1231 {
1232 	//----- base values
1233 
1234 	SHOW__NONE	= 0,
1235 
1236 	SHOW_INTRO	= 0x00000001, // introduction
1237 	SHOW_FHEADER	= 0x00000002, // file header
1238 	SHOW_SLOT	= 0x00000004, // slot info
1239 	SHOW_GEOMETRY	= 0x00000008, // geometry data
1240 	SHOW_D_ID	= 0x00000010, // disc ID
1241 	SHOW_P_ID	= 0x00000020, // partition IDs
1242 	SHOW_P_TAB	= 0x00000040, // partition table
1243 	SHOW_P_INFO	= 0x00000080, // partition info
1244 	SHOW_P_MAP	= 0x00000100, // memory map of partitions
1245 	SHOW_D_MAP	= 0x00000200, // memory map of discs
1246 	SHOW_W_MAP	= 0x00000400, // memory map of WBFS
1247 	SHOW_CERT	= 0x00000800, // certificates info
1248 	SHOW_TICKET	= 0x00001000, // ticket info
1249 	SHOW_TMD	= 0x00002000, // tmd info
1250 	SHOW_USAGE	= 0x00004000, // usage table
1251 	SHOW_FILES	= 0x00008000, // file list
1252 	SHOW_PATCH	= 0x00010000, // patching table
1253 	SHOW_RELOCATE	= 0x00020000, // relocation table
1254 	SHOW_PATH	= 0x00040000, // full path
1255 	SHOW_CHECK	= 0x00080000, // integrity check
1256 
1257 	SHOW_UNUSED	= 0x00100000, // show unused areas
1258 	SHOW_OFFSET	= 0x00200000, // show offsets
1259 	SHOW_SIZE	= 0x00400000, // show size
1260 
1261 	SHOW__ALL	= 0x007fffff,
1262 
1263 	//----- combinations
1264 
1265 	SHOW__ID	= SHOW_D_ID
1266 			| SHOW_P_ID,
1267 
1268 	SHOW__PART	= SHOW_P_INFO
1269 			| SHOW_P_ID
1270 			| SHOW_P_MAP
1271 			| SHOW_CERT
1272 			| SHOW_TICKET
1273 			| SHOW_TMD,
1274 
1275 	SHOW__DISC	= SHOW_FILES
1276 			| SHOW_D_MAP,
1277 
1278 	SHOW__MAP	= SHOW_P_MAP
1279 			| SHOW_D_MAP
1280 			| SHOW_W_MAP,
1281 
1282 	//----- flags
1283 
1284 	SHOW_F_DEC1	= 0x01000000, // prefer DEC, only one of DEC1,HEX1 is set
1285 	SHOW_F_HEX1	= 0x02000000, // prefer HEX, only one of DEC1,HEX1 is set
1286 	SHOW_F_DEC	= 0x04000000, // prefer DEC
1287 	SHOW_F_HEX	= 0x08000000, // prefer HEX,
1288 	SHOW_F__NUM	= 0x0f000000,
1289 
1290 	SHOW_F_HEAD	= 0x01000000, // print header lines
1291 	SHOW_F_PRIMARY	= 0x02000000, // print primary (unpatched) disc
1292 
1293 	//----- etc
1294 
1295 	SHOW__DEFAULT	= (int)0x80000000,
1296 	SHOW__ERROR	= -1 // not a mode but an error message
1297 
1298 } ShowMode;
1299 
1300 extern ShowMode opt_show_mode;
1301 ShowMode ScanShowMode ( ccp arg );
1302 int ScanOptShow ( ccp arg );
1303 
1304 int ConvertShow2PFST
1305 (
1306 	ShowMode show_mode,	// show mode
1307 	ShowMode def_mode	// default mode
1308 );
1309 
1310 //-----------------------------------------------------------------------------
1311 
1312 extern wd_size_mode_t opt_unit;
1313 
1314 wd_size_mode_t ScanUnit ( ccp arg );
1315 int ScanOptUnit ( ccp arg );
1316 
1317 //
1318 ///////////////////////////////////////////////////////////////////////////////
1319 ///////////////             time printing % scanning            ///////////////
1320 ///////////////////////////////////////////////////////////////////////////////
1321 
1322 enum enumPrintTime
1323 {
1324 	PT_USE_ITIME		= 1,
1325 	PT_USE_MTIME		= 2,
1326 	PT_USE_CTIME		= 3,
1327 	PT_USE_ATIME		= 4,
1328 	 PT__USE_MASK		= 7,
1329 
1330 	PT_F_ITIME		= 0x10,
1331 	PT_F_MTIME		= 0x20,
1332 	PT_F_CTIME		= 0x40,
1333 	PT_F_ATIME		= 0x80,
1334 	 PT__F_MASK		= 0xf0,
1335 
1336 	PT_PRINT_DATE		= 0x100,
1337 	PT_PRINT_TIME		= 0x200,
1338 	PT_PRINT_SEC		= 0x300,
1339 	 PT__PRINT_MASK		= 0x300,
1340 
1341 	PT_SINGLE		= 0x1000,
1342 	PT_MULTI		= 0x2000,
1343 	 PT__MULTI_MASK		= PT_SINGLE | PT_MULTI,
1344 
1345 	PT_ENABLED		= 0x10000,
1346 	PT_DISABLED		= 0x20000,
1347 	 PT__ENABLED_MASK	= PT_ENABLED | PT_DISABLED,
1348 
1349 	PT__MASK		= PT__USE_MASK | PT__F_MASK | PT__PRINT_MASK
1350 				  | PT__MULTI_MASK | PT__ENABLED_MASK,
1351 
1352 	PT__DEFAULT		= PT_USE_MTIME | PT_PRINT_DATE,
1353 
1354 	PT__ERROR		= -1
1355 };
1356 
1357 ///////////////////////////////////////////////////////////////////////////////
1358 
1359 #define PT_BUF_SIZE 24
1360 
1361 typedef struct PrintTime_t
1362 {
1363 	int  mode;			// active mode (enumPrintTime)
1364 	int  nelem;			// number of printed elements
1365 	int  wd1;			// width of single column includig leading space
1366 	int  wd;			// width of all columns := nelem * wd1
1367 
1368 	ccp  format;			// format for strftime (single time)
1369 	ccp  undef;			// text for single undefined times
1370 
1371 	char head[4*PT_BUF_SIZE];	// text of table header includig leading space
1372 	char fill[4*PT_BUF_SIZE];	// 'wd' spaces, can be used as filler
1373 	char tbuf[4*PT_BUF_SIZE];	// the formatted time includig leading space
1374 
1375 } PrintTime_t;
1376 
1377 ///////////////////////////////////////////////////////////////////////////////
1378 
1379 extern int opt_print_time;
1380 
1381 int  ScanPrintTimeMode	( ccp argv, int prev_mode );
1382 int  ScanAndSetPrintTimeMode ( ccp argv );
1383 int  SetPrintTimeMode	( int prev_mode, int new_mode );
1384 int  EnablePrintTime	( int opt_time );
1385 void SetTimeOpt		( int opt_time );
1386 
1387 void	SetupPrintTime	( PrintTime_t * pt, int opt_time );
1388 char *	PrintTime	( PrintTime_t * pt, const FileAttrib_t * fa );
1389 time_t	SelectTime	( const FileAttrib_t * fa, int opt_time );
1390 SortMode SelectSortMode	( int opt_time );
1391 time_t	ScanTime	( ccp arg );
1392 
1393 //
1394 ///////////////////////////////////////////////////////////////////////////////
1395 ///////////////              string fields & lists              ///////////////
1396 ///////////////////////////////////////////////////////////////////////////////
1397 
1398 typedef struct IdItem_t
1399 {
1400     char	id6[7];		// NULL or id6, null terminated
1401     char	flag;		// a user defined flag
1402     time_t	mtime;		// NULL or mtime of source file
1403     char	arg[0];		// additional string, null terminated
1404 
1405 } IdItem_t;
1406 
1407 //-----------------------------------------------------------------------------
1408 
1409 typedef struct IdField_t
1410 {
1411     IdItem_t	** field;	// pointer to the string field
1412     uint	used;		// number of used titles in the title field
1413     uint	size;		// number of allocated pointer in 'field'
1414 
1415 } IdField_t;
1416 
1417 //-----------------------------------------------------------------------------
1418 
1419 void InitializeIdField ( IdField_t * idf );
1420 void ResetIdField ( IdField_t * idf );
1421 
1422 // return: pointer to matched key if the key is in the field.
1423 const IdItem_t * FindIdField ( IdField_t * idf, ccp key );
1424 
1425 // return: true if item inserted/deleted
1426 bool InsertIdField ( IdField_t * idf, void * id6, char flag, time_t mtime, ccp key );
1427 bool RemoveIdField ( IdField_t * idf, ccp key );
1428 
1429 // dump list
1430 void DumpIdField ( FILE *f, int indent, const IdField_t * idf );
1431 
1432 //
1433 ///////////////////////////////////////////////////////////////////////////////
1434 ///////////////			struct StringField_t		///////////////
1435 ///////////////////////////////////////////////////////////////////////////////
1436 
1437 typedef struct StringField_t
1438 {
1439     ccp		* field;	// pointer to the string field
1440     uint	used;		// number of used titles in the title field
1441     uint	size;		// number of allocated pointer in 'field'
1442 
1443 } StringField_t;
1444 
1445 //-----------------------------------------------------------------------------
1446 
1447 void InitializeStringField ( StringField_t * sf );
1448 void ResetStringField ( StringField_t * sf );
1449 
1450 // return: pointer to matched key if the key is in the field.
1451 ccp FindStringField ( StringField_t * sf, ccp key );
1452 
1453 // return: true if item inserted/deleted
1454 bool InsertStringField ( StringField_t * sf, ccp key,  bool move_key );
1455 bool RemoveStringField ( StringField_t * sf, ccp key );
1456 
1457 // special id6 support
1458 IdItem_t * InsertStringID6 ( StringField_t * sf, void * id6, char flag, ccp arg );
1459 
1460 // append at the end an do not sort
1461 void AppendStringField ( StringField_t * sf, ccp key, bool move_key );
1462 
1463 // return the index of the (next) item
1464 uint FindStringFieldHelper ( StringField_t * sf, bool * found, ccp key );
1465 
1466 // file support
1467 enumError LoadStringField ( StringField_t * sf, bool sort, ccp filename, bool silent );
1468 enumError SaveStringField ( StringField_t * sf, ccp filename, bool rm_if_empty );
1469 
1470 //
1471 ///////////////////////////////////////////////////////////////////////////////
1472 ///////////////			struct ParamField_t		///////////////
1473 ///////////////////////////////////////////////////////////////////////////////
1474 
1475 typedef enum ParamFieldType_t
1476 {
1477     PFT_NONE,
1478     PFT_ALIGN,
1479 
1480 } ParamFieldType_t;
1481 
1482 //-----------------------------------------------------------------------------
1483 
1484 typedef struct ParamFieldItem_t
1485 {
1486     ccp			key;		// string key of object
1487     uint		count;		// a free counter
1488     uint		num;		// a free number
1489 
1490 } ParamFieldItem_t;
1491 
1492 //-----------------------------------------------------------------------------
1493 
1494 typedef struct ParamField_t
1495 {
1496     ParamFieldItem_t	* list;		// pointer to the item list
1497     uint		used;		// number of used elements of 'list'
1498     uint		size;		// number of allocated  elements of 'list'
1499     ParamFieldType_t	pft;		// type of list
1500 
1501 } ParamField_t;
1502 
1503 //-----------------------------------------------------------------------------
1504 
1505 void InitializeParamField ( ParamField_t * pf, ParamFieldType_t pft );
1506 void ResetParamField ( ParamField_t * pf );
1507 void MoveParamField ( ParamField_t * dest, ParamField_t * src );
1508 
1509 int FindParamFieldIndex ( const ParamField_t * pf, ccp key, int not_found_value );
1510 ParamFieldItem_t * FindParamField ( const ParamField_t * pf, ccp key );
1511 bool RemoveParamField ( ParamField_t * pf, ccp key ); // return: true if item deleted
1512 
1513 ParamFieldItem_t * InsertParamField
1514 (
1515     ParamField_t	* pf,		// valid param field
1516     ccp			key,		// key to insert
1517     uint		num		// value
1518 );
1519 
1520 enumError LoadParamField
1521 (
1522     ParamField_t	* pf,		// param field
1523     ParamFieldType_t	init_pf,	// >0: initialize 'pf' with entered type
1524     ccp			filename,	// filename of source file
1525     bool		silent		// true: don't print open/read errors
1526 );
1527 
1528 enumError SaveParamField
1529 (
1530     ParamField_t	* pf,		// valid param field
1531     ccp			filename,	// filename of dest file
1532     bool		rm_if_empty	// true: rm dest file if 'pf' is empty
1533 );
1534 
1535 enumError WriteParamField
1536 (
1537     FILE		* f,		// open destination file
1538     ccp			filename,	// NULL or filename (needed on write error)
1539     ParamField_t	* pf,		// valid param field
1540     ccp			line_prefix,	// not NULL: insert prefix before each line
1541     ccp			key_prefix,	// not NULL: insert prefix before each key
1542     ccp			eol		// end of line text (if NULL: use LF)
1543 );
1544 
1545 //
1546 ///////////////////////////////////////////////////////////////////////////////
1547 ///////////////			    some list			///////////////
1548 ///////////////////////////////////////////////////////////////////////////////
1549 
1550 typedef struct StringList_t
1551 {
1552 	ccp str;
1553 	struct StringList_t * next;
1554 
1555 } StringList_t;
1556 
1557 ///////////////////////////////////////////////////////////////////////////////
1558 
1559 typedef struct ParamList_t
1560 {
1561 	char * arg;
1562 	char id6[7];
1563 	char selector[7];
1564 	bool is_expanded;
1565 	int count;
1566 	struct ParamList_t * next;
1567 
1568 } ParamList_t;
1569 
1570 extern uint n_param, id6_param_found;
1571 extern ParamList_t * first_param;
1572 extern ParamList_t ** append_param;
1573 
1574 ///////////////////////////////////////////////////////////////////////////////
1575 
1576 int AtFileHelper
1577 (
1578     ccp arg,
1579     int mode,
1580     int mode_expand,
1581     int (*func)(ccp arg,int mode)
1582 );
1583 
1584 ParamList_t * AppendParam ( ccp arg, int is_temp );
1585 int AddParam ( ccp arg, int is_temp );
1586 void AtExpandParam ( ParamList_t ** param );
1587 void AtExpandAllParam ( ParamList_t ** first_param );
1588 
1589 //
1590 ///////////////////////////////////////////////////////////////////////////////
1591 ///////////////              string substitutions               ///////////////
1592 ///////////////////////////////////////////////////////////////////////////////
1593 
1594 typedef struct SubstString_t
1595 {
1596 	char c1, c2;		// up to 2 codes (lower+upper case)
1597 	bool allow_slash;	// true: allow slash in replacement
1598 	ccp  str;		// pointer to string
1599 
1600 } SubstString_t;
1601 
1602 char * SubstString
1603 	( char * buf, size_t bufsize, SubstString_t * tab, ccp source, int * count );
1604 int ScanEscapeChar ( ccp arg );
1605 bool HaveEscapeChar ( ccp string );
1606 
1607 //
1608 ///////////////////////////////////////////////////////////////////////////////
1609 ///////////////			setup files			///////////////
1610 ///////////////////////////////////////////////////////////////////////////////
1611 
1612 typedef struct SetupDef_t
1613 {
1614 	ccp	name;		// name of parameter, NULL=list terminator
1615 	u32	factor;		// alignment factor; 0: text param
1616 	ccp	param;		// alloced text param
1617 	u64	value;		// numeric value of param
1618 
1619 } SetupDef_t;
1620 
1621 //-----------------------------------------------------------------------------
1622 
1623 size_t ResetSetup
1624 (
1625 	SetupDef_t * list	// object list terminated with an element 'name=NULL'
1626 );
1627 
1628 enumError ScanSetupFile
1629 (
1630 	SetupDef_t * list,	// object list terminated with an element 'name=NULL'
1631 	ccp path1,		// filename of text file, part 1
1632 	ccp path2,		// filename of text file, part 2
1633 	bool silent		// true: suppress error message if file not found
1634 );
1635 
1636 //
1637 ///////////////////////////////////////////////////////////////////////////////
1638 ///////////////		    scan compression option		///////////////
1639 ///////////////////////////////////////////////////////////////////////////////
1640 
1641 extern wd_compression_t opt_compr_method; // = WD_COMPR__DEFAULT
1642 extern int opt_compr_level;		  // = 0=default, 1..9=valid
1643 extern u32 opt_compr_chunk_size;	  // = 0=default
1644 
1645 //-----------------------------------------------------------------------------
1646 
1647 wd_compression_t ScanCompression
1648 (
1649     ccp			arg,		// argument to scan
1650     bool		silent,		// don't print error message
1651     int			* level,	// not NULL: appendix '.digit' allowed
1652 					// The level will be stored in '*level'
1653     u32			* chunk_size	// not NULL: appendix '@size' allowed
1654 					// The size will be stored in '*chunk_size'
1655 );
1656 
1657 //-----------------------------------------------------------------------------
1658 
1659 int ScanOptCompression
1660 (
1661     bool		set_oft_wia,	// true: output_file_type := OFT_WIA
1662     ccp			arg		// argument to scan
1663 );
1664 
1665 //
1666 ///////////////////////////////////////////////////////////////////////////////
1667 ///////////////			scan mem option			///////////////
1668 ///////////////////////////////////////////////////////////////////////////////
1669 
1670 extern u64 opt_mem;			  // = 0
1671 
1672 int ScanOptMem
1673 (
1674     ccp			arg,		// argument to scan
1675     bool		print_err	// true: print error messages
1676 );
1677 
1678 u64 GetMemLimit();
1679 
1680 //
1681 ///////////////////////////////////////////////////////////////////////////////
1682 ///////////////			data area & list		///////////////
1683 ///////////////////////////////////////////////////////////////////////////////
1684 
1685 typedef struct DataArea_t
1686 {
1687     const u8		* data;		// pointer to data area
1688 					// for lists: NULL is the end of list marker
1689     size_t		size;		// size of data area
1690 
1691 } DataArea_t;
1692 
1693 //-----------------------------------------------------------------------------
1694 
1695 typedef struct DataList_t
1696 {
1697     const DataArea_t	* area;		// pointer to a source list
1698 					//  terminated with an element where addr==NULL
1699     DataArea_t		current;	// current element
1700 
1701 } DataList_t;
1702 
1703 //-----------------------------------------------------------------------------
1704 
1705 void SetupDataList
1706 (
1707     DataList_t		* dl,		// Object for setup
1708     const DataArea_t	* da		// Source list,
1709 					//  terminated with an element where addr==NULL
1710 					// The content of this area must not changed
1711 					//  while accessing the data list
1712 );
1713 
1714 size_t ReadDataList // returns number of writen bytes
1715 (
1716     DataList_t		* dl,		// NULL or pointer to data list
1717     void		* buf,		// destination buffer
1718     size_t		size		// size of destination buffer
1719 );
1720 
1721 //
1722 ///////////////////////////////////////////////////////////////////////////////
1723 ///////////////			  enum RepairMode		///////////////
1724 ///////////////////////////////////////////////////////////////////////////////
1725 
1726 typedef enum RepairMode
1727 {
1728 	REPAIR_NONE		=     0,
1729 
1730 	REPAIR_FBT		= 0x001, // repair free blocks table
1731 	REPAIR_INODES		= 0x002, // repair invalid inode infos
1732 	 REPAIR_DEFAULT		= 0x003, // standard value
1733 
1734 	REPAIR_RM_INVALID	= 0x010, // remove discs with invalid blocks
1735 	REPAIR_RM_OVERLAP	= 0x020, // remove discs with overlaped blocks
1736 	REPAIR_RM_FREE		= 0x040, // remove discs with free marked blocks
1737 	REPAIR_RM_EMPTY		= 0x080, // remove discs without any valid blocks
1738 	 REPAIR_RM_ALL		= 0x0f0, // remove all discs with errors
1739 
1740 	REPAIR_ALL		= 0x0f3, // repair all
1741 
1742 	REPAIR__ERROR		= -1 // not a mode but an error message
1743 
1744 } RepairMode;
1745 
1746 extern RepairMode repair_mode;
1747 
1748 RepairMode ScanRepairMode ( ccp arg );
1749 
1750 ///////////////////////////////////////////////////////////////////////////////
1751 ///////////////			random mumbers			///////////////
1752 ///////////////////////////////////////////////////////////////////////////////
1753 
1754 u32 Random32 ( u32 max );
1755 u64 Seed32Time();
1756 u64 Seed32 ( u64 base );
1757 
1758 void RandomFill ( void * buf, size_t size );
1759 
1760 ///////////////////////////////////////////////////////////////////////////////
1761 ///////////////			    bit handling		///////////////
1762 ///////////////////////////////////////////////////////////////////////////////
1763 
1764 extern const uchar TableBitCount[0x100];
1765 
1766 uint Count1Bits   ( const void * data, size_t len );
1767 uint Count1Bits8  ( u8  data );
1768 uint Count1Bits16 ( u16 data );
1769 uint Count1Bits32 ( u32 data );
1770 uint Count1Bits64 ( u64 data );
1771 
1772 int FindLowest1Bit64 ( u64 data );
1773 u64 GetAlign64 ( u64 data );
1774 
1775 //
1776 ///////////////////////////////////////////////////////////////////////////////
1777 ///////////////			    etc				///////////////
1778 ///////////////////////////////////////////////////////////////////////////////
1779 
1780 size_t AllocTempBuffer ( size_t needed_size );
1781 int AddCertFile ( ccp fname, int unused );
1782 char * AllocRealPath ( ccp source );
1783 
1784 //
1785 ///////////////////////////////////////////////////////////////////////////////
1786 ///////////////			    vars			///////////////
1787 ///////////////////////////////////////////////////////////////////////////////
1788 
1789 extern enumProgID	prog_id;
1790 extern u32		revision_id;
1791 extern ccp		progname;
1792 extern ccp		search_path[];
1793 extern ccp		lang_info;
1794 extern volatile int	SIGINT_level;
1795 extern volatile int	verbose;
1796 extern volatile int	logging;
1797 extern int		progress;
1798 extern int		scan_progress;
1799 extern bool		use_utf8;
1800 extern char		escape_char;
1801 extern int		opt_force;
1802 extern ccp		opt_patch_file;
1803 extern bool		opt_copy_gc;
1804 extern bool		opt_no_link;
1805 extern int		testmode;
1806 extern int		newmode;
1807 extern ccp		opt_dest;
1808 extern bool		opt_overwrite;
1809 extern bool		opt_mkdir;
1810 extern int		opt_limit;
1811 extern int		opt_file_limit;
1812 extern int		opt_block_size;
1813 extern int		print_old_style;
1814 extern int		print_sections;
1815 extern int		long_count;
1816 extern int		brief_count;
1817 extern int		ignore_count;
1818 extern int		opt_technical;
1819 extern u32		job_limit;
1820 extern enumIOMode	io_mode;
1821 extern bool		opt_no_expand;
1822 extern u32		opt_recurse_depth;
1823 
1824 extern StringField_t	source_list;
1825 extern StringField_t	recurse_list;
1826 extern StringField_t	created_files;
1827 extern       char	iobuf [0x400000];	// global io buffer
1828 extern const char	zerobuf[0x40000];	// global zero buffer
1829 
1830 // 'tempbuf' is only for short usage
1831 //	==> don't call other functions while using tempbuf
1832 extern u8		* tempbuf;		// global temp buffer -> AllocTempBuffer()
1833 extern size_t		tempbuf_size;		// size of 'tempbuf'
1834 
1835 extern const char	sep_79[80];		//  79 * '-' + NULL
1836 
1837 //
1838 ///////////////////////////////////////////////////////////////////////////////
1839 ///////////////				END			///////////////
1840 ///////////////////////////////////////////////////////////////////////////////
1841 
1842 #endif // WIT_LIB_STD_H
1843