diff -r 000000000000 -r 7f656887cf89 commands/cloggerconfig/cloggerconfig.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commands/cloggerconfig/cloggerconfig.cpp Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,433 @@ +// cloggerconfig.cpp +// +// Copyright (c) 2007 - 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Accenture - Initial contribution +// + +#include +#include +#include +#include + +using namespace IoUtils; + +class CCmdCloggerConfig : public CCommandBase + { +public: + static CCommandBase* NewLC(); + ~CCmdCloggerConfig(); +private: + CCmdCloggerConfig(); + void PrintLogL(); + void GetBackupFileNameL(TFileName& aName); + void SetAllL(TBool aEnabled); +private: // From CCommandBase. + virtual const TDesC& Name() const; + virtual void DoRunL(); + virtual void ArgumentsL(RCommandArgumentList& aArguments); + virtual void OptionsL(RCommandOptionList& aOptions); +private: + RClogger iClogger; + RCloggerLogConsumer iLogGetter; + TUint iGlobalOptions; + TBool iPersist; + TBool iReset; + HBufC* iTagName; + TUint iEnabledMask; + TUint iRotateOptions; + TBool iRotate; + TBool iFollow; + TBool iWipe; + TInt iNumBuffers; + TInt iBufferSize; + RBuf iTempBuffer; + TBool iRdebug; + TBool iBackup; + TBool iRestore; + TBool iDisableAll; + TBool iEnableAll; + }; + + +CCommandBase* CCmdCloggerConfig::NewLC() + { + CCmdCloggerConfig* self = new(ELeave) CCmdCloggerConfig(); + CleanupStack::PushL(self); + self->BaseConstructL(); + return self; + } + +CCmdCloggerConfig::~CCmdCloggerConfig() + { + iClogger.Close(); + iLogGetter.Close(); + delete iTagName; + iTempBuffer.Close(); + } + +CCmdCloggerConfig::CCmdCloggerConfig() + { + } + +const TDesC& CCmdCloggerConfig::Name() const + { + _LIT(KName, "cloggerconfig"); + return KName; + } + +#define WRITEIF(opt, flag) if (opt & (RClogger :: flag)) { Write(_L(#flag)); Write(_L(" ")); } + +void CCmdCloggerConfig::DoRunL() + { + if (iEnableAll && iDisableAll) + { + LeaveIfErr(KErrArgument, _L("Can't enable and disable all tags")); + } + + User::LeaveIfError(iClogger.Connect()); + + TBool listSettings = ETrue; + if (iReset) + { + iClogger.ResetSettings(); + listSettings = EFalse; + } + + if (iOptions.IsPresent(&iGlobalOptions)) + { + iClogger.SetGlobalOptions(iGlobalOptions); + listSettings = EFalse; + } + if (iOptions.IsPresent(&iRotateOptions)) + { + TInt n; + iClogger.GetRotateBehaviour(&n); + iClogger.SetRotateBehaviour(n, iRotateOptions); + listSettings = EFalse; + } + if (iNumBuffers || iBufferSize) + { + if (iNumBuffers == 0) + { + // Need to read it in as we have to set both at once. Bad API... + iClogger.GetRamBufferSize(&iNumBuffers); + } + if (iBufferSize == 0) + { + // Same reason as above + iBufferSize = iClogger.GetRamBufferSize(NULL); + } + iClogger.SetRamBufferSize(iBufferSize, iNumBuffers); + listSettings = EFalse; + } + if (iPersist || iBackup || iRestore) + { + // We don't do anything here, we take action at the end of this function + listSettings = EFalse; + } + if (iRotate) + { + TFileName name; + TInt err = iClogger.Rotate(name); + Printf(_L("Log rotated to %S\r\n"), &name); + if (err) PrintError(err, _L("Rotate returned error")); + listSettings = EFalse; + } + else if (iWipe) + { + TInt oldLogs; + TUint rotopt = iClogger.GetRotateBehaviour(&oldLogs); + iClogger.SetRotateBehaviour(KMaxTInt, RClogger::EDoNothingSpecial); // Change rotate behaviour temporarily + + TFileName name; + TInt err = iClogger.Rotate(name); + //Printf(_L("Log rotated to %S\r\n"), &name); + if (err) PrintError(err, _L("Rotate returned error")); + else + { + err = FsL().Delete(name); + + iClogger.SetRotateBehaviour(oldLogs, rotopt); // Restore old behaviour + LeaveIfErr(err, _L("Couldn't remove wiped log %S"), &name); + } + + listSettings = EFalse; + } + + if (iDisableAll) + { + SetAllL(EFalse); + listSettings = EFalse; + } + + if (iEnableAll) + { + SetAllL(ETrue); + listSettings = EFalse; + } + + if (iRdebug) + { + TUint opts = iClogger.GetGlobalOptions(); + opts |= RClogger::ERedirectRDebugPrintToClogger; + iClogger.SetGlobalOptions(opts); + + PrintLogL(); + } + + if (iFollow) + { + PrintLogL(); // Does not return + } + + if (iArguments.IsPresent(1)) + { + // Set + TInt err = iClogger.SetEnabled(*iTagName, iEnabledMask); + if (err == KErrNotFound) + { + PrintError(err, _L("Tag does not exist, couldn't set it. (NOTE: This behaviour will be changed in the future so you can set tags that haven't been created yet!)")); + User::Leave(KErrNotFound); + } + LeaveIfErr(err, _L("Couldn't enable tag.")); + listSettings = EFalse; + } + else if (iArguments.IsPresent(0)) + { + // Get + TUint32 e = iClogger.IsEnabled(*iTagName); + Printf(_L("Tag [%S] enabled: 0x%x\r\n"), iTagName, e); + listSettings = EFalse; + } + + if (listSettings) + { + // List global options + TUint globalOptions = iClogger.GetGlobalOptions(); + Printf(_L("Global options: 0x%x ( "), globalOptions); + if (!globalOptions) + { + Write(_L("None ")); + } + else + { + WRITEIF(globalOptions, EBufferLog); + WRITEIF(globalOptions, EMirrorToRDebugPrint); + WRITEIF(globalOptions, EMirrorToBluetooth); + WRITEIF(globalOptions, EMirrorToMessageQueue); + WRITEIF(globalOptions, ERedirectRDebugPrintToClogger); + WRITEIF(globalOptions, EDisableFileWriter); + } + Write(_L(")\r\n")); + + // List rotate options + TInt numLogs = 0; + TUint rotateBehaviour = iClogger.GetRotateBehaviour(&numLogs); + Printf(_L("Number of rotated logs to keep: %i\r\n"), numLogs); + Printf(_L("Rotate behaviour: 0x%x ( "), rotateBehaviour); + if (!rotateBehaviour) + { + Write(_L("EDoNothingSpecial ")); + } + else + { + WRITEIF(rotateBehaviour, ECopyRotatedToExternalMedia); + WRITEIF(rotateBehaviour, EAutoRotateAtStartup); + WRITEIF(rotateBehaviour, ECompressRotatedLogs); + } + Write(_L(")\r\n")); + + // List buffer size + TInt numBuffers = 0; + TInt bufSize = iClogger.GetRamBufferSize(&numBuffers); + Printf(_L("Number of RAM buffers: %i\r\n"), numBuffers); + Printf(_L("Size of RAM buffers: %i\r\n"), bufSize); + + // List tags + CDesC16Array* tags = NULL; + RBuf8 enabled; + iClogger.GetTagStatesL(tags, enabled); + TInt count = enabled.Size() / 4; + if (count) Printf(_L("\r\n")); + for (TInt i = 0; i < count; i++) + { + TPtrC tag = tags->operator[](i); + TUint32 e = ((TUint32*)enabled.Ptr())[i]; + Printf(_L("Tag [%S] enabled: 0x%x\r\n"), &tag, e); + } + delete tags; + enabled.Close(); + } + + if (iPersist) + { + iClogger.PersistSettings(); + } + + if (iBackup) + { + // Args should be: --exec 'cp -ro C:\Private\10202be9\persists\10272efd.cre E:\Private\10202be9\persists\10272efd.cre' + TFileName args; + GetBackupFileNameL(args); + + TInt len = args.Length(); + args.Append(args); + args.Append('\''); + args[0] = 'C'; + args.Insert(len, _L(" ")); + args.Insert(0, _L("--exec 'cp -ro ")); + + RChildProcess shell; + shell.CreateL(_L("fshell.exe"), args, IoSession(), Stdin(), Stdout(), Stderr()); + CleanupClosePushL(shell); + TRequestStatus stat; + shell.Run(stat); + User::WaitForRequest(stat); + LeaveIfErr(stat.Int(), _L("Failed to copy cenrep file")); + CleanupStack::PopAndDestroy(&shell); + + const TPtrC name = args.Right(len+1); + Printf(_L("Settings backed up to '%S, use --restore option to restore.\r\n"), &name); + } + else if (iRestore) + { + TFileName args; + GetBackupFileNameL(args); + TInt len = args.Length(); + //TEntry e; + //LeaveIfErr(FsL().Entry(args, e), _L("No backup file found")); + // Args should be: --exec 'cp E:\Private\10202be9\persists\10272efd.cre C:\Private\10202be9\persists\10272efd.cre' + args.Append(args); + args.Append('\''); + args[len] = 'C'; + args.Insert(len, _L(" ")); + args.Insert(0, _L("--exec 'cp -ro ")); + + RChildProcess shell; + shell.CreateL(_L("fshell.exe"), args, IoSession(), Stdin(), Stdout(), Stderr()); + CleanupClosePushL(shell); + TRequestStatus stat; + shell.Run(stat); + User::WaitForRequest(stat); + LeaveIfErr(stat.Int(), _L("Failed to copy cenrep file")); + CleanupStack::PopAndDestroy(&shell); + + Printf(_L("Settings restored. You must reboot or restart cloggerserver to get the new settings\r\n")); + } + } + +void CCmdCloggerConfig::ArgumentsL(RCommandArgumentList& aArguments) + { + aArguments.AppendStringL(iTagName, _L("tag_name")); + aArguments.AppendUintL(iEnabledMask, _L("enabled_mask")); + } + +void CCmdCloggerConfig::OptionsL(RCommandOptionList& aOptions) + { + aOptions.AppendUintL(iGlobalOptions, _L("set-global")); + aOptions.AppendBoolL(iPersist, _L("persist")); + aOptions.AppendBoolL(iReset, _L("reset")); + aOptions.AppendUintL(iRotateOptions, _L("set-rotate")); + aOptions.AppendBoolL(iRotate, _L("rotate")); + aOptions.AppendBoolL(iFollow, _L("follow")); + aOptions.AppendIntL(iNumBuffers, _L("num-buffers")); + aOptions.AppendUintL((TUint&)iBufferSize, _L("buffer-size")); + aOptions.AppendBoolL(iWipe, _L("wipe")); + aOptions.AppendBoolL(iRdebug, _L("rdebug")); + aOptions.AppendBoolL(iBackup, _L("backup")); + aOptions.AppendBoolL(iRestore, _L("restore")); + aOptions.AppendBoolL(iDisableAll, _L("disable-all")); + aOptions.AppendBoolL(iEnableAll, _L("enable-all")); + } + + +EXE_BOILER_PLATE(CCmdCloggerConfig) + +void CCmdCloggerConfig::PrintLogL() + { + // Because of how RCloggerLogConsumer API works we can only 'see' things in the clogger ChunkForBufs. This however + // won't be where the descriptor being logged will be unless buffered logging is enabled. To fix properly, + // the rdebug chunk would need to be mapped into the client, and also the Server's iSessionTempBuf and + // CDebugRouterClient's iTempBuf would need to be moved to an accessible chunk + TUint opts = iClogger.GetGlobalOptions(); + opts |= RClogger::EBufferLog; + iClogger.SetGlobalOptions(opts); + + LeaveIfErr(iLogGetter.Connect(), _L("Couldn't connect to RCloggerLogConsumer")); + iTempBuffer.CreateL(2048); + + TRequestStatus stat; + TPtrC8 logLine; + while (ETrue) + { + iLogGetter.GetNextLog(stat, logLine); + User::WaitForRequest(stat); + LeaveIfErr(stat.Int(), _L("GetNextLog returned error")); + + // CCommandBase::Write doesn't take 8-bit descriptor so write in iTempBuffer-sized chunks + TPtrC8 lineFrag(logLine); + const TInt buflen = iTempBuffer.MaxLength(); + while (lineFrag.Length()) + { + TPtrC8 frag = lineFrag.Left(buflen); + iTempBuffer.Copy(frag); + //HexDumpL(frag, iTempBuffer); + TInt err = Stdout().Write(iTempBuffer); + LeaveIfErr(err, _L("Write of %d bytes (%d total) failed"), iTempBuffer.Length(), logLine.Length()); + lineFrag.Set(lineFrag.Mid(frag.Length())); + } + } + } + +void CCmdCloggerConfig::GetBackupFileNameL(TFileName& aName) + { + TInt err = KErrNone; + TInt theDrive = KErrNotFound; + // Figure out the first external media device + for (TInt drive = EDriveA; drive <= EDriveZ; drive++) + { + TVolumeInfo info; + err = FsL().Volume(info, drive); + if (err == KErrNone) + { + //LogNote(ELogDisks, _L8("Found drive %c iDrivaAtt=0x%x iType=0x%x"), 'A' + drive, info.iDrive.iDriveAtt, info.iDrive.iType); + } + if (err == KErrNone && ((info.iDrive.iDriveAtt & KDriveAttRemovable) || info.iDrive.iType == EMediaHardDisk)) // Added the check for hard disk so we can use _epoc_drive_d in the emulator + { + // Found one + theDrive = drive; + break; + } + } + LeaveIfErr(theDrive, _L("Couldn't find a removable drive to backup on to")); + + aName = _L("?:\\private\\10202be9\\persists\\10272efd.cre"); + TChar c; + Fs().DriveToChar(theDrive, c); + aName[0] = c; + } + +void CCmdCloggerConfig::SetAllL(TBool aEnabled) + { + CDesC16Array* tags = NULL; + RBuf8 states; + CleanupClosePushL(states); + iClogger.GetTagStatesL(tags, states); + CleanupStack::PushL(tags); + if (aEnabled) + { + states.Fill(TChar(0xff)); + } + else + { + states.FillZ(); + } + iClogger.SetTagStatesL(tags, states); + CleanupStack::PopAndDestroy(2, &states); + }