// (C) 2016 Intel Deutschland GmbH
// Author: Michael Soegtrop
// Released to the public under CC0
// See https://creativecommons.org/publicdomain/zero/1.0/
// Windows drop in repacement for Linux ln
// Supports command form "ln TARGET LINK_NAME"
// Supports -s and -f options
// Does not support hard links to folders (but symlinks are ok)
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
// Cygwin MinGW doesn't have this Vista++ function in windows.h
#ifdef UNICODE
WINBASEAPI BOOLEAN APIENTRY CreateSymbolicLinkW ( LPCWSTR, LPCWSTR, DWORD );
#define CreateSymbolicLink CreateSymbolicLinkW
#define CommandLineToArgv CommandLineToArgvW
#else
WINBASEAPI BOOLEAN APIENTRY CreateSymbolicLinkA ( LPCSTR, LPCSTR, DWORD );
#define CreateSymbolicLink CreateSymbolicLinkA
#define CommandLineToArgv CommandLineToArgvA
#endif
#define SYMBOLIC_LINK_FLAG_DIRECTORY 1
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLineA, int nShowCmd )
{
int iarg;
BOOL symbolic = FALSE;
BOOL force = FALSE;
BOOL folder;
const _TCHAR *target;
const _TCHAR *link;
LPTSTR lpCmdLine;
int argc;
LPTSTR *argv;
// Parse command line
// This is done explicitly here for two reasons
// 1.) MinGW doesn't seem to support _tmain, wWinMain and the like
// 2.) We want to make sure that CommandLineToArgv is used
lpCmdLine = GetCommandLine();
argv = CommandLineToArgv( lpCmdLine, &argc );
// Get target and link name
if( argc<3 )
{
_ftprintf( stderr, _T("Expecting at least 2 arguments, got %d\n"), argc-1 );
return 1;
}
target = argv[argc-2];
link = argv[argc-1];
// Parse options
// The last two arguments are interpreted as file names
// All other arguments must be -s or -f os multi letter options like -sf
for(iarg=1; iarg<argc-2; iarg++ )
{
const _TCHAR *pos = argv[iarg];
if( *pos != _T('-') )
{
_ftprintf( stderr, _T("Command line option expected in argument %d\n"), iarg );
return 1;
}
pos ++;
while( *pos )
{
switch( *pos )
{
case _T('s') : symbolic = TRUE; break;
case _T('f') : force = TRUE; break;
default :
_ftprintf( stderr, _T("Unknown option '%c'\n"), *pos );
return 1;
}
pos ++;
}
}
#ifdef IGNORE_SYMBOLIC
symbolic = FALSE;
#endif
// Check if link already exists - delete it if force is given or abort
{
if( GetFileAttributes(link) != INVALID_FILE_ATTRIBUTES )
{
if( force )
{
if( !DeleteFile( link ) )
{
_ftprintf( stderr, _T("Error deleting file '%s'\n"), link );
return 1;
}
}
else
{
_ftprintf( stderr, _T("File '%s' exists!\n"), link );
return 1;
}
}
}
// Check if target is a folder
folder = ( (GetFileAttributes(target) & FILE_ATTRIBUTE_DIRECTORY) ) != 0;
// Create link
if(symbolic)
{
if( !CreateSymbolicLink( link, target, folder ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ) )
{
_ftprintf( stderr, _T("Error creating symbolic link '%s' -> '%s'!\n"), link, target );
return 1;
}
}
else
{
if( folder )
{
_ftprintf( stderr, _T("Cannot create hard link to folder") );
return 1;
}
else
{
if( !CreateHardLink( link, target, NULL ) )
{
_ftprintf( stderr, _T("Error creating hard link '%s' -> '%s'!\n"), link, target );
return 1;
}
}
}
// Everything is fine
return 0;
}
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet)
¤
|
Haftungshinweis
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.
|