2016-01-28 14:52:40 +01:00
|
|
|
/** @file
|
|
|
|
|
*
|
|
|
|
|
* @par History
|
|
|
|
|
* - 2008/03/01 Shinigami: VS2005 will not use STLport, but VS2003 will use it
|
|
|
|
|
*/
|
2016-02-11 22:54:43 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <assert.h>
|
2018-01-29 21:55:48 +01:00
|
|
|
#include <ctype.h>
|
2016-02-11 22:54:43 +01:00
|
|
|
#include <errno.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <io.h>
|
2018-01-29 21:55:48 +01:00
|
|
|
#include <stdio.h>
|
2016-02-11 22:54:43 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
2018-01-29 21:55:48 +01:00
|
|
|
#include <sys\stat.h>
|
2016-02-11 22:54:43 +01:00
|
|
|
|
|
|
|
|
#pragma hdrstop
|
|
|
|
|
|
|
|
|
|
#include "clib.h"
|
|
|
|
|
|
|
|
|
|
#include "dirfunc.h"
|
2016-02-19 19:26:35 +01:00
|
|
|
namespace Pol
|
|
|
|
|
{
|
|
|
|
|
namespace Clib
|
|
|
|
|
{
|
|
|
|
|
// temp stuff for fnsplit/ fnmerge
|
|
|
|
|
char temp_path[MAXPATH];
|
|
|
|
|
char temp_drive[MAXDRIVE];
|
|
|
|
|
char temp_dir[MAXDIR];
|
|
|
|
|
char temp_fname[MAXFILE];
|
|
|
|
|
char temp_ext[MAXEXT];
|
|
|
|
|
|
|
|
|
|
int fullsplit( const char* path )
|
|
|
|
|
{
|
2016-02-11 22:54:43 +01:00
|
|
|
#ifdef _WIN32
|
2016-02-19 19:26:35 +01:00
|
|
|
// FIXME: 2008 Upgrades needed here?
|
|
|
|
|
#if defined( _MSC_VER ) && ( _MSC_VER <= 1310 ) // up to VS2003
|
|
|
|
|
_splitpath( path, temp_drive, temp_dir, temp_fname, temp_ext );
|
|
|
|
|
#else // VS2005 using MS STL, boooooo
|
|
|
|
|
_splitpath_s( path, temp_drive, MAXDRIVE, temp_dir, MAXDIR, temp_fname, MAXFILE, temp_ext,
|
|
|
|
|
MAXEXT );
|
2016-02-11 22:54:43 +01:00
|
|
|
#endif
|
2016-02-19 19:26:35 +01:00
|
|
|
return 0;
|
2016-02-11 22:54:43 +01:00
|
|
|
#else
|
2016-02-19 19:26:35 +01:00
|
|
|
return fnsplit( path, temp_drive, temp_dir, temp_fname, temp_ext );
|
2016-02-11 22:54:43 +01:00
|
|
|
#endif
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
2016-02-11 22:54:43 +01:00
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
char* fullmerge( char* path )
|
|
|
|
|
{
|
2016-02-11 22:54:43 +01:00
|
|
|
#ifdef _WIN32
|
2016-02-19 19:26:35 +01:00
|
|
|
// FIXME: 2008 Upgrades needed here?
|
|
|
|
|
#if defined( _MSC_VER ) && ( _MSC_VER <= 1310 ) // up to VS2003
|
|
|
|
|
_makepath( path, temp_drive, temp_dir, temp_fname, temp_ext );
|
|
|
|
|
#else // VS2005 using MS STL, booooo
|
|
|
|
|
_makepath_s( path, MAXPATH, temp_drive, temp_dir, temp_fname, temp_ext );
|
2016-02-11 22:54:43 +01:00
|
|
|
#endif
|
|
|
|
|
#else
|
2016-02-19 19:26:35 +01:00
|
|
|
fnmerge( path, temp_drive, temp_dir, temp_fname, temp_ext );
|
2016-02-11 22:54:43 +01:00
|
|
|
#endif
|
2016-02-19 19:26:35 +01:00
|
|
|
return path;
|
|
|
|
|
}
|
2016-02-11 22:54:43 +01:00
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
char* mergeFnExt( char* fname )
|
|
|
|
|
{
|
2019-08-25 09:05:15 +02:00
|
|
|
stracpy( fname, temp_fname, MAXFILE );
|
2016-02-19 19:26:35 +01:00
|
|
|
strncat( fname, temp_ext, MAXEXT - 1 );
|
|
|
|
|
return fname;
|
|
|
|
|
}
|
2016-02-11 22:54:43 +01:00
|
|
|
|
|
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
static Pathname workspace2, fullpath2;
|
2016-02-11 22:54:43 +01:00
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
2016-02-19 19:26:35 +01:00
|
|
|
int chddir( const char* dir )
|
|
|
|
|
{
|
|
|
|
|
// assume: drive is full pathname.
|
|
|
|
|
int ch = toupper( dir[0] );
|
|
|
|
|
if ( isalpha( ch ) )
|
|
|
|
|
setdisk( ch - 'A' );
|
|
|
|
|
return chdir( dir );
|
|
|
|
|
}
|
2016-02-11 22:54:43 +01:00
|
|
|
#endif
|
2016-02-19 19:26:35 +01:00
|
|
|
/*
|
|
|
|
|
the build directory functions:
|
|
|
|
|
params: directory, filename, node
|
|
|
|
|
directory: should not include trailing backslash
|
|
|
|
|
|
|
|
|
|
*/
|
2018-01-01 21:49:30 +01:00
|
|
|
namespace
|
|
|
|
|
{
|
2016-02-19 19:26:35 +01:00
|
|
|
const char* use_dir;
|
|
|
|
|
const char* use_fname;
|
|
|
|
|
const char* use_template;
|
|
|
|
|
|
|
|
|
|
void find_usefns( const char* dir, const char* fname )
|
|
|
|
|
{
|
|
|
|
|
/* first, the directory. */
|
|
|
|
|
if ( dir && dir[0] ) /* this is not null */
|
|
|
|
|
use_dir = dir;
|
|
|
|
|
else
|
|
|
|
|
use_dir = "."; // current directory.
|
|
|
|
|
|
|
|
|
|
if ( fname && fname[0] )
|
|
|
|
|
use_fname = fname;
|
|
|
|
|
else
|
|
|
|
|
use_fname = ".";
|
|
|
|
|
|
|
|
|
|
// now, if dir has a trailing backslash, we use %s%s
|
|
|
|
|
// else, we use %s\\%s
|
|
|
|
|
const char* s = strrchr( use_dir, '\\' );
|
2018-10-09 16:36:35 +02:00
|
|
|
if ( s == nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
s = strrchr( use_dir, '/' );
|
|
|
|
|
|
2018-10-09 16:36:35 +02:00
|
|
|
if ( s != nullptr && ( s[1] == '\0' ) ) // is trailing
|
2016-02-19 19:26:35 +01:00
|
|
|
use_template = "%s%s";
|
|
|
|
|
else
|
|
|
|
|
use_template = "%s\\%s";
|
|
|
|
|
}
|
2018-01-29 21:55:48 +01:00
|
|
|
} // namespace
|
2016-02-19 19:26:35 +01:00
|
|
|
|
|
|
|
|
char* nodefile( const char* directory, const char* filename, int node )
|
|
|
|
|
{
|
|
|
|
|
char buf[20];
|
|
|
|
|
find_usefns( directory, filename );
|
|
|
|
|
sprintf( buf, "%s.%%d", use_template );
|
|
|
|
|
sprintf( workspace2, buf, directory, filename, node );
|
|
|
|
|
_fullpath( fullpath2, workspace2, sizeof fullpath2 );
|
|
|
|
|
|
|
|
|
|
return fullpath2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char* buildfn( const char* directory, const char* filename )
|
|
|
|
|
{
|
|
|
|
|
// oughta, first, strip off the traling backslash.
|
|
|
|
|
find_usefns( directory, filename );
|
|
|
|
|
sprintf( workspace2, use_template, use_dir, use_fname );
|
|
|
|
|
_fullpath( fullpath2, workspace2, sizeof fullpath2 );
|
|
|
|
|
|
|
|
|
|
return fullpath2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char* buildfnext( const char* directory, const char* filename, const char* extension )
|
|
|
|
|
{
|
|
|
|
|
find_usefns( directory, filename );
|
|
|
|
|
sprintf( workspace2, use_template, directory, filename );
|
|
|
|
|
strcat( workspace2, "." );
|
|
|
|
|
strncat( workspace2, extension, 3 );
|
|
|
|
|
_fullpath( fullpath2, workspace2, sizeof fullpath2 );
|
|
|
|
|
|
|
|
|
|
return fullpath2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
normalize_dir: strip a trailin backslash from a directory.
|
|
|
|
|
*/
|
|
|
|
|
void normalize_dir( char* dir )
|
|
|
|
|
{
|
|
|
|
|
char* s = strrchr( dir, '\\' );
|
2018-10-09 16:36:35 +02:00
|
|
|
if ( s == nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
return;
|
|
|
|
|
if ( *( s + 1 ) == '\0' )
|
|
|
|
|
*s = '\0';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int mydir_errno;
|
2016-02-11 22:54:43 +01:00
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
2016-02-19 19:26:35 +01:00
|
|
|
static int inner_copy( const char* src, const char* dst, int replaceOk )
|
|
|
|
|
{
|
|
|
|
|
int in = -1, out = -1; // file handles
|
|
|
|
|
int result = -1; // default to error
|
|
|
|
|
|
|
|
|
|
int bufsize = 0;
|
2018-10-09 16:36:35 +02:00
|
|
|
void* buf = nullptr;
|
2016-02-19 19:26:35 +01:00
|
|
|
|
2018-10-09 16:36:35 +02:00
|
|
|
for ( bufsize = 0x4000; buf == nullptr && bufsize >= 128; bufsize /= 2 )
|
2016-02-19 19:26:35 +01:00
|
|
|
buf = malloc( bufsize );
|
2018-10-09 16:36:35 +02:00
|
|
|
if ( buf == nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
{ /* no errors allowed here! */
|
|
|
|
|
static char dummy[4];
|
|
|
|
|
buf = dummy;
|
|
|
|
|
bufsize = 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
in = open( src, O_RDONLY | O_BINARY );
|
|
|
|
|
if ( in >= 0 )
|
|
|
|
|
{
|
|
|
|
|
out = open( dst, O_BINARY | O_CREAT | O_RDWR | ( replaceOk ? O_TRUNC : O_EXCL ),
|
|
|
|
|
S_IREAD | S_IWRITE );
|
|
|
|
|
if ( out >= 0 )
|
|
|
|
|
{
|
|
|
|
|
int lastwrite, nbytes;
|
|
|
|
|
while ( ( nbytes = read( in, buf, bufsize ) ) > 0 )
|
|
|
|
|
{
|
|
|
|
|
lastwrite = write( out, buf, nbytes );
|
|
|
|
|
if ( lastwrite == -1 )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if ( lastwrite >= 0 )
|
|
|
|
|
{
|
2016-02-11 22:54:43 +01:00
|
|
|
#ifdef _WIN32
|
2016-02-19 19:26:35 +01:00
|
|
|
struct _timeb ftime;
|
2016-02-11 22:54:43 +01:00
|
|
|
#else
|
2016-02-19 19:26:35 +01:00
|
|
|
struct ftime ftime;
|
2016-02-11 22:54:43 +01:00
|
|
|
#endif
|
2016-02-19 19:26:35 +01:00
|
|
|
getftime( in, &ftime );
|
|
|
|
|
setftime( out, &ftime );
|
|
|
|
|
result = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
mydir_errno = WRITE_ERROR;
|
|
|
|
|
|
|
|
|
|
close( out );
|
|
|
|
|
// put this here so if fail 'cause of existence,
|
|
|
|
|
// we don't remove the unreplaced file!
|
|
|
|
|
// also, the file must be closed to remove
|
|
|
|
|
if ( result )
|
|
|
|
|
remove( dst );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mydir_errno = DST_OPEN_ERROR;
|
|
|
|
|
switch ( errno )
|
|
|
|
|
{
|
|
|
|
|
case EEXIST:
|
|
|
|
|
mydir_errno = DST_ALREADY_EXIST;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
close( in );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mydir_errno = SRC_OPEN_ERROR;
|
|
|
|
|
switch ( errno )
|
|
|
|
|
{
|
|
|
|
|
case ENOENT:
|
|
|
|
|
mydir_errno = SRC_NO_EXIST;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-02-11 22:54:43 +01:00
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
assert( buf );
|
|
|
|
|
if ( bufsize != 4 )
|
|
|
|
|
free( buf );
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int copyFile( const char* src, const char* dst )
|
|
|
|
|
{
|
|
|
|
|
int replaceOk = 1;
|
|
|
|
|
return inner_copy( src, dst, replaceOk );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int copyFileNoRep( const char* src, const char* dst )
|
|
|
|
|
{
|
|
|
|
|
int replaceOk = 0;
|
|
|
|
|
return inner_copy( src, dst, replaceOk );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int inner_move( const char* src, const char* dst, int replaceOk )
|
|
|
|
|
{
|
|
|
|
|
if ( replaceOk && access( dst, 0 ) == 0 )
|
|
|
|
|
remove( dst ); // let rename work
|
|
|
|
|
if ( rename( src, dst ) == 0 )
|
|
|
|
|
return 0; // same drive, no replace.
|
|
|
|
|
else if ( inner_copy( src, dst, replaceOk ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
remove( src );
|
|
|
|
|
return 0;
|
2016-02-11 22:54:43 +01:00
|
|
|
}
|
2016-02-19 19:26:35 +01:00
|
|
|
else
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int moveFile( const char* src, const char* dst )
|
|
|
|
|
{
|
|
|
|
|
int replaceOk = 1;
|
|
|
|
|
return inner_move( src, dst, replaceOk );
|
|
|
|
|
}
|
|
|
|
|
int moveFileNoRep( const char* src, const char* dst )
|
|
|
|
|
{
|
|
|
|
|
int replaceOk = 0;
|
|
|
|
|
return inner_move( src, dst, replaceOk );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2019-08-25 09:05:15 +02:00
|
|
|
} // namespace Clib
|
|
|
|
|
} // namespace Pol
|