From a623c4232f9ee7a7990cb6c2581d5f7a632a6205 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Tue, 30 Nov 2010 07:46:52 +0000 Subject: [PATCH] 2010-11-30 08:37 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * src/rtl/hbsocket.c ! hb_socketSetReuseAddr() changed on win platforms to use SO_EXCLUSIVEADDRUSE instead of SO_REUSEADDR. See http://paste.lisp.org/display/59751. Rough patch, maybe the logic isn't applied to the right place, maybe extra win version checks are required, please test it and patch it further if needed. * src/rtl/hbinet.c * s_inetBind() changed back to call hb_socketSetReuseAddr() also on win platforms. * contrib/hbwin/tests/testole.prg + Added shortcut creation example. * contrib/hbide/idemisc.prg ! Fixed HBIDE_PATHNORMALIZED() to _never_ lowercase passed filename. As discussed very long time ago, such behavior is not portable. For comparison purposes HB_FILEMATCH() should be used, for other purposes _no_ change should be done by hbide in filename casing. Ever. This is brute force fix only applied to low-level code. It will cause regressions on the higher level, which have to be fixed. ; TODO: Delete this second parameter from all calls, now the value is ignored. ; TOFIX: Review all HBIDE_PATHNORMALIZED() and HBIDE_PATHNORMALIZED( p, .T. ) calls if they are used in comparison context and change caller code to use HB_FILEMATCH(). ; TOFIX: All current code which uses LOWER()/UPPER() to "normalize" filename before comparison with '==' operator should also be changed to HB_FILEMATCH(). (except for cases where extension is used in the sense of file type). ; TOFIX: Rest of cases where LOWER()/UPPER() is applied to filenames. ! Fixed HBIDE_PATHFILE() to never uppercase drive letter. It's not strictly required since all so far known systems supporting drive letter are case insensitive, but it's nevertheless not the job of hbide to reformat pathnames. * contrib/hbide/ideactions.prg * contrib/hbide/idesaveload.prg * contrib/hbide/ideharbourhelp.prg * contrib/hbide/ideeditor.prg * contrib/hbide/ideprojmanager.prg * contrib/hbide/idesources.prg ! Fixed some code to use HB_FILEMATCH() instead of unconditional uppercasing/lowercasing. Please review and finish this modification, there might be more hidden places and might have overlooked anything in this patch. --- harbour/ChangeLog | 54 ++++++++++++++++++++++++ harbour/contrib/hbide/ideactions.prg | 2 +- harbour/contrib/hbide/ideeditor.prg | 4 +- harbour/contrib/hbide/ideharbourhelp.prg | 4 +- harbour/contrib/hbide/idemisc.prg | 16 +++---- harbour/contrib/hbide/ideprojmanager.prg | 6 +-- harbour/contrib/hbide/idesaveload.prg | 4 +- harbour/contrib/hbide/idesources.prg | 4 +- harbour/contrib/hbwin/tests/testole.prg | 21 ++++++++- harbour/src/rtl/hbinet.c | 2 - harbour/src/rtl/hbsocket.c | 14 ++++-- 11 files changed, 102 insertions(+), 29 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 6b016cfcf8..e2561f3be7 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,60 @@ The license applies to all entries newer than 2009-04-28. */ +2010-11-30 08:37 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) + * src/rtl/hbsocket.c + ! hb_socketSetReuseAddr() changed on win platforms to use + SO_EXCLUSIVEADDRUSE instead of SO_REUSEADDR. See http://paste.lisp.org/display/59751. + Rough patch, maybe the logic isn't applied to the right place, + maybe extra win version checks are required, please test it + and patch it further if needed. + + * src/rtl/hbinet.c + * s_inetBind() changed back to call hb_socketSetReuseAddr() also + on win platforms. + + * contrib/hbwin/tests/testole.prg + + Added shortcut creation example. + + * contrib/hbide/idemisc.prg + ! Fixed HBIDE_PATHNORMALIZED() to _never_ lowercase passed + filename. As discussed very long time ago, such behavior + is not portable. For comparison purposes HB_FILEMATCH() + should be used, for other purposes _no_ change should be + done by hbide in filename casing. Ever. + This is brute force fix only applied to low-level code. + It will cause regressions on the higher level, which have + to be fixed. + ; TODO: Delete this second parameter from all calls, now + the value is ignored. + ; TOFIX: Review all + HBIDE_PATHNORMALIZED() and + HBIDE_PATHNORMALIZED( p, .T. ) + calls if they are used in comparison context and change + caller code to use HB_FILEMATCH(). + ; TOFIX: All current code which uses LOWER()/UPPER() to + "normalize" filename before comparison with '==' + operator should also be changed to HB_FILEMATCH(). + (except for cases where extension is used in the + sense of file type). + ; TOFIX: Rest of cases where LOWER()/UPPER() is applied to + filenames. + ! Fixed HBIDE_PATHFILE() to never uppercase drive letter. + It's not strictly required since all so far known systems + supporting drive letter are case insensitive, but it's + nevertheless not the job of hbide to reformat pathnames. + + * contrib/hbide/ideactions.prg + * contrib/hbide/idesaveload.prg + * contrib/hbide/ideharbourhelp.prg + * contrib/hbide/ideeditor.prg + * contrib/hbide/ideprojmanager.prg + * contrib/hbide/idesources.prg + ! Fixed some code to use HB_FILEMATCH() instead of unconditional + uppercasing/lowercasing. Please review and finish this modification, + there might be more hidden places and might have overlooked anything + in this patch. + 2010-11-29 15:47 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/src/codepage/cpsk852.c * harbour/src/codepage/cpskiso.c diff --git a/harbour/contrib/hbide/ideactions.prg b/harbour/contrib/hbide/ideactions.prg index 6906c72598..c91ae0a3f4 100644 --- a/harbour/contrib/hbide/ideactions.prg +++ b/harbour/contrib/hbide/ideactions.prg @@ -794,7 +794,7 @@ FUNCTION hbide_mnuAddFileToMRU( oIde, cFileName, cType ) a_:= oIde:oINI:aRecentFiles ENDIF - IF ( nPos := aScan( a_, {|f| hbide_pathNormalized( f ) == cFileNormal } ) ) > 0 + IF ( nPos := aScan( a_, {|f| hb_FileMatch( hbide_pathNormalized( f ), cFileNormal ) } ) ) > 0 hb_aDel( a_, nPos, .T. ) ENDIF diff --git a/harbour/contrib/hbide/ideeditor.prg b/harbour/contrib/hbide/ideeditor.prg index 8ef5eaa7ee..2e30923d0a 100644 --- a/harbour/contrib/hbide/ideeditor.prg +++ b/harbour/contrib/hbide/ideeditor.prg @@ -426,7 +426,7 @@ METHOD IdeEditsManager:getTabBySource( cSource ) cSource := hbide_pathNormalized( cSource, .t. ) - RETURN ascan( ::aTabs, {|e_| e_[ TAB_OEDITOR ]:pathNormalized == cSource } ) + RETURN ascan( ::aTabs, {|e_| hb_FileMatch( e_[ TAB_OEDITOR ]:pathNormalized, cSource ) } ) /*----------------------------------------------------------------------*/ @@ -541,7 +541,7 @@ METHOD IdeEditsManager:getEditorBySource( cSource ) LOCAL n cSource := hbide_pathNormalized( cSource, .t. ) - IF ( n := ascan( ::aTabs, {|e_| e_[ TAB_OEDITOR ]:pathNormalized == cSource } ) ) > 0 + IF ( n := ascan( ::aTabs, {|e_| hb_FileMatch( e_[ TAB_OEDITOR ]:pathNormalized, cSource ) } ) ) > 0 RETURN ::aTabs[ n, TAB_OEDITOR ] ENDIF diff --git a/harbour/contrib/hbide/ideharbourhelp.prg b/harbour/contrib/hbide/ideharbourhelp.prg index aa1788e810..578a537c95 100644 --- a/harbour/contrib/hbide/ideharbourhelp.prg +++ b/harbour/contrib/hbide/ideharbourhelp.prg @@ -676,11 +676,11 @@ STATIC FUNCTION hbide_buildFoldersTree( aNodes, aPaths ) FOR i := 1 TO len( aSubs ) IF !empty( aSubs[ i ] ) cCPath := hbide_buildPathFromSubs( aSubs, i ) - n := ascan( aNodes, {|e_| hbide_pathNormalized( e_[ 4 ], .t. ) == hbide_pathNormalized( cRoot + cCPath, .t. ) } ) + n := ascan( aNodes, {|e_| hb_FileMatch( hbide_pathNormalized( e_[ 4 ], .t. ), hbide_pathNormalized( cRoot + cCPath, .t. ) ) } ) IF n == 0 cPPath := hbide_buildPathFromSubs( aSubs, i - 1 ) - nP := ascan( aNodes, {|e_| hbide_pathNormalized( e_[ 4 ], .t. ) == hbide_pathNormalized( cRoot + cPPath, .t. ) } ) + nP := ascan( aNodes, {|e_| hb_FileMatch( hbide_pathNormalized( e_[ 4 ], .t. ), hbide_pathNormalized( cRoot + cPPath, .t. ) ) } ) oParent := aNodes[ nP, 1 ] diff --git a/harbour/contrib/hbide/idemisc.prg b/harbour/contrib/hbide/idemisc.prg index 6e2cecd2c7..02f57a207d 100644 --- a/harbour/contrib/hbide/idemisc.prg +++ b/harbour/contrib/hbide/idemisc.prg @@ -615,14 +615,8 @@ FUNCTION hbide_sourceType( cSourceFile ) /*----------------------------------------------------------------------*/ -FUNCTION hbide_pathNormalized( cPath, lLower ) - LOCAL S - - DEFAULT lLower TO .T. - - s := strtran( cPath, "\", "/" ) - - RETURN IIF( lLower, lower( s ), s ) +FUNCTION hbide_pathNormalized( cPath ) + RETURN strtran( cPath, "\", "/" ) /*----------------------------------------------------------------------*/ @@ -651,7 +645,7 @@ FUNCTION hbide_pathToOSPath( cPath ) cPath := strtran( cPath, "\" , hb_ps() ) IF ( n := at( ":", cPath ) ) > 0 - cPath := upper( substr( cPath, 1, n - 1 ) ) + substr( cPath, n ) + cPath := substr( cPath, 1, n - 1 ) + substr( cPath, n ) ENDIF RETURN cPath @@ -1735,7 +1729,7 @@ FUNCTION hbide_isPrevParent( cRoot, cPath ) cLRoot := hbide_pathNormalized( cRoot, .t. ) cLPath := hbide_pathNormalized( cPath, .t. ) - IF left( cLPath, len( cLRoot ) ) == cLRoot + IF hb_FileMatch( left( cLPath, len( cLRoot ) ), cLRoot ) RETURN .t. ENDIF @@ -1779,7 +1773,7 @@ FUNCTION hbide_stripRoot( cRoot, cPath ) cLRoot := hbide_pathNormalized( cRoot, .t. ) cLPath := hbide_pathNormalized( cPath, .f. ) - IF left( lower( cLPath ), len( cLRoot ) ) == cLRoot + IF hb_FileMatch( left( lower( cLPath ), len( cLRoot ) ), cLRoot ) cP := substr( cLPath, len( cRoot ) + 1 ) RETURN cP ENDIF diff --git a/harbour/contrib/hbide/ideprojmanager.prg b/harbour/contrib/hbide/ideprojmanager.prg index 6657883d79..83ac6462ab 100644 --- a/harbour/contrib/hbide/ideprojmanager.prg +++ b/harbour/contrib/hbide/ideprojmanager.prg @@ -363,7 +363,7 @@ METHOD IdeProjManager:loadProperties( cProjFileName, lNew, lFetch, lUpdateTree ) cProjFileName := hbide_pathToOSPath( cProjFileName ) - nAlready := ascan( ::aProjects, {|e_| e_[ 1 ] == hbide_pathNormalized( cProjFileName ) } ) + nAlready := ascan( ::aProjects, {|e_| hb_FileMatch( e_[ 1 ], hbide_pathNormalized( cProjFileName ) ) } ) IF !empty( cProjFileName ) .AND. hb_fileExists( cProjFileName ) ::aPrjProps := ::pullHbpData( hbide_pathToOSPath( cProjFileName ) ) @@ -606,7 +606,7 @@ METHOD IdeProjManager:save( lCanClose ) IF ( lOk := hbide_createTarget( ::cSaveTo, txt_ ) ) ::aPrjProps := ::pullHbpData( hbide_pathToOSPath( ::cSaveTo ) ) - IF ( nAlready := ascan( ::aProjects, {|e_| e_[ 1 ] == hbide_pathNormalized( ::cSaveTo ) } ) ) == 0 + IF ( nAlready := ascan( ::aProjects, {|e_| hb_FileMatch( e_[ 1 ], hbide_pathNormalized( ::cSaveTo ) ) } ) ) == 0 aadd( ::oIDE:aProjects, { hbide_pathNormalized( ::cSaveTo ), ::cSaveTo, aclone( ::aPrjProps ) } ) IF ::lUpdateTree ::oIDE:updateProjectTree( ::aPrjProps ) @@ -1181,7 +1181,7 @@ METHOD IdeProjManager:getProjectByFile( cProjectFile ) cProjectFile := hbide_pathNormalized( cProjectFile ) - IF ( n := ascan( ::aProjects, {|e_| e_[ 1 ] == cProjectFile } ) ) > 0 + IF ( n := ascan( ::aProjects, {|e_| hb_FileMatch( e_[ 1 ], cProjectFile ) } ) ) > 0 aProj := ::aProjects[ n ] ENDIF diff --git a/harbour/contrib/hbide/idesaveload.prg b/harbour/contrib/hbide/idesaveload.prg index adab786eb6..833bf1a746 100644 --- a/harbour/contrib/hbide/idesaveload.prg +++ b/harbour/contrib/hbide/idesaveload.prg @@ -646,7 +646,7 @@ METHOD IdeINI:load( cHbideIni ) IF hbide_parseKeyValPair( s, @cKey, @cVal ) IF Len( ::aRecentProjects ) < 25 cVal := hbide_pathNormalized( cVal, .f. ) - IF aScan( ::aRecentProjects, {|e| hbide_pathNormalized( e, .f. ) == cVal } ) == 0 + IF aScan( ::aRecentProjects, {|e| hb_FileMatch( hbide_pathNormalized( e, .f. ), cVal ) } ) == 0 AAdd( ::aRecentProjects, cVal ) ENDIF ENDIF @@ -656,7 +656,7 @@ METHOD IdeINI:load( cHbideIni ) IF hbide_parseKeyValPair( s, @cKey, @cVal ) IF Len( ::aRecentFiles ) < 25 cVal := hbide_pathNormalized( cVal, .f. ) - IF aScan( ::aRecentFiles, {|e| hbide_pathNormalized( e, .f. ) == cVal } ) == 0 + IF aScan( ::aRecentFiles, {|e| hb_FileMatch( hbide_pathNormalized( e, .f. ), cVal ) } ) == 0 AAdd( ::aRecentFiles, cVal ) ENDIF ENDIF diff --git a/harbour/contrib/hbide/idesources.prg b/harbour/contrib/hbide/idesources.prg index e59d088832..cf2bad2d93 100644 --- a/harbour/contrib/hbide/idesources.prg +++ b/harbour/contrib/hbide/idesources.prg @@ -132,7 +132,7 @@ METHOD IdeSourcesManager:saveNamedSource( cSource ) FOR EACH a_ IN ::aTabs oEditor := a_[ TAB_OEDITOR ] IF hb_isObject( oEditor ) - IF hbide_pathNormalized( oEditor:sourceFile, .t. ) == cSource + IF hb_FileMatch( hbide_pathNormalized( oEditor:sourceFile, .t. ), cSource ) IF oEditor:lLoaded IF oEditor:qDocument:isModified() cBuffer := oEditor:prepareBufferToSave( oEditor:qEdit:toPlainText() ) @@ -229,7 +229,7 @@ METHOD IdeSourcesManager:saveSource( nTab, lCancel, lAs ) // will check later what decision to take RETURN .f. ENDIF - IF hbide_pathNormalized( cNewFile ) == hbide_pathNormalized( cSource ) + IF hb_FileMatch( hbide_pathNormalized( cNewFile ), hbide_pathNormalized( cSource ) ) lNew := .f. ENDIF ENDIF diff --git a/harbour/contrib/hbwin/tests/testole.prg b/harbour/contrib/hbwin/tests/testole.prg index 524a386732..0db9966291 100644 --- a/harbour/contrib/hbwin/tests/testole.prg +++ b/harbour/contrib/hbwin/tests/testole.prg @@ -10,7 +10,7 @@ * Copyright 2007 Enrico Maria Giordano e.m.giordano at emagsoftware.it * Copyright 2009 Mindaugas Kavaliauskas * Copyright 2008 Viktor Szakats (harbour.01 syenar.hu) - * Exm_CDO(), Exm_OOOpen() + * Exm_CDO(), Exm_OOOpen(), Exm_CreateShortcut() * * www - http://harbour-project.org * @@ -35,6 +35,7 @@ PROCEDURE Main() ? "b) SOAP Toolkit client" ? "c) PocketSOAP client" ? "d) Internet Explorer with callback" + ? "e) Create shortcut" ? "0) Quit" ? "> " @@ -67,6 +68,8 @@ PROCEDURE Main() Exm_PocketSOAP() ELSEIF nOption == Asc( "d" ) Exm_IExplorer2() + ELSEIF nOption == Asc( "e" ) + Exm_CreateShortcut() ELSEIF nOption == Asc( "0" ) EXIT ENDIF @@ -488,3 +491,19 @@ STATIC PROCEDURE Exm_PocketSOAP() ENDIF RETURN + + +STATIC PROCEDURE Exm_CreateShortcut() + LOCAL oShell, oSC + + IF ( oShell := win_oleCreateObject( "WScript.Shell" ) ) != NIL + oSC := oShell:CreateShortcut( hb_dirBase() + hb_ps() + "testole.lnk" ) + oSC:TargetPath := hb_ProgName() + oSC:WorkingDirectory := hb_DirBase() + oSC:IconLocation := hb_ProgName() + ",0" + oSC:Save() + ELSE + ? "Error: Shell not available. [" + win_oleErrorText()+ "]" + ENDIF + + RETURN diff --git a/harbour/src/rtl/hbinet.c b/harbour/src/rtl/hbinet.c index 0f68318dc1..909da9ebc2 100644 --- a/harbour/src/rtl/hbinet.c +++ b/harbour/src/rtl/hbinet.c @@ -1105,9 +1105,7 @@ HB_FUNC( HB_INETIFINFO ) static int s_inetBind( PHB_SOCKET_STRUCT socket, const void * pSockAddr, unsigned uiLen ) { -#if !defined( HB_OS_WIN ) hb_socketSetReuseAddr( socket->sd, HB_TRUE ); -#endif return hb_socketBind( socket->sd, pSockAddr, uiLen ); } diff --git a/harbour/src/rtl/hbsocket.c b/harbour/src/rtl/hbsocket.c index e392a5a0ae..f63419410a 100644 --- a/harbour/src/rtl/hbsocket.c +++ b/harbour/src/rtl/hbsocket.c @@ -2432,15 +2432,23 @@ int hb_socketSetNoDelay( HB_SOCKET sd, HB_BOOL fNoDelay ) return ret; } -/* NOTE: For notes on Windows, see: - http://paste.lisp.org/display/59751 */ int hb_socketSetReuseAddr( HB_SOCKET sd, HB_BOOL fReuse ) { /* it allows to reuse port immediately without timeout used to * clean all pending connections addressed to previous port owner */ int val = fReuse ? 1 : 0, ret; - ret = setsockopt( sd, SOL_SOCKET, SO_REUSEADDR, ( const char * ) &val, sizeof( val ) ); + #if defined( HB_OS_WIN ) + #if defined( SO_EXCLUSIVEADDRUSE ) + /* NOTE: For notes on Windows, see: http://paste.lisp.org/display/59751 */ + ret = setsockopt( sd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, ( const char * ) &val, sizeof( val ) ); + #else + HB_SYMBOL_UNUSED( val ); + ret = -1; + #endif + #else + ret = setsockopt( sd, SOL_SOCKET, SO_REUSEADDR, ( const char * ) &val, sizeof( val ) ); + #endif hb_socketSetOsError( ret != -1 ? 0 : HB_SOCK_GETERROR() ); return ret; }