GME
13
|
00001 00023 #include "../StdAfx.h" 00024 #include "../MsgConsole.h" 00025 00026 #if(USESVN) 00027 00028 #include ".\util.h" 00029 #include <iostream> // remove this later 00030 #include <fstream> 00031 #include <string> 00032 #include "svn_path.h" 00033 #include "svn_pools.h" 00034 #include <locale.h> // for LC_ALL 00035 00036 //#define _ 00037 00042 bool Util::globalInit() 00043 { 00044 // this method has to be run only once during the run a 00045 // programm 00046 static bool run = false; 00047 if(run) // already run 00048 { 00049 return true; 00050 } 00051 run = true; 00052 00053 apr_status_t status; 00054 00055 /* C programs default to the "C" locale. But because svn is supposed 00056 to be i18n-aware, it should inherit the default locale of its 00057 environment. */ 00058 if (!setlocale(LC_ALL, "")) 00059 { 00060 if (stderr) 00061 { 00062 const char *env_vars[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL }; 00063 const char **env_var = &env_vars[0], *env_val = NULL; 00064 while (*env_var) 00065 { 00066 env_val = getenv(*env_var); 00067 if (env_val && env_val[0]) 00068 break; 00069 ++env_var; 00070 } 00071 00072 if (!*env_var) 00073 { 00074 /* Unlikely. Can setlocale fail if no env vars are set? */ 00075 --env_var; 00076 env_val = "not set"; 00077 } 00078 00079 fprintf(stderr, 00080 "%s: error: cannot set LC_ALL locale\n" 00081 "%s: error: environment variable %s is %s\n" 00082 "%s: error: please check that your locale name is correct\n", 00083 "svnjavahl", "svnjavahl", *env_var, env_val, "svnjavahl"); 00084 } 00085 return FALSE; 00086 } 00087 00088 /* Initialize the APR subsystem, and register an atexit() function 00089 to Uninitialize that subsystem at program exit. */ 00090 status = apr_initialize(); 00091 if (status) 00092 { 00093 if (stderr) 00094 { 00095 char buf[1024]; 00096 apr_strerror(status, buf, sizeof(buf) - 1); 00097 fprintf(stderr, 00098 "%s: error: cannot initialize APR: %s\n", 00099 "svnjavahl", buf); 00100 } 00101 return FALSE; 00102 } 00103 00104 if (0 > atexit(apr_terminate)) 00105 { 00106 if (stderr) 00107 fprintf(stderr, 00108 "%s: error: atexit registration failed\n", 00109 "svnjavahl"); 00110 return FALSE; 00111 } 00112 00113 #ifdef ENABLE_NLS 00114 #ifdef WIN32 00115 { 00116 WCHAR ucs2_path[MAX_PATH]; 00117 char* utf8_path; 00118 const char* internal_path; 00119 apr_pool_t* pool; 00120 apr_status_t apr_err; 00121 unsigned int inwords, outbytes, outlength; 00122 00123 apr_pool_create (&pool, 0); 00124 /* get dll name - our locale info will be in '../share/locale' */ 00125 inwords = sizeof (ucs2_path) / sizeof(ucs2_path[0]); 00126 HINSTANCE moduleHandle = GetModuleHandle("libsvnjavahl-1"); 00127 GetModuleFileNameW (moduleHandle, ucs2_path, inwords); 00128 inwords = lstrlenW (ucs2_path); 00129 outbytes = outlength = 3 * (inwords + 1); 00130 utf8_path = (char *)apr_palloc (pool, outlength); 00131 apr_err = apr_conv_ucs2_to_utf8 ((const apr_wchar_t *) ucs2_path, 00132 &inwords, utf8_path, &outbytes); 00133 if (!apr_err && (inwords > 0 || outbytes == 0)) 00134 apr_err = APR_INCOMPLETE; 00135 if (apr_err) 00136 { 00137 if (stderr) 00138 fprintf (stderr, "Can't convert module path to UTF-8"); 00139 return FALSE; 00140 } 00141 utf8_path[outlength - outbytes] = '\0'; 00142 internal_path = svn_path_internal_style (utf8_path, pool); 00143 /* get base path name */ 00144 internal_path = svn_path_dirname (internal_path, pool); 00145 internal_path = svn_path_join (internal_path, SVN_LOCALE_RELATIVE_PATH, 00146 pool); 00147 bindtextdomain (PACKAGE_NAME, internal_path); 00148 apr_pool_destroy (pool); 00149 } 00150 #else 00151 bindtextdomain(PACKAGE_NAME, SVN_LOCALE_DIR); 00152 #endif 00153 textdomain(PACKAGE_NAME); 00154 #endif 00155 00156 00157 #if defined(WIN32) || defined(__CYGWIN__) 00158 apr_pool_t* pool = svn_pool_create (NULL); 00159 /* See http://svn.collab.net/repos/svn/trunk/notes/asp-dot-net-hack.txt */ 00160 /* ### This code really only needs to be invoked by consumers of 00161 ### the libsvn_wc library, which basically means SVNClient. */ 00162 if (getenv ("SVN_ASP_DOT_NET_HACK")) 00163 { 00164 svn_error_t *err = svn_wc_set_adm_dir("_svn", pool); 00165 if (err) 00166 { 00167 if (stderr) 00168 { 00169 fprintf(stderr, 00170 "%s: error: SVN_ASP_DOT_NET_HACK failed: %s\n", 00171 "svnjavahl", err->message); 00172 } 00173 svn_error_clear(err); 00174 return FALSE; 00175 } 00176 } 00177 svn_pool_destroy(pool); 00178 #endif 00179 00180 return true; 00181 } 00182 00183 /*static*/ void Util::throwNullPointerException( const char * p_msg) 00184 { 00185 throw std::invalid_argument(p_msg); 00186 } 00187 00188 00199 void Util::assembleErrorMessage(svn_error_t *err, int depth, 00200 apr_status_t parent_apr_err, 00201 std::string &buffer) 00202 { 00203 // buffer for a single error message 00204 char errbuf[256]; 00205 00206 /* Pretty-print the error */ 00207 /* Note: we can also log errors here someday. */ 00208 00209 /* When we're recursing, don't repeat the top-level message if its 00210 the same as before. */ 00211 if (depth == 0 || err->apr_err != parent_apr_err) 00212 { 00213 /* Is this a Subversion-specific error code? */ 00214 if ((err->apr_err > APR_OS_START_USEERR) 00215 && (err->apr_err <= APR_OS_START_CANONERR)) 00216 buffer.append(svn_strerror (err->apr_err, errbuf, sizeof (errbuf))); 00217 /* Otherwise, this must be an APR error code. */ 00218 else 00219 buffer.append(apr_strerror (err->apr_err, errbuf, sizeof (errbuf))); 00220 buffer.append("\n"); 00221 } 00222 if (err->message) 00223 buffer.append( "svn: ").append(err->message).append("\n"); 00224 00225 if (err->child) 00226 assembleErrorMessage(err->child, depth + 1, err->apr_err, buffer); 00227 00228 } 00229 00230 00236 /*static*/ void Util::handleSVNError( svn_error_t * p_err) 00237 { 00238 if( !p_err) 00239 { 00240 //std::cout << "handleSVNError: p_err is 0" << std::endl; 00241 return; 00242 } 00243 //std::cout << "Error " << ( p_err->message?p_err->message:"<<nomsg>>") << std::endl; 00244 00245 std::string buffer; 00246 assembleErrorMessage( p_err, 0, APR_SUCCESS, buffer); 00247 buffer = "SVN Error details follow:\n" + buffer; 00248 AfxMessageBox( buffer.c_str()); 00249 00250 // modifying buffer for the console 00251 // replacing '\n's with <br>s 00252 std::string::size_type p = buffer.find( "\n"); 00253 while( std::string::npos != p) 00254 { 00255 buffer.replace( p, 1, "<br>"); 00256 p = buffer.find( "\n"); 00257 } 00258 // removing '\r's 00259 p = buffer.find( "\r"); 00260 while( std::string::npos != p) 00261 { 00262 buffer.erase( p, 1); 00263 p = buffer.find( "\r"); 00264 } 00265 // FIXME: MsgConsole::ssendMsg( buffer, MSG_ERROR); 00266 //std::cout << "Error " << buffer << std::endl; 00267 00268 //if( p_err->apr_err == SVN_ERR_RA_ILLEGAL_URL) 00269 // std::cout << "Error SVN_ERR_RA_ILLEGAL_URL, [URL does not exist]. " << std::endl; 00270 //if( p_err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE) 00271 // std::cout << "Error SVN_ERR_UNSUPPORTED_FEATURE, [URL refs to file instead of a directory]. " << std::endl; 00272 //if( p_err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) 00273 // std::cout << "Error SVN_ERR_UNVERSIONED_RESOURCE " << ( p_err->file? p_err->file: "<<nofile>>") << " msg = " << ( p_err->message?p_err->message:"<<nomsg>>") << std::endl; 00274 //if( p_err->apr_err == SVN_ERR_RA_ILLEGAL_URL) 00275 // std::cout << "Error SVN_ERR_RA_ILLEGAL_URL " << ( p_err->file? p_err->file: "<<nofile>>") << " msg = " << ( p_err->message?p_err->message:"<<nomsg>>") << std::endl; 00276 //if( p_err->apr_err == SVN_ERR_RA_DAV_SOCK_INIT) 00277 // std::cout << "Error SVN_ERR_RA_DAV_SOCK_INIT " << (p_err->file?p_err->file:"") << " msg = " << ( p_err->message?p_err->message:"<<nomsg>>") << std::endl; 00278 //if( p_err->child) 00279 // handleSVNError( p_err->child); 00280 } 00281 00282 /*static*/ svn_error_t * Util::preprocessPath(const char *&path, apr_pool_t * pool) 00283 { 00284 /* URLs and wc-paths get treated differently. */ 00285 if (svn_path_is_url (path)) 00286 { 00287 /* No need to canonicalize a URL's case or path separators. */ 00288 00289 /* Convert to URI. */ 00290 path = svn_path_uri_from_iri (path, pool); 00291 /* Auto-escape some ASCII characters. */ 00292 path = svn_path_uri_autoescape (path, pool); 00293 00294 /* The above doesn't guarantee a valid URI. */ 00295 if (! svn_path_is_uri_safe (path)) 00296 return svn_error_createf (SVN_ERR_BAD_URL, 0, 00297 "URL '%s' is not properly URI-encoded", 00298 path); 00299 00300 /* Verify that no backpaths are present in the URL. */ 00301 if (svn_path_is_backpath_present (path)) 00302 return svn_error_createf (SVN_ERR_BAD_URL, 0, 00303 "URL '%s' contains a '..' element", 00304 path); 00305 00306 /* strip any trailing '/' */ 00307 path = svn_path_canonicalize (path, pool); 00308 } 00309 else /* not a url, so treat as a path */ 00310 { 00311 const char *apr_target; 00312 char *truenamed_target; /* APR-encoded */ 00313 apr_status_t apr_err; 00314 00315 /* canonicalize case, and change all separators to '/'. */ 00316 SVN_ERR (svn_path_cstring_from_utf8 (&apr_target, path, 00317 pool)); 00318 apr_err = apr_filepath_merge (&truenamed_target, "", apr_target, 00319 APR_FILEPATH_TRUENAME, pool); 00320 00321 if (!apr_err) 00322 /* We have a canonicalized APR-encoded target now. */ 00323 apr_target = truenamed_target; 00324 else if (APR_STATUS_IS_ENOENT (apr_err)) 00325 /* It's okay for the file to not exist, that just means we 00326 have to accept the case given to the client. We'll use 00327 the original APR-encoded target. */ 00328 ; 00329 else 00330 return svn_error_createf (apr_err, NULL, 00331 "Error resolving case of '%s'", 00332 svn_path_local_style (path, 00333 pool)); 00334 00335 /* convert back to UTF-8. */ 00336 SVN_ERR (svn_path_cstring_to_utf8 (&path, apr_target, pool)); 00337 path = svn_path_canonicalize (path, pool); 00338 00339 } 00340 return NULL; 00341 } 00342 00343 #endif