int P4ClientAPI::ConnectOrReconnect() { if( IsTrackMode() ) client.SetProtocol( "track", "" ); Error e; ResetFlags(); client.Init( &e ); if ( e.Test() && exceptionLevel ) { return Except( "P4:connect()", &e ); } if ( e.Test() ) return 0; // If an iterator is defined, reset the break functionality // for the KeepAlive function if( ui.GetHandler() != LUA_NOREF ) { client.SetBreak( &ui ); } SetConnected(); lua_pushboolean( L, true ); return 1; }
int P4ClientApi::FormatSpec( const char * type, int table ) { if ( !specMgr.HaveSpecDef( type ) ) { StrBuf m; m = "No spec definition for "; m.Append( type ); m.Append( " objects." ); return Except( "P4#format_spec", m.Text() ); } // Got a specdef so now we can attempt to convert. StrBuf buf; Error e; specMgr.SpecToString( type, table, buf, &e ); if( !e.Test() ) { lua_pushstring( L, buf.Text() ); return 1; } StrBuf m; m = "Error converting hash to a string."; if( e.Test() ) e.Fmt( m, EF_PLAIN ); return Except( "P4#format_spec", m.Text() ); }
bool P4ClientApi::SetEnv( const char *var, const char *value ) { Error e; enviro->Set( var, value, &e ); return !e.Test(); }
int P4MergeData::RunMergeTool() { Error e; ui->Merge( merger->GetBaseFile(), merger->GetTheirFile(), merger->GetYourFile(), merger->GetResultFile(), &e ); if( e.Test() ) lua_pushboolean( L, false ); else lua_pushboolean( L, true ); return 1; }
BOOL CTempDirPage::TestTempDir( LPCTSTR path ) { BOOL success=FALSE; CString filename(path); FileSys *pFile= FileSys::Create( (enum FileSysType) FST_BINARY ); pFile->SetDeleteOnClose(); // TODO: calc a unique name. but for time being, change that // a user has this exact file as readonly is as likely as // three atoms colliding CString TempName; TempName.Format( _T("%s\\p4win.p4wintempdir.test"), path); pFile->Set(CharFromCString(TempName)); Error e; e.Clear(); // Prepare write (makes dir as required) pFile->MkDir( &e ); if( !e.Test() ) { // Open it pFile->Perms( FPM_RO ); pFile->Open( FOM_WRITE, &e ); pFile->Close(&e); } if(!e.Test()) success=TRUE; delete pFile; if(!success) AfxMessageBox(IDS_TEMPORARY_FILES_DIRECTORY_NOT_WRITEABLE, MB_ICONSTOP); return success; }
// // RunCmd is a private function to work around an obscure protocol // bug in 2000.[12] servers. Running a "p4 -Ztag client -o" messes up the // protocol so if they're running this command then we disconnect and // reconnect to refresh it. For efficiency, we only do this if the // server2 protocol is either 9 or 10 as other versions aren't affected. // void P4ClientApi::RunCmd( const char *cmd, ClientUser *ui, int argc, char * const *argv, int table ) { client.SetProg( &prog ); if( version.Length() ) client.SetVersion( &version ); if( mode & M_TAGGED ) client.SetVar( "tag" ); // If maxresults or maxscanrows is set, enforce them now if( maxResults ) client.SetVar( "maxResults", maxResults ); if( maxScanRows ) client.SetVar( "maxScanRows", maxScanRows ); if( maxLockTime ) client.SetVar( "maxLockTime", maxLockTime ); client.SetBreak( &cb ); client.SetArgv( argc, argv ); client.Run( cmd, ui ); // Have to request server2 protocol *after* a command has been run. I // don't know why, but that's the way it is. if ( ! server2 ) { StrPtr *pv = client.GetProtocol( "server2" ); if ( pv ) server2 = pv->Atoi(); } if ( IS_TAGGED(mode) && StrRef( cmd ) == "client" && server2 >= 9 && server2 <= 10 ) { if ( argc && ( StrRef( argv[ 0 ] ) == "-o" ) ) { if ( P4LUADEBUG_COMMANDS ) printf( "Resetting client to avoid 2000.[12] protocol bug\n" ); Error e; client.Final( &e ); client.Init( &e ); // Pass any errors down to the UI, so they'll get picked up. if ( e.Test() ) ui->HandleError( &e ); } } }
int P4ClientApi::Connect() { if ( P4LUADEBUG_COMMANDS ) fprintf( stderr, "[P4] Connecting to Perforce\n" ); if ( initCount ) { lua_pushboolean( L, true ); lua_pushstring( L, "P4#connect - Perforce client already connected!" ); return 2; } Error e; client.Init( &e ); if ( e.Test() ) return Except( "P4#connect", &e ); initCount++; lua_pushboolean( L, true ); return 1; }
int P4ClientApi::ParseSpec( const char * type, const char *form ) { if ( !specMgr.HaveSpecDef( type ) ) { StrBuf m; m = "No spec definition for "; m.Append( type ); m.Append( " objects." ); return Except( "P4#parse_spec", m.Text() ); } // Got a specdef so now we can attempt to parse it. Error e; int v; v = specMgr.StringToSpec( type, form, &e ); if ( e.Test() ) { return Except( "P4#parse_spec", &e ); } return 1; }
int P4ClientAPI::ParseSpec( const char * type, const char *form ) { if ( !specMgr.HaveSpecDef( type ) ) { if( exceptionLevel ) { StrBuf m; m = "No spec definition for "; m.Append( type ); m.Append( " objects." ); return Except( "P4:parse_spec", m.Text() ); } } else { lua_pushboolean( L, false ); return 1; } // Got a specdef so now we can attempt to parse it. Error e; int v = specMgr.StringToSpec( type, form, &e ); if ( e.Test() ) { if ( exceptionLevel ) { return Except( "P4:parse_spec()", &e ); } else { lua_pushboolean( L, false ); return 1; } } return 1; }
bool Provider::Connect() { if ( m_IsConnected ) { // This extra 'info' command is unfortunate but necessary // .Dropped() can only be trusted immediately after .Run(), so do a lightweight run here to update .Dropped()'s state class NullClient : public ClientUser { public: virtual void OutputInfo( char level, const char* data ) {} virtual void OutputError( const char* data ) {} } nullClient; m_Client.SetBreak( this ); m_Client.Run( "info", &nullClient ); } if ( m_Client.Dropped() ) { Error e; m_Client.Final( &e ); m_IsConnected = false; #ifdef PERFORCE_DEBUG_CONNECT if ( e.Test() ) { StrBuf buf; e.Fmt( &buf, EF_PLAIN ); Log::Warning( "%s\n", buf.Text() ); } #endif } if ( !m_IsConnected ) { Error e; m_Client.SetProtocol( "tag", "" ); m_Client.Init( &e ); m_Client.SetBreak( this ); #ifdef PERFORCE_DEBUG_CONNECT if ( e.Test() ) { StrBuf buf; e.Fmt( &buf, EF_PLAIN ); Log::Warning( "%s\n", buf.Text() ); } #endif char buf[ 64 ]; sprintf_s( buf, sizeof(buf), "Perforce.dll" ); buf[ sizeof(buf) - 1 ] = 0; m_Client.SetProg( buf ); bool converted = Helium::ConvertString( m_Client.GetUser().Text(), m_UserName ); HELIUM_ASSERT( converted ); converted = Helium::ConvertString( m_Client.GetClient().Text(), m_ClientName ); HELIUM_ASSERT( converted ); m_IsConnected = e.Test() == 0; } return m_IsConnected; }
void ClientUserLua::OutputStat( StrDict *values ) { StrPtr * spec = values->GetVar( "specdef" ); StrPtr * data = values->GetVar( "data" ); StrPtr * sf = values->GetVar( "specFormatted" ); StrDict * dict = values; SpecDataTable specData; Error e; // // Determine whether or not the data we've got contains a spec in one form // or another. 2000.1 -> 2005.1 servers supplied the form in a data variable // and we use the spec variable to parse the form. 2005.2 and later servers // supply the spec ready-parsed but set the 'specFormatted' variable to tell // the client what's going on. Either way, we need the specdef variable set // to enable spec parsing. // int isspec = spec && ( sf || data ); // // Save the spec definition for later // if( spec ) specMgr->AddSpecDef( cmd.Text(), spec->Text() ); // // Parse any form supplied in the 'data' variable and convert it into a // dictionary. // if( spec && data ) { // 2000.1 -> 2005.1 server's handle tagged form output by supplying the form // as text in the 'data' variable. We need to convert it to a dictionary // using the supplied spec. if( P4LUADEBUG_CALLS ) fprintf( stderr, "[P4] OutputStat() - parsing form\n" ); // Parse the form. Use the ParseNoValid() interface to prevent // errors caused by the use of invalid defaults for select items in // jobspecs. //#if P4APIVER_ID >= 513538 Spec s( spec->Text(), "", &e ); //#else //Spec s( spec->Text(), "" ); //#endif if( !e.Test() ) s.ParseNoValid( data->Text(), &specData, &e ); if( e.Test() ) { HandleError( &e ); return; } dict = specData.Dict(); } // // If what we've got is a parsed form, then we'll convert it to a P4::Spec // object. Otherwise it's a plain hash. // if( isspec ) { if( P4LUADEBUG_CALLS ) fprintf(stderr ,"[P4] OutputStat() - Converting to P4::Spec object\n"); results.AddOutput( specMgr->StrDictToSpec( dict, spec ) ); lua_pop( L, 1 ); } else { if( P4LUADEBUG_CALLS ) fprintf(stderr ,"[P4] OutputStat() - Converting to hash\n"); results.AddOutput( specMgr->StrDictToHash( dict ) ); lua_pop( L, 1 ); } }
// Create from an fstat result set. BOOL CP4FileStats::Create(StrDict *client) { int i; StrPtr *str; Error err; // Get the depot name str= client->GetVar( "depotFile", &err); // name in depot ASSERT(str || err.Test()); if(err.Test()) goto badFile; m_DepotPath = CharToCString(str->Value()); // If the client path exists, note that file is in client view str= client->GetVar( "clientFile" ); if(str) { m_ClientPath = CharToCString(str->Value()); m_ClientPath.Replace(_T('/'), _T('\\')); } else { // need to determine if the client path doesn't exist or doesn't translate // we can't handle the no translation case. CString txt = FormatError(&err); if(txt.Find(_T("No Translation")) == 0) goto badFile; // there is no client path m_ClientPath=_T(""); } // Concatenate a list of all other users with the file open { char varName[] = "otherOpen "; char varNam2[] = "otherAction "; for(m_OtherOpens=m_OtherOpenAction=0; m_OtherOpens < 100; m_OtherOpens++) { _itoa(m_OtherOpens, varName+9, 10); if( (str=client->GetVar( varName )) == 0 ) break; else { if(m_OtherOpens==0) m_OtherUsers = CharToCString(str->Value()); else { m_OtherUsers+=_T("/"); m_OtherUsers+=CharToCString(str->Value()); } if (m_OtherOpenAction != F_DELETE) { _itoa(m_OtherOpens, varNam2+11, 10); if ( (str=client->GetVar( varNam2 )) != 0) { m_OtherOpenAction = actionByName(CharToCString(str->Value())); } } } } } if( (str= client->GetVar( "headRev" )) != NULL) m_HeadRev=atol(str->Value()); if( (str= client->GetVar( "haveRev" )) != NULL) m_HaveRev=atol(str->Value()); if( (str= client->GetVar( "change" )) != NULL) m_OpenChangeNum=atol(str->Value()); if( (str= client->GetVar( "headChange" )) != NULL) m_HeadChangeNum=atol(str->Value()); if( (str= client->GetVar( "headTime" )) != NULL) m_HeadTime=atol(str->Value()); if( (str= client->GetVar( "ourLock" )) != NULL) m_MyLock=TRUE; if( (str= client->GetVar( "otherLock" )) != NULL) m_OtherLock=TRUE; if( (str= client->GetVar( "type" )) != NULL) m_Type= CharToCString(str->Value()); if( (str= client->GetVar( "headType" )) != NULL) m_HeadType= CharToCString(str->Value()); if( (str= client->GetVar( "headAction" )) != NULL) { m_HeadAction = actionByName(CharToCString(str->Value())); } ASSERT(client->GetVar("headAction")==NULL || m_HeadAction); if( (str= client->GetVar( "action" )) != NULL) { m_MyOpenAction = actionByName(CharToCString(str->Value())); } ASSERT(client->GetVar("action")==NULL || m_MyOpenAction); if (!m_HaveRev && !m_HeadRev && (m_MyOpenAction == F_ADD || m_MyOpenAction == F_BRANCH)) m_HaveRev = 1; if( (str= client->GetVar( "unresolved" )) != NULL) m_Unresolved=TRUE; str= client->GetVar( "actionOwner" ); if(str) { m_ActionOwner = CharToCString(str->Value()); if (Compare( m_ActionOwner, GET_P4REGPTR()->GetP4User() ) !=0) { m_OtherUserMyClient = TRUE; m_OtherUsers = m_ActionOwner + _T('@') + GET_P4REGPTR()->GetP4Client(); } } str= client->GetVar( "digest" ); if(str) m_Digest = CharToCString(str->Value()); if( (str= client->GetVar( "fileSize" )) != NULL) m_FileSize=atol(str->Value()); // In release builds, these values may be zero for an unrecognized // file type or action, which maps to F_UNKNOWNFILETYPE or F_UNKNOWNACTION // ASSERT(client->GetVar("headType")== NULL || m_HeadType); // commented out as useless and irritating in debug version - leighb 99/11/30 ASSERT(client->GetVar("headAction")==NULL || m_HeadAction); ASSERT(client->GetVar("action")==NULL || m_MyOpenAction); return TRUE; badFile: // most likely a translation failure. Nothing to do but ignore this file. return FALSE; }
void PythonClientUser::OutputStat( StrDict *values ) { EnsurePythonLock guard; StrPtr * spec = values->GetVar( "specdef" ); StrPtr * data = values->GetVar( "data" ); StrPtr * sf = values->GetVar( "specFormatted" ); StrDict * dict = values; SpecDataTable specData; Error e; // // Determine whether or not the data we've got contains a spec in one form // or another. 2000.1 -> 2005.1 servers supplied the form in a data variable // and we use the spec variable to parse the form. 2005.2 and later servers // supply the spec ready-parsed but set the 'specFormatted' variable to tell // the client what's going on. Either way, we need the specdef variable set // to enable spec parsing. // int isspec = spec && ( sf || data ); // // Save the spec definition for later // if( spec ) specMgr->AddSpecDef( cmd.Text(), spec->Text() ); // // Parse any form supplied in the 'data' variable and convert it into a // dictionary. // if( spec && data ) { // 2000.1 -> 2005.1 server's handle tagged form output by supplying the form // as text in the 'data' variable. We need to convert it to a dictionary // using the supplied spec. if( P4PYDBG_CALLS ) cerr << "[P4] OutputStat() - parsing form" << endl; // Parse the form. Use the ParseNoValid() interface to prevent // errors caused by the use of invalid defaults for select items in // jobspecs. Spec s( spec->Text(), "", &e ); if( !e.Test() ) s.ParseNoValid( data->Text(), &specData, &e ); if( e.Test() ) { HandleError( &e ); return; } dict = specData.Dict(); } // // If what we've got is a parsed form, then we'll convert it to a P4::Spec // object. Otherwise it's a plain dict. // PyObject * r = 0; if( isspec ) { if( P4PYDBG_CALLS ) cerr << "[P4] OutputStat() - Converting to P4::Spec object" << endl; r = specMgr->StrDictToSpec( dict, spec ); } else { if( P4PYDBG_CALLS ) cerr << "[P4] OutputStat() - Converting to dict" << endl; r = specMgr->StrDictToDict( dict ); } ProcessOutput("outputStat", r ); }