commands/cloggerconfig/cloggerconfig.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // cloggerconfig.cpp
       
     2 // 
       
     3 // Copyright (c) 2007 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <fshell/ioutils.h>
       
    14 #include <fshell/clogger.h>
       
    15 #include <BADESCA.H>
       
    16 #include <e32msgqueue.h>
       
    17 
       
    18 using namespace IoUtils;
       
    19 
       
    20 class CCmdCloggerConfig : public CCommandBase
       
    21 	{
       
    22 public:
       
    23 	static CCommandBase* NewLC();
       
    24 	~CCmdCloggerConfig();
       
    25 private:
       
    26 	CCmdCloggerConfig();
       
    27 	void PrintLogL();
       
    28 	void GetBackupFileNameL(TFileName& aName);
       
    29 	void SetAllL(TBool aEnabled);
       
    30 private: // From CCommandBase.
       
    31 	virtual const TDesC& Name() const;
       
    32 	virtual void DoRunL();
       
    33 	virtual void ArgumentsL(RCommandArgumentList& aArguments);
       
    34 	virtual void OptionsL(RCommandOptionList& aOptions);
       
    35 private:
       
    36 	RClogger iClogger;
       
    37 	RCloggerLogConsumer iLogGetter;
       
    38 	TUint iGlobalOptions;
       
    39 	TBool iPersist;
       
    40 	TBool iReset;
       
    41 	HBufC* iTagName;
       
    42 	TUint iEnabledMask;
       
    43 	TUint iRotateOptions;
       
    44 	TBool iRotate;
       
    45 	TBool iFollow;
       
    46 	TBool iWipe;
       
    47 	TInt iNumBuffers;
       
    48 	TInt iBufferSize;
       
    49 	RBuf iTempBuffer;
       
    50 	TBool iRdebug;
       
    51 	TBool iBackup;
       
    52 	TBool iRestore;
       
    53 	TBool iDisableAll;
       
    54 	TBool iEnableAll;
       
    55 	};
       
    56 
       
    57 
       
    58 CCommandBase* CCmdCloggerConfig::NewLC()
       
    59 	{
       
    60 	CCmdCloggerConfig* self = new(ELeave) CCmdCloggerConfig();
       
    61 	CleanupStack::PushL(self);
       
    62 	self->BaseConstructL();
       
    63 	return self;
       
    64 	}
       
    65 
       
    66 CCmdCloggerConfig::~CCmdCloggerConfig()
       
    67 	{
       
    68 	iClogger.Close();
       
    69 	iLogGetter.Close();
       
    70 	delete iTagName;
       
    71 	iTempBuffer.Close();
       
    72 	}
       
    73 
       
    74 CCmdCloggerConfig::CCmdCloggerConfig()
       
    75 	{
       
    76 	}
       
    77 
       
    78 const TDesC& CCmdCloggerConfig::Name() const
       
    79 	{
       
    80 	_LIT(KName, "cloggerconfig");	
       
    81 	return KName;
       
    82 	}
       
    83 
       
    84 #define WRITEIF(opt, flag) if (opt & (RClogger :: flag)) { Write(_L(#flag)); Write(_L(" ")); }
       
    85 
       
    86 void CCmdCloggerConfig::DoRunL()
       
    87 	{
       
    88 	if (iEnableAll && iDisableAll)
       
    89 		{
       
    90 		LeaveIfErr(KErrArgument, _L("Can't enable and disable all tags"));
       
    91 		}
       
    92 
       
    93 	User::LeaveIfError(iClogger.Connect());
       
    94 
       
    95 	TBool listSettings = ETrue;
       
    96 	if (iReset)
       
    97 		{
       
    98 		iClogger.ResetSettings();
       
    99 		listSettings = EFalse;
       
   100 		}
       
   101 	
       
   102 	if (iOptions.IsPresent(&iGlobalOptions))
       
   103 		{
       
   104 		iClogger.SetGlobalOptions(iGlobalOptions);
       
   105 		listSettings = EFalse;
       
   106 		}
       
   107 	if (iOptions.IsPresent(&iRotateOptions))
       
   108 		{
       
   109 		TInt n;
       
   110 		iClogger.GetRotateBehaviour(&n);
       
   111 		iClogger.SetRotateBehaviour(n, iRotateOptions);
       
   112 		listSettings = EFalse;
       
   113 		}
       
   114 	if (iNumBuffers || iBufferSize)
       
   115 		{
       
   116 		if (iNumBuffers == 0)
       
   117 			{
       
   118 			// Need to read it in as we have to set both at once.  Bad API...
       
   119 			iClogger.GetRamBufferSize(&iNumBuffers);
       
   120 			}
       
   121 		if (iBufferSize == 0)
       
   122 			{
       
   123 			// Same reason as above
       
   124 			iBufferSize = iClogger.GetRamBufferSize(NULL);
       
   125 			}
       
   126 		iClogger.SetRamBufferSize(iBufferSize, iNumBuffers);
       
   127 		listSettings = EFalse;
       
   128 		}
       
   129 	if (iPersist || iBackup || iRestore)
       
   130 		{
       
   131 		// We don't do anything here, we take action at the end of this function
       
   132 		listSettings = EFalse;
       
   133 		}
       
   134 	if (iRotate)
       
   135 		{
       
   136 		TFileName name;
       
   137 		TInt err = iClogger.Rotate(name);
       
   138 		Printf(_L("Log rotated to %S\r\n"), &name);
       
   139 		if (err) PrintError(err, _L("Rotate returned error"));
       
   140 		listSettings = EFalse;
       
   141 		}
       
   142 	else if (iWipe)
       
   143 		{
       
   144 		TInt oldLogs;
       
   145 		TUint rotopt = iClogger.GetRotateBehaviour(&oldLogs);
       
   146 		iClogger.SetRotateBehaviour(KMaxTInt, RClogger::EDoNothingSpecial); // Change rotate behaviour temporarily
       
   147 		
       
   148 		TFileName name;
       
   149 		TInt err = iClogger.Rotate(name);
       
   150 		//Printf(_L("Log rotated to %S\r\n"), &name);
       
   151 		if (err) PrintError(err, _L("Rotate returned error"));
       
   152 		else
       
   153 			{
       
   154 			err = FsL().Delete(name);
       
   155 
       
   156 			iClogger.SetRotateBehaviour(oldLogs, rotopt); // Restore old behaviour
       
   157 			LeaveIfErr(err, _L("Couldn't remove wiped log %S"), &name);
       
   158 			}
       
   159 
       
   160 		listSettings = EFalse;
       
   161 		}
       
   162 
       
   163 	if (iDisableAll)
       
   164 		{
       
   165 		SetAllL(EFalse);
       
   166 		listSettings = EFalse;
       
   167 		}
       
   168 
       
   169 	if (iEnableAll)
       
   170 		{
       
   171 		SetAllL(ETrue);
       
   172 		listSettings = EFalse;
       
   173 		}
       
   174 
       
   175 	if (iRdebug)
       
   176 		{
       
   177 		TUint opts = iClogger.GetGlobalOptions();
       
   178 		opts |= RClogger::ERedirectRDebugPrintToClogger;
       
   179 		iClogger.SetGlobalOptions(opts);
       
   180 		
       
   181 		PrintLogL();
       
   182 		}
       
   183 
       
   184 	if (iFollow)
       
   185 		{
       
   186 		PrintLogL(); // Does not return
       
   187 		}
       
   188 
       
   189 	if (iArguments.IsPresent(1))
       
   190 		{
       
   191 		// Set
       
   192 		TInt err = iClogger.SetEnabled(*iTagName, iEnabledMask);
       
   193 		if (err == KErrNotFound)
       
   194 			{
       
   195 			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!)"));
       
   196 			User::Leave(KErrNotFound);
       
   197 			}
       
   198 		LeaveIfErr(err, _L("Couldn't enable tag."));
       
   199 		listSettings = EFalse;
       
   200 		}
       
   201 	else if (iArguments.IsPresent(0))
       
   202 		{
       
   203 		// Get
       
   204 		TUint32 e = iClogger.IsEnabled(*iTagName);
       
   205 		Printf(_L("Tag [%S] enabled: 0x%x\r\n"), iTagName, e);
       
   206 		listSettings = EFalse;
       
   207 		}
       
   208 	
       
   209 	if (listSettings)
       
   210 		{
       
   211 		// List global options
       
   212 		TUint globalOptions = iClogger.GetGlobalOptions();
       
   213 		Printf(_L("Global options: 0x%x ( "), globalOptions);
       
   214 		if (!globalOptions)
       
   215 			{
       
   216 			Write(_L("None "));
       
   217 			}
       
   218 		else
       
   219 			{
       
   220 			WRITEIF(globalOptions, EBufferLog);
       
   221 			WRITEIF(globalOptions, EMirrorToRDebugPrint);
       
   222 			WRITEIF(globalOptions, EMirrorToBluetooth);
       
   223 			WRITEIF(globalOptions, EMirrorToMessageQueue);
       
   224 			WRITEIF(globalOptions, ERedirectRDebugPrintToClogger);
       
   225 			WRITEIF(globalOptions, EDisableFileWriter);
       
   226 			}
       
   227 		Write(_L(")\r\n"));
       
   228 
       
   229 		// List rotate options
       
   230 		TInt numLogs = 0;
       
   231 		TUint rotateBehaviour = iClogger.GetRotateBehaviour(&numLogs);
       
   232 		Printf(_L("Number of rotated logs to keep: %i\r\n"), numLogs);
       
   233 		Printf(_L("Rotate behaviour: 0x%x ( "), rotateBehaviour);
       
   234 		if (!rotateBehaviour)
       
   235 			{
       
   236 			Write(_L("EDoNothingSpecial "));
       
   237 			}
       
   238 		else
       
   239 			{
       
   240 			WRITEIF(rotateBehaviour, ECopyRotatedToExternalMedia);
       
   241 			WRITEIF(rotateBehaviour, EAutoRotateAtStartup);
       
   242 			WRITEIF(rotateBehaviour, ECompressRotatedLogs);
       
   243 			}
       
   244 		Write(_L(")\r\n"));
       
   245 
       
   246 		// List buffer size
       
   247 		TInt numBuffers = 0;
       
   248 		TInt bufSize = iClogger.GetRamBufferSize(&numBuffers);
       
   249 		Printf(_L("Number of RAM buffers: %i\r\n"), numBuffers);
       
   250 		Printf(_L("Size of RAM buffers: %i\r\n"), bufSize);
       
   251 
       
   252 		// List tags
       
   253 		CDesC16Array* tags = NULL;
       
   254 		RBuf8 enabled;
       
   255 		iClogger.GetTagStatesL(tags, enabled);
       
   256 		TInt count = enabled.Size() / 4;
       
   257 		if (count) Printf(_L("\r\n"));
       
   258 		for (TInt i = 0; i < count; i++)
       
   259 			{
       
   260 			TPtrC tag = tags->operator[](i);
       
   261 			TUint32 e = ((TUint32*)enabled.Ptr())[i];
       
   262 			Printf(_L("Tag [%S] enabled: 0x%x\r\n"), &tag, e);
       
   263 			}
       
   264 		delete tags;
       
   265 		enabled.Close();
       
   266 		}
       
   267 
       
   268 	if (iPersist)
       
   269 		{
       
   270 		iClogger.PersistSettings();
       
   271 		}
       
   272 
       
   273 	if (iBackup)
       
   274 		{
       
   275 		// Args should be: --exec 'cp -ro C:\Private\10202be9\persists\10272efd.cre E:\Private\10202be9\persists\10272efd.cre'
       
   276 		TFileName args;
       
   277 		GetBackupFileNameL(args);
       
   278 
       
   279 		TInt len = args.Length();
       
   280 		args.Append(args);
       
   281 		args.Append('\'');
       
   282 		args[0] = 'C';
       
   283 		args.Insert(len, _L(" "));
       
   284 		args.Insert(0, _L("--exec 'cp -ro "));
       
   285 		
       
   286 		RChildProcess shell;
       
   287 		shell.CreateL(_L("fshell.exe"), args, IoSession(), Stdin(), Stdout(), Stderr());
       
   288 		CleanupClosePushL(shell);
       
   289 		TRequestStatus stat;
       
   290 		shell.Run(stat);
       
   291 		User::WaitForRequest(stat);
       
   292 		LeaveIfErr(stat.Int(), _L("Failed to copy cenrep file"));
       
   293 		CleanupStack::PopAndDestroy(&shell);
       
   294 
       
   295 		const TPtrC name = args.Right(len+1);
       
   296 		Printf(_L("Settings backed up to '%S, use --restore option to restore.\r\n"), &name);
       
   297 		}
       
   298 	else if (iRestore)
       
   299 		{
       
   300 		TFileName args;
       
   301 		GetBackupFileNameL(args);
       
   302 		TInt len = args.Length();
       
   303 		//TEntry e;
       
   304 		//LeaveIfErr(FsL().Entry(args, e), _L("No backup file found"));
       
   305 		// Args should be: --exec 'cp E:\Private\10202be9\persists\10272efd.cre C:\Private\10202be9\persists\10272efd.cre'
       
   306 		args.Append(args);
       
   307 		args.Append('\'');
       
   308 		args[len] = 'C';
       
   309 		args.Insert(len, _L(" "));
       
   310 		args.Insert(0, _L("--exec 'cp -ro "));
       
   311 		
       
   312 		RChildProcess shell;
       
   313 		shell.CreateL(_L("fshell.exe"), args, IoSession(), Stdin(), Stdout(), Stderr());
       
   314 		CleanupClosePushL(shell);
       
   315 		TRequestStatus stat;
       
   316 		shell.Run(stat);
       
   317 		User::WaitForRequest(stat);
       
   318 		LeaveIfErr(stat.Int(), _L("Failed to copy cenrep file"));
       
   319 		CleanupStack::PopAndDestroy(&shell);
       
   320 
       
   321 		Printf(_L("Settings restored. You must reboot or restart cloggerserver to get the new settings\r\n"));
       
   322 		}
       
   323 	}
       
   324 
       
   325 void CCmdCloggerConfig::ArgumentsL(RCommandArgumentList& aArguments)
       
   326 	{
       
   327 	aArguments.AppendStringL(iTagName, _L("tag_name"));
       
   328 	aArguments.AppendUintL(iEnabledMask, _L("enabled_mask"));
       
   329 	}
       
   330 
       
   331 void CCmdCloggerConfig::OptionsL(RCommandOptionList& aOptions)
       
   332 	{
       
   333 	aOptions.AppendUintL(iGlobalOptions, _L("set-global"));
       
   334 	aOptions.AppendBoolL(iPersist, _L("persist"));
       
   335 	aOptions.AppendBoolL(iReset, _L("reset"));
       
   336 	aOptions.AppendUintL(iRotateOptions, _L("set-rotate"));
       
   337 	aOptions.AppendBoolL(iRotate, _L("rotate"));
       
   338 	aOptions.AppendBoolL(iFollow, _L("follow"));
       
   339 	aOptions.AppendIntL(iNumBuffers, _L("num-buffers"));
       
   340 	aOptions.AppendUintL((TUint&)iBufferSize, _L("buffer-size"));
       
   341 	aOptions.AppendBoolL(iWipe, _L("wipe"));
       
   342 	aOptions.AppendBoolL(iRdebug, _L("rdebug"));
       
   343 	aOptions.AppendBoolL(iBackup, _L("backup"));
       
   344 	aOptions.AppendBoolL(iRestore, _L("restore"));
       
   345 	aOptions.AppendBoolL(iDisableAll, _L("disable-all"));
       
   346 	aOptions.AppendBoolL(iEnableAll, _L("enable-all"));
       
   347 	}
       
   348 
       
   349 
       
   350 EXE_BOILER_PLATE(CCmdCloggerConfig)
       
   351 
       
   352 void CCmdCloggerConfig::PrintLogL()
       
   353 	{
       
   354 	// Because of how RCloggerLogConsumer API works we can only 'see' things in the clogger ChunkForBufs. This however
       
   355 	// won't be where the descriptor being logged will be unless buffered logging is enabled. To fix properly,
       
   356 	// the rdebug chunk would need to be mapped into the client, and also the Server's iSessionTempBuf and 
       
   357 	// CDebugRouterClient's iTempBuf would need to be moved to an accessible chunk
       
   358 	TUint opts = iClogger.GetGlobalOptions();
       
   359 	opts |= RClogger::EBufferLog;
       
   360 	iClogger.SetGlobalOptions(opts);
       
   361 
       
   362 	LeaveIfErr(iLogGetter.Connect(), _L("Couldn't connect to RCloggerLogConsumer"));
       
   363 	iTempBuffer.CreateL(2048);
       
   364 
       
   365 	TRequestStatus stat;
       
   366 	TPtrC8 logLine;
       
   367 	while (ETrue)
       
   368 		{
       
   369 		iLogGetter.GetNextLog(stat, logLine);
       
   370 		User::WaitForRequest(stat);
       
   371 		LeaveIfErr(stat.Int(), _L("GetNextLog returned error"));
       
   372 		
       
   373 		// CCommandBase::Write doesn't take 8-bit descriptor so write in iTempBuffer-sized chunks
       
   374 		TPtrC8 lineFrag(logLine);
       
   375 		const TInt buflen = iTempBuffer.MaxLength();
       
   376 		while (lineFrag.Length())
       
   377 			{
       
   378 			TPtrC8 frag = lineFrag.Left(buflen);
       
   379 			iTempBuffer.Copy(frag);
       
   380 			//HexDumpL(frag, iTempBuffer);
       
   381 			TInt err = Stdout().Write(iTempBuffer);
       
   382 			LeaveIfErr(err, _L("Write of %d bytes (%d total) failed"), iTempBuffer.Length(), logLine.Length());
       
   383 			lineFrag.Set(lineFrag.Mid(frag.Length()));
       
   384 			}
       
   385 		}
       
   386 	}
       
   387 
       
   388 void CCmdCloggerConfig::GetBackupFileNameL(TFileName& aName)
       
   389 	{
       
   390 	TInt err = KErrNone;
       
   391 	TInt theDrive = KErrNotFound;
       
   392 	// Figure out the first external media device
       
   393 	for (TInt drive = EDriveA; drive <= EDriveZ; drive++)
       
   394 		{
       
   395 		TVolumeInfo info;
       
   396 		err = FsL().Volume(info, drive);
       
   397 		if (err == KErrNone)
       
   398 			{
       
   399 			//LogNote(ELogDisks, _L8("Found drive %c iDrivaAtt=0x%x iType=0x%x"), 'A' + drive, info.iDrive.iDriveAtt, info.iDrive.iType);
       
   400 			}
       
   401 		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
       
   402 			{
       
   403 			// Found one
       
   404 			theDrive = drive;
       
   405 			break;
       
   406 			}
       
   407 		}
       
   408 	LeaveIfErr(theDrive, _L("Couldn't find a removable drive to backup on to"));
       
   409 
       
   410 	aName = _L("?:\\private\\10202be9\\persists\\10272efd.cre");
       
   411 	TChar c;
       
   412 	Fs().DriveToChar(theDrive, c);
       
   413 	aName[0] = c;
       
   414 	}
       
   415 
       
   416 void CCmdCloggerConfig::SetAllL(TBool aEnabled)
       
   417 	{
       
   418 	CDesC16Array* tags = NULL;
       
   419 	RBuf8 states;
       
   420 	CleanupClosePushL(states);
       
   421 	iClogger.GetTagStatesL(tags, states);
       
   422 	CleanupStack::PushL(tags);
       
   423 	if (aEnabled)
       
   424 		{
       
   425 		states.Fill(TChar(0xff));
       
   426 		}
       
   427 	else
       
   428 		{
       
   429 		states.FillZ();
       
   430 		}
       
   431 	iClogger.SetTagStatesL(tags, states);
       
   432 	CleanupStack::PopAndDestroy(2, &states);
       
   433 	}