--- /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 <fshell/ioutils.h>
+#include <fshell/clogger.h>
+#include <BADESCA.H>
+#include <e32msgqueue.h>
+
+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);
+ }