|
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 } |