summaryrefslogtreecommitdiff
path: root/utils/getbugs/getbugs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/getbugs/getbugs.cpp')
-rw-r--r--utils/getbugs/getbugs.cpp1005
1 files changed, 1005 insertions, 0 deletions
diff --git a/utils/getbugs/getbugs.cpp b/utils/getbugs/getbugs.cpp
new file mode 100644
index 0000000..2ce5b5d
--- /dev/null
+++ b/utils/getbugs/getbugs.cpp
@@ -0,0 +1,1005 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+#include <stdio.h>
+#include <windows.h>
+#include "tier0/dbg.h"
+#include "utldict.h"
+#include "filesystem.h"
+#include "KeyValues.h"
+#include "cmdlib.h"
+#include "interface.h"
+#include "imysqlwrapper.h"
+#include "../bugreporter/trktool.h"
+#include "utlbuffer.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <direct.h>
+
+bool uselogfile = false;
+
+static bool spewed = false;
+
+static char workingdir[ 256 ];
+
+#define SCR_TYPE 1
+
+#define DEFAULT_DBMS "tracker"
+#define DEFAULT_USERNAME "PublicUser"
+#define DEFAULT_PASSWORD DEFAULT_USERNAME
+
+#define BUG_REPOSITORY_FMT "\\\\fileserver\\bugs\\public\\%s\\%s\\%s.zip"
+
+struct BugField_t
+{
+ BugField_t()
+ {
+ value[ 0 ] = 0;
+ numvalue = 0;
+ trkfield[ 0 ] = 0;
+ isdesc = false;
+ isnumeric = false;
+ }
+
+ char value[ 8192 ];
+ int numvalue;
+ char trkfield[ 256 ];
+ bool isdesc;
+ bool isnumeric;
+};
+
+#define SQL_SETVALUE( fieldname, sqlcolumn ) Q_strncpy( bug.m_pBug->fieldname, sqlcolumn.String(), sizeof( bug.m_pBug->fieldname ) );
+#define SQL_SETVALUESTRING( fieldname, str ) Q_strncpy( bug.m_pBug->fieldname, str, sizeof( bug.m_pBug->fieldname ) );
+
+
+class CBugReporter
+{
+public:
+
+ CBugReporter();
+ virtual ~CBugReporter();
+
+ // Initialize and login with default username/password for this computer (from resource/bugreporter.res)
+ virtual bool Init( char const *projectname );
+ virtual void Shutdown();
+
+ virtual bool IsPublicUI() { return false; }
+
+// Submission API
+ virtual void StartNewBugReport();
+ virtual void CancelNewBugReport();
+ virtual bool CommitBugReport( int& bugSubmissionId );
+
+ virtual void AddField( char const *fieldname, char const *value, bool isdesc = false );
+ virtual void AddNumericField( char const *fieldname, int value );
+
+private:
+
+ void ReportError(TRK_UINT rc, char const *func, char const *msg );
+ TRK_UINT Login(TRK_HANDLE* pTrkHandle, char const *projectname );
+
+ void SubstituteBugId( int bugid, char *out, int outlen, CUtlBuffer& src );
+
+ TRK_HANDLE trkHandle;
+ TRK_RECORD_HANDLE trkRecHandle;
+
+public:
+ CUtlVector< BugField_t > m_Fields;
+};
+
+void CBugReporter::AddField( char const *fieldname, char const *value, bool isdesc /*=false*/ )
+{
+ BugField_t fld;
+ Q_strncpy( fld.value, value, sizeof( fld.value ) );
+ fld.isnumeric = false;
+ Q_strncpy( fld.trkfield, fieldname, sizeof( fld.trkfield ) );
+ fld.isdesc = isdesc;
+
+ m_Fields.AddToTail( fld );
+}
+
+void CBugReporter::AddNumericField( char const *fieldname, int value )
+{
+ BugField_t fld;
+ fld.numvalue = value;
+ fld.isnumeric = true;
+ Q_strncpy( fld.trkfield, fieldname, sizeof( fld.trkfield ) );
+ fld.isdesc = false;
+
+ m_Fields.AddToTail( fld );
+}
+
+CBugReporter::CBugReporter()
+{
+ trkHandle = (TRK_HANDLE)0;
+ trkRecHandle = (TRK_RECORD_HANDLE)0;
+}
+
+CBugReporter::~CBugReporter()
+{
+ m_Fields.RemoveAll();
+}
+
+struct TRKELookup
+{
+ unsigned int id;
+ char const *str;
+};
+
+#define TRKERROR( id ) { id, #id }
+
+static TRKELookup g_Lookup[] =
+{
+ TRKERROR( TRK_SUCCESS ),
+ TRKERROR( TRK_E_VERSION_MISMATCH ),
+ TRKERROR( TRK_E_OUT_OF_MEMORY ),
+ TRKERROR( TRK_E_BAD_HANDLE ),
+ TRKERROR( TRK_E_BAD_INPUT_POINTER ),
+ TRKERROR( TRK_E_BAD_INPUT_VALUE ),
+ TRKERROR( TRK_E_DATA_TRUNCATED ),
+ TRKERROR( TRK_E_NO_MORE_DATA ),
+ TRKERROR( TRK_E_LIST_NOT_INITIALIZED ),
+ TRKERROR( TRK_E_END_OF_LIST ),
+ TRKERROR( TRK_E_NOT_LOGGED_IN ),
+ TRKERROR( TRK_E_SERVER_NOT_PREPARED ),
+ TRKERROR( TRK_E_BAD_DATABASE_VERSION ),
+ TRKERROR( TRK_E_UNABLE_TO_CONNECT ),
+ TRKERROR( TRK_E_UNABLE_TO_DISCONNECT ),
+ TRKERROR( TRK_E_UNABLE_TO_START_TIMER ),
+ TRKERROR( TRK_E_NO_DATA_SOURCES ),
+ TRKERROR( TRK_E_NO_PROJECTS ),
+ TRKERROR( TRK_E_WRITE_FAILED ),
+ TRKERROR( TRK_E_PERMISSION_DENIED ),
+ TRKERROR( TRK_E_SET_FIELD_DENIED ),
+ TRKERROR( TRK_E_ITEM_NOT_FOUND ),
+ TRKERROR( TRK_E_CANNOT_ACCESS_DATABASE ),
+ TRKERROR( TRK_E_CANNOT_ACCESS_QUERY ),
+ TRKERROR( TRK_E_CANNOT_ACCESS_INTRAY ),
+ TRKERROR( TRK_E_CANNOT_OPEN_FILE ),
+ TRKERROR( TRK_E_INVALID_DBMS_TYPE ),
+ TRKERROR( TRK_E_INVALID_RECORD_TYPE ),
+ TRKERROR( TRK_E_INVALID_FIELD ),
+ TRKERROR( TRK_E_INVALID_CHOICE ),
+ TRKERROR( TRK_E_INVALID_USER ),
+ TRKERROR( TRK_E_INVALID_SUBMITTER ),
+ TRKERROR( TRK_E_INVALID_OWNER ),
+ TRKERROR( TRK_E_INVALID_DATE ),
+ TRKERROR( TRK_E_INVALID_STORED_QUERY ),
+ TRKERROR( TRK_E_INVALID_MODE ),
+ TRKERROR( TRK_E_INVALID_MESSAGE ),
+ TRKERROR( TRK_E_VALUE_OUT_OF_RANGE ),
+ TRKERROR( TRK_E_WRONG_FIELD_TYPE ),
+ TRKERROR( TRK_E_NO_CURRENT_RECORD ),
+ TRKERROR( TRK_E_NO_CURRENT_NOTE ),
+ TRKERROR( TRK_E_NO_CURRENT_ATTACHED_FILE ),
+ TRKERROR( TRK_E_NO_CURRENT_ASSOCIATION ),
+ TRKERROR( TRK_E_NO_RECORD_BEGIN ),
+ TRKERROR( TRK_E_NO_MODULE ),
+ TRKERROR( TRK_E_USER_CANCELLED ),
+ TRKERROR( TRK_E_SEMAPHORE_TIMEOUT ),
+ TRKERROR( TRK_E_SEMAPHORE_ERROR ),
+ TRKERROR( TRK_E_INVALID_SERVER_NAME ),
+ TRKERROR( TRK_E_NOT_LICENSED )
+};
+
+void CBugReporter::ReportError(TRK_UINT rc, char const *func, char const *msg )
+{
+ if ( rc != TRK_SUCCESS )
+ {
+ switch (rc)
+ {
+ case TRK_E_ITEM_NOT_FOUND:
+ Msg( "%s %s was not found!\n", func, msg );
+ break;
+ case TRK_E_INVALID_FIELD:
+ Msg( "%s %s Invalid field!\n", func, msg );
+ break;
+ default:
+ int i = 0;
+ for ( i; i < ARRAYSIZE( g_Lookup ) ; ++i )
+ {
+ if ( g_Lookup[ i ].id == rc )
+ {
+ Msg( "%s returned %i - %s (%s)!\n", func, rc, g_Lookup[ i ].str, msg );
+ break;
+ }
+ }
+
+ if ( i >= ARRAYSIZE( g_Lookup ) )
+ {
+ Msg( "%s returned %i - %s! (%s)\n", func, rc, "???", msg );
+ }
+ break;
+ }
+ }
+}
+
+TRK_UINT CBugReporter::Login(TRK_HANDLE* pTrkHandle, char const *projectname )
+{
+ char dbms[50] = DEFAULT_DBMS;
+
+ char username[ 50 ];
+ char password[ 50 ];
+
+ Q_strncpy( username, DEFAULT_USERNAME, sizeof( username ) );
+ Q_strncpy( password, DEFAULT_PASSWORD, sizeof( password ) );
+
+ TRK_UINT rc = TrkProjectLogin(*pTrkHandle,
+ username,
+ password,
+ projectname,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ TRK_USE_INI_FILE_DBMS_LOGIN);
+
+ if (rc != TRK_SUCCESS)
+ {
+ rc = TrkProjectLogin(*pTrkHandle,
+ username,
+ "",
+ projectname,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ TRK_USE_INI_FILE_DBMS_LOGIN);
+ if (rc != TRK_SUCCESS)
+ {
+ Msg("Bug reporter init failed: Your tracker password must be your user name or blank.\n");
+ return rc;
+ }
+ }
+
+ TrkGetLoginDBMSName(*pTrkHandle, sizeof(dbms), dbms );
+
+ char projout[ 256 ];
+
+ TrkGetLoginProjectName(*pTrkHandle, sizeof( projout ), projout );
+
+ Msg( "Project: %s\n", projout );
+ Msg( "Server: %s\n", dbms );
+
+ return rc;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Initialize and login with default username/password for this computer (from resource/bugreporter.res)
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CBugReporter::Init( char const *projectname )
+{
+ TRK_UINT rc;
+ rc = TrkHandleAlloc( TRK_VERSION_ID, &trkHandle);
+ if ( rc != TRK_SUCCESS )
+ {
+ ReportError(rc, "TrkHandleAlloc", "Failed to Allocate Tracker Handle!");
+ return false;
+ }
+
+ // Login to default project out of INI file.
+ rc = Login( &trkHandle, projectname );
+ if (rc != TRK_SUCCESS)
+ {
+ return false;
+ }
+
+ rc = TrkRecordHandleAlloc(trkHandle, &trkRecHandle);
+ if (rc != TRK_SUCCESS)
+ {
+ ReportError(rc, "TrkRecordHandleAlloc",
+ "Failed to Allocate Tracker Record Handle!");
+ return false;
+ }
+
+ return true;
+}
+
+void CBugReporter::Shutdown()
+{
+ TRK_UINT rc;
+
+ if ( trkRecHandle )
+ {
+ rc = TrkRecordHandleFree(&trkRecHandle);
+ if (rc != TRK_SUCCESS)
+ {
+ ReportError(rc, "TrkRecordHandleFree", "Failed to Free Tracker Record Handle!");
+ }
+ }
+
+ if ( trkHandle )
+ {
+ rc = TrkProjectLogout(trkHandle);
+ if (rc != TRK_SUCCESS)
+ {
+ ReportError(rc, "TrkProjectLogout", "Failed to Logout of Project!");
+ }
+ else
+ {
+ rc = TrkHandleFree(&trkHandle);
+ if (rc != TRK_SUCCESS)
+ {
+ ReportError(rc, "TrkHandleFree", "Failed to Free Tracker Handle!");
+ }
+ }
+ }
+}
+
+void CBugReporter::StartNewBugReport()
+{
+ m_Fields.RemoveAll();
+}
+
+void CBugReporter::CancelNewBugReport()
+{
+ m_Fields.RemoveAll();
+}
+
+void CBugReporter::SubstituteBugId( int bugid, char *out, int outlen, CUtlBuffer& src )
+{
+ out[ 0 ] = 0;
+
+ char *dest = out;
+
+ src.SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
+
+ char const *replace = "\\BugId\\";
+ int replace_len = Q_strlen( replace );
+
+ for ( int pos = 0; pos <= src.TellPut() && ( ( dest - out ) < outlen ); )
+ {
+ char const *str = ( char const * )src.PeekGet( pos );
+ if ( !Q_strnicmp( str, replace, replace_len ) )
+ {
+ *dest++ = '\\';
+
+ char num[ 32 ];
+ Q_snprintf( num, sizeof( num ), "%i", bugid );
+ char *pnum = num;
+ while ( *pnum )
+ {
+ *dest++ = *pnum++;
+ }
+
+ *dest++ = '\\';
+ pos += replace_len;
+ continue;
+ }
+
+ *dest++ = *str;
+ ++pos;
+ }
+ *dest = 0;
+}
+
+bool CBugReporter::CommitBugReport( int& bugSubmissionId )
+{
+ bugSubmissionId = -1;
+
+ int fieldCount = m_Fields.Count();
+ if ( fieldCount == 0 )
+ return false;
+
+ TRK_UINT rc = 0;
+ rc = TrkNewRecordBegin( trkRecHandle, SCR_TYPE );
+ if ( rc != TRK_SUCCESS )
+ {
+ ReportError(rc, "TrkNewRecordBegin",
+ "Failed to TrkNewRecordBegin!");
+ return false;
+ }
+
+ CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
+
+ for ( int i = 0; i < fieldCount; ++i )
+ {
+ BugField_t& fld = m_Fields[ i ];
+
+ if ( !fld.isdesc )
+ {
+ // Populate fields
+ if ( !fld.isnumeric )
+ {
+ rc = TrkSetStringFieldValue(
+ trkRecHandle,
+ fld.trkfield,
+ fld.value );
+ }
+ else
+ {
+ rc = TrkSetNumericFieldValue(
+ trkRecHandle,
+ fld.trkfield,
+ fld.numvalue );
+ }
+ if ( rc != TRK_SUCCESS )
+ {
+ char es[ 256 ];
+ Q_snprintf( es, sizeof( es ), "Failed to add '%s'", fld.trkfield );
+
+ ReportError( rc, "TrkSetStringFieldValue", es );
+ return false;
+ }
+ }
+ else
+ {
+ buf.Printf( "%s\n", fld.value );
+
+ buf.PutChar( 0 );
+
+ rc = TrkSetDescriptionData( trkRecHandle,
+ buf.TellPut(),
+ (const char * )buf.Base(),
+ 0 );
+ if ( rc != TRK_SUCCESS )
+ {
+ ReportError(rc, "TrkSetDescriptionData",
+ "Failed to set description data!");
+ return false;
+ }
+ }
+
+ }
+
+ TRK_TRANSACTION_ID id;
+ rc = TrkNewRecordCommit( trkRecHandle, &id );
+ if ( rc != TRK_SUCCESS )
+ {
+ ReportError(rc, "TrkNewRecordCommit",
+ "Failed to TrkNewRecordCommit!");
+ return false;
+ }
+
+ TRK_UINT bugId;
+ rc = TrkGetNumericFieldValue( trkRecHandle, "Id", &bugId );
+ if ( rc != TRK_SUCCESS )
+ {
+ ReportError(rc, "TrkGetNumericFieldValue",
+ "Failed to TrkGetNumericFieldValue for bug Id #!");
+ }
+ else
+ {
+ bugSubmissionId = (int)bugId;
+ }
+
+ rc = TrkGetSingleRecord( trkRecHandle, bugId, SCR_TYPE );
+ if ( rc != TRK_SUCCESS )
+ {
+ ReportError( rc, "TrkGetSingleRecord",
+ "Failed to open bug id for update" );
+ return false;
+ }
+
+ rc = TrkUpdateRecordBegin( trkRecHandle );
+ if ( rc != TRK_SUCCESS )
+ {
+ ReportError( rc, "TrkUpdateRecordBegin",
+ "Failed to open bug id for update" );
+ return false;
+ }
+ else
+ {
+ int textbuflen = 2 * buf.TellPut() + 1;
+
+ char *textbuf = new char [ textbuflen ];
+ Q_memset( textbuf, 0, textbuflen );
+
+ SubstituteBugId( (int)bugId, textbuf, textbuflen, buf );
+
+ // Update the description with the substituted text!!!
+ rc = TrkSetDescriptionData( trkRecHandle,
+ Q_strlen( textbuf ) + 1,
+ (const char * )textbuf,
+ 0 );
+
+ delete[] textbuf;
+
+ if ( rc != TRK_SUCCESS )
+ {
+ ReportError(rc, "TrkSetDescriptionData(update)",
+ "Failed to set description data!");
+ return false;
+ }
+
+ rc = TrkUpdateRecordCommit( trkRecHandle, &id );
+ if ( rc != TRK_SUCCESS )
+ {
+ ReportError(rc, "TrkUpdateRecordCommit",
+ "Failed to TrkUpdateRecordCommit for bug Id #!");
+ return false;
+ }
+ }
+
+ m_Fields.RemoveAll();
+
+ return true;
+}
+
+SpewRetval_t SpewFunc( SpewType_t type, char const *pMsg )
+{
+ spewed = true;
+
+ printf( "%s", pMsg );
+ OutputDebugString( pMsg );
+
+ if ( type == SPEW_ERROR )
+ {
+ printf( "\n" );
+ OutputDebugString( "\n" );
+ }
+
+ return SPEW_CONTINUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : depth -
+// *fmt -
+// ... -
+//-----------------------------------------------------------------------------
+void vprint( int depth, const char *fmt, ... )
+{
+ char string[ 8192 ];
+ va_list va;
+ va_start( va, fmt );
+ vsprintf( string, fmt, va );
+ va_end( va );
+
+ FILE *fp = NULL;
+
+ if ( uselogfile )
+ {
+ fp = fopen( "log.txt", "ab" );
+ }
+
+ while ( depth-- > 0 )
+ {
+ printf( " " );
+ OutputDebugString( " " );
+ if ( fp )
+ {
+ fprintf( fp, " " );
+ }
+ }
+
+ ::printf( "%s", string );
+ OutputDebugString( string );
+
+ if ( fp )
+ {
+ char *p = string;
+ while ( *p )
+ {
+ if ( *p == '\n' )
+ {
+ fputc( '\r', fp );
+ }
+ fputc( *p, fp );
+ p++;
+ }
+ fclose( fp );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void printusage( void )
+{
+ vprint( 0, "usage: getbugs pvcsproject hostname database username password contentadminexe <startbug endbug>\n\
+ \ne.g.: getbugs \"Steam Beta\" steamweb cserr username password \"u:/p4clients/yahn_steam_work/projects/gazelleproto/tools/contentadmin/vc70_debug_static/contentadmin.exe\" 1 10\n" );
+
+ // Exit app
+ exit( 1 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CheckLogFile( void )
+{
+ if ( uselogfile )
+ {
+ _unlink( "log.txt" );
+ vprint( 0, " Outputting to log.txt\n" );
+ }
+}
+
+void PrintHeader()
+{
+ vprint( 0, "Valve Software - getbugs.exe (%s)\n", __DATE__ );
+ vprint( 0, "--- Pulls public bugreporter bugs into PVCS tracker ---\n" );
+}
+
+bool GetBugZip( int bugnum, char const *admin )
+{
+ bool retval = false;
+
+ char commandline[ 512 ];
+ char directory[ 512 ];
+
+ Q_strncpy( directory, admin, sizeof( directory ) );
+ Q_StripFilename( directory );
+
+
+ // sprintf( commandline, "msdev engdll.dsw /MAKE \"quiver - Win32 GL Debug\" /OUT log.txt" );
+
+ // Builds the default configuration
+ sprintf( commandline, "\"%s\" bugreport %i", admin, bugnum );
+
+ PROCESS_INFORMATION pi;
+ memset( &pi, 0, sizeof( pi ) );
+
+ STARTUPINFO si;
+ memset( &si, 0, sizeof( si ) );
+ si.cb = sizeof( si );
+
+ if ( !CreateProcess( NULL, commandline, NULL, NULL, TRUE, 0, NULL, directory, &si, &pi ) )
+ {
+ LPVOID lpMsgBuf;
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+ // Process any inserts in lpMsgBuf.
+ // ...
+ // Display the string.
+ MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
+ // Free the buffer.
+ LocalFree( lpMsgBuf );
+ return retval;
+ }
+
+ // Wait until child process exits.
+ WaitForSingleObject( pi.hProcess, INFINITE );
+
+ DWORD exitCode = (DWORD)-1;
+ if ( GetExitCodeProcess( pi.hProcess, &exitCode ) )
+ {
+ if ( exitCode == 0 )
+ {
+ retval = true;
+ }
+ }
+
+ // Close process and thread handles.
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+
+ return retval;
+}
+
+void CreateDirHierarchy(const char *path)
+{
+ char temppath[512];
+ Q_strncpy( temppath, path, sizeof(temppath) );
+
+ for (char *ofs = temppath+1 ; *ofs ; ofs++)
+ {
+ if (*ofs == '/' || *ofs == '\\')
+ { // create the directory
+ char old = *ofs;
+ *ofs = 0;
+ _mkdir (temppath);
+ *ofs = old;
+ }
+ }
+}
+
+
+void GetBugInfo( CBugReporter& bug, char const *host, char const *database, char const *username, char const *password, char const *admin, int startbug, int endbug )
+{
+ // Now connect to steamweb and update the engineaccess table
+ CSysModule *sql = Sys_LoadModule( "mysql_wrapper" );
+ if ( sql )
+ {
+ CreateInterfaceFn factory = Sys_GetFactory( sql );
+ if ( factory )
+ {
+ IMySQL *mysql = ( IMySQL * )factory( MYSQL_WRAPPER_VERSION_NAME, NULL );
+ if ( mysql )
+ {
+ if ( mysql->InitMySQL( database, host, username, password ) )
+ {
+ char q[ 512 ];
+
+ /*
+ Q_snprintf( q, sizeof( q ), "insert into engineaccess (BuildIdentifier,AllowAccess) values (\"%s\",1);",
+ argv[2] );
+
+ int retcode = mysql->Execute( q );
+ if ( retcode != 0 )
+ {
+ printf( "Query %s failed\n", q );
+ }
+ else
+ {
+ printf( "Successfully added buildidentifier '%s' to %s:%s\n",
+ argv[ 2 ], argv[ 3 ], argv[ 4 ] );
+ }
+ */
+
+ char where[ 256 ];
+ where[ 0 ] = 0;
+ if ( startbug != -1 && endbug != -1 )
+ {
+ Q_snprintf( where, sizeof( where ), "BugId>=%i and BugId<=%i and ", startbug, endbug );
+ }
+
+ Q_snprintf( q, sizeof( q ), "select BugId, Time, BuildNumber, ExeName, GameDirectory, MapName, Title, Description, IP,"
+ "BaseIP, RAM, CPU, ProcessorVendor, DXVersionHighPart, DXVersionLowPart, DXVendorID, DXDeviceID, OSVersion, "
+ "BugReportFilePath, ReportType, EMail, AccountName, SteamID, Processed, Important from bugreports where %s ( Processed is NULL or Processed = 0 );", where );
+
+
+ int retcode = mysql->Execute( q );
+ if ( retcode != 0 )
+ {
+ vprint( 0, "Query %s failed\n", q );
+ }
+ else
+ {
+ IMySQLRowSet *rows = mysql->DuplicateRowSet();
+
+ CUtlVector< int > processed;
+
+ if ( rows && rows->NumFields() > 0 )
+ {
+ while ( rows->NextRow() )
+ {
+ CColumnValue BugId = rows->GetColumnValue( "BugId" );
+ CColumnValue Time = rows->GetColumnValue( "Time" );
+ CColumnValue BuildNumber = rows->GetColumnValue( "BuildNumber" );
+ CColumnValue ExeName = rows->GetColumnValue( "ExeName" );
+ CColumnValue GameDirectory = rows->GetColumnValue( "GameDirectory" );
+ CColumnValue MapName = rows->GetColumnValue( "MapName" );
+ CColumnValue Title = rows->GetColumnValue( "Title" );
+ CColumnValue Description = rows->GetColumnValue( "Description" );
+ CColumnValue IP = rows->GetColumnValue( "IP" );
+ CColumnValue BaseIP = rows->GetColumnValue( "BaseIP" );
+ CColumnValue RAM = rows->GetColumnValue( "RAM" );
+ CColumnValue CPU = rows->GetColumnValue( "CPU" );
+ CColumnValue ProcessorVendor = rows->GetColumnValue( "ProcessorVendor" );
+ CColumnValue DXVersionHighPart = rows->GetColumnValue( "DXVersionHighPart" );
+ CColumnValue DXVersionLowPart = rows->GetColumnValue( "DXVersionLowPart" );
+ CColumnValue DXVendorID = rows->GetColumnValue( "DXVendorID" );
+ CColumnValue DXDeviceID = rows->GetColumnValue( "DXDeviceID" );
+ CColumnValue OSVersion = rows->GetColumnValue( "OSVersion" );
+ CColumnValue BugReportFilePath = rows->GetColumnValue( "BugReportFilePath" );
+ CColumnValue ReportType = rows->GetColumnValue( "ReportType" );
+ CColumnValue EMail = rows->GetColumnValue( "EMail" );
+ CColumnValue Accountname = rows->GetColumnValue( "Accountname" );
+ CColumnValue SteamID = rows->GetColumnValue( "SteamID" );
+ CColumnValue Processed = rows->GetColumnValue( "Processed" );
+ CColumnValue Important = rows->GetColumnValue( "Important" );
+
+ bug.StartNewBugReport();
+
+ vprint( 1, "Processing bug %i\n", BugId.Int32() );
+
+ bug.AddField( "Owner", "PublicUser" );
+ bug.AddField( "Submitter", "PublicUser" );
+ bug.AddField( "Title", Title.String() );
+
+
+ bug.AddNumericField( "BugId", BugId.Int32() );
+ bug.AddNumericField( "Build", BuildNumber.Int32() );
+ bug.AddField( "Exe", ExeName.String() );
+ bug.AddField( "Gamedir", GameDirectory.String() );
+ bug.AddField( "Map", MapName.String() );
+ bug.AddField( "Operating System", OSVersion.String() );
+ bug.AddField( "Processor", ProcessorVendor.String() );
+ bug.AddNumericField( "Memory", RAM.Int32() );
+ bug.AddField( "SteamID", SteamID.String() );
+ bug.AddNumericField( "CPU", CPU.Int32() );
+
+ bug.AddField( "Time", Time.String() );
+
+ char dxversion[ 512 ];
+ int vhigh = DXVersionHighPart.Int32();
+ int vlow = DXVersionLowPart.Int32();
+
+ Q_snprintf( dxversion, sizeof( dxversion ), "%u.%u.%u.%u", ( vhigh >> 16 ) , vhigh & 0xffff, ( vlow >> 16 ), vlow & 0xffff );
+
+ bug.AddField( "DXVersion", dxversion);
+
+ bug.AddNumericField( "DXDevice", DXDeviceID.Int32() );
+ bug.AddNumericField( "DXVendor", DXVendorID.Int32() );
+
+ bug.AddField( "BugType", ReportType.String() );
+ bug.AddField( "E-Mail Address", EMail.String() );
+ bug.AddField( "Account Name", Accountname.String() );
+
+ char zipurl[ 512 ];
+ zipurl[ 0 ] = 0;
+
+ char basepath[ 512 ];
+ Q_FileBase( BugReportFilePath.String(), basepath, sizeof( basepath ) );
+
+ char desc[ 8192 ];
+
+ if ( BugReportFilePath.String()[ 0 ] )
+ {
+ Q_snprintf( zipurl, sizeof( zipurl ), BUG_REPOSITORY_FMT, database, "BugId", basepath );
+
+ Q_snprintf( desc, sizeof( desc ), "%s\n\nzip url: %s\n", Description.String(), zipurl );
+ }
+ else
+ {
+ Q_strncpy( desc, Description.String(), sizeof( desc ) );
+ }
+
+ bug.AddField( "Description", desc, true );
+
+ int trackerBugId = -1;
+
+ bool success = bug.CommitBugReport( trackerBugId );
+ if ( success )
+ {
+ // The public UI handles uploading on it's own...
+ // Fixup URL
+ if ( zipurl[ 0 ] )
+ {
+ char zipurlfixed[ 512 ];
+ char id[ 32 ];
+ Q_snprintf( id, sizeof( id ), "%i", trackerBugId );
+
+ // The upload destination
+ Q_snprintf( zipurlfixed, sizeof( zipurlfixed ), BUG_REPOSITORY_FMT, database, id, basepath );
+ Q_strlower( zipurlfixed );
+ Q_FixSlashes( zipurlfixed );
+
+ char admindir[ 512 ];
+ Q_strncpy( admindir, admin, sizeof( admindir ) );
+ Q_StripFilename( admindir );
+ Q_strlower( admindir );
+ Q_FixSlashes( admindir );
+
+
+ char zipurllocal[ 512 ];
+ Q_snprintf( zipurllocal, sizeof( zipurllocal ), "%s\\%s.zip", admindir, basepath );
+ Q_strlower( zipurllocal );
+ Q_FixSlashes( zipurllocal );
+
+ // Get local copy of .zip file
+
+ if ( GetBugZip( BugId.Int32(), admin ) )
+ {
+ struct _stat statbuf;
+
+ if ( _stat( zipurllocal, &statbuf ) == 0 )
+ {
+ CreateDirHierarchy( zipurlfixed );
+
+ MoveFile( zipurllocal, zipurlfixed );
+
+ // Mark processed
+ processed.AddToTail( BugId.Int32() );
+ }
+ }
+ else
+ {
+ Warning( "Unable to retrieve bug file for %i\n", BugId.Int32() );
+ }
+ }
+ else
+ {
+ processed.AddToTail( BugId.Int32() );
+ }
+
+ }
+ else
+ {
+ Warning( "Unable to post bug report to database\n" );
+ }
+ }
+
+ // Discard memory
+ rows->Release();
+
+ int c = processed.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ Q_snprintf( q, sizeof( q ), "update bugreports set Processed=1 where BugId=%i;", processed[ i ] );
+
+ retcode = mysql->Execute( q );
+ if ( retcode != 0 )
+ {
+ Msg( "Query failed '%s'\n", q );
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ vprint( 0, "InitMySQL failed\n" );
+ }
+
+ mysql->Release();
+ }
+ else
+ {
+ vprint( 0, "Unable to connect via mysql_wrapper\n");
+ }
+ }
+ else
+ {
+ vprint( 0, "Unable to get factory from mysql_wrapper.dll, not updating access mysql table!!!" );
+ }
+
+ Sys_UnloadModule( sql );
+ }
+ else
+ {
+ vprint( 0, "Unable to load mysql_wrapper.dll, not updating access mysql table!!!" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : argc -
+// argv[] -
+// Output : int
+//-----------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+ SpewOutputFunc( SpewFunc );
+ SpewActivate( "getbugs", 2 );
+
+ uselogfile = true;
+ verbose = true;
+
+ if ( argc != 7 && argc != 9 )
+ {
+ PrintHeader();
+ printusage();
+ }
+
+ CheckLogFile();
+
+ PrintHeader();
+
+ vprint( 0, " Getting bugs...\n" );
+
+ workingdir[0] = 0;
+ Q_getwd( workingdir, sizeof( workingdir ) );
+
+ // If they didn't specify -game on the command line, use VPROJECT.
+ CmdLib_InitFileSystem( workingdir );
+
+
+ CBugReporter bugreporter;
+ if ( !bugreporter.Init( argv[ 1 ] ) )
+ {
+ vprint( 0, "Couldn't init bug reporter\n" );
+ return 0;
+ }
+
+ if ( argc == 9 )
+ {
+ GetBugInfo( bugreporter, argv[2], argv[3], argv[4], argv[5], argv[ 6 ], atoi( argv[ 7 ] ), atoi( argv[ 8 ] ) );
+ }
+ else
+ {
+ GetBugInfo( bugreporter, argv[2], argv[3], argv[4], argv[5], argv[ 6 ], -1, -1 );
+ }
+
+
+ bugreporter.Shutdown();
+ CmdLib_TermFileSystem();
+
+ return 0;
+}