1// ======================================================================
2//	File:		KCOperation.cpp
3//
4//	pure virtual base class for performing operations in KeychainLib
5//  (based on Dave Akhond's Operation for CDSA
6//
7//	Copyright:	Copyright (c) 2000,2003 Apple Computer, Inc. All Rights Reserved.
8//
9//	Change History (most recent first):
10//
11//		 <1>	3/28/00	em		Created.
12// ======================================================================
13
14#include "KCOperation.h"
15
16#include <Security/cssmerr.h>
17
18vector<KCRef>			KCOperation::sKCRefList;
19vector<KCItemRef>		KCItemOperation::sKCItemRefList;
20vector<KCSearchRef>		KCSearchOperation::sKCSearchRefList;
21vector<AliasHandle>		KCOperation::sAliasList;
22
23//vector<SecKeychainRef>		SecOperation::sSecRefList;
24//vector<AliasHandle>		SecOperation::sAliasList;
25
26// ���������������������������������������������������������������������������
27// 	� SetClient
28// ���������������������������������������������������������������������������
29void
30Operation::SetClient(void *inClient)
31{
32	if(inClient == NULL) return;
33	CTestApp	*aTestApp = static_cast<CTestApp*>(inClient);
34	if(aTestApp == NULL) return;
35	mClient = aTestApp;
36}
37
38
39// ���������������������������������������������������������������������������
40// 	� ReadArguments
41// ���������������������������������������������������������������������������
42void
43Operation::ReadArguments(
44    FILE	*inFile)
45{
46
47    tParamList::iterator		aIterator = mParamList.begin();
48    CParam *					aParam = *aIterator;
49
50    while(aIterator != mParamList.end()){
51
52        aParam->Read(inFile);
53        aParam = *(++aIterator);
54    }
55}
56
57// ���������������������������������������������������������������������������
58// 	� WriteArguments
59// ���������������������������������������������������������������������������
60void
61Operation::WriteArguments(
62    FILE	*inFile)
63{
64    tParamList::iterator		aIterator = mParamList.begin();
65    CParam *					aParam = *aIterator;
66    while(aIterator != mParamList.end()){
67        aParam->Write(inFile);
68        aParam = *(++aIterator);
69    }
70}
71
72// ���������������������������������������������������������������������������
73// 	� WriteResults
74// ���������������������������������������������������������������������������
75void
76Operation::WriteResults(
77    FILE	*inFile)
78{
79	if (CSSM_BASE_ERROR <= mStatus && mStatus < CSSM_AC_BASE_ERROR + CSSM_ERRORCODE_MODULE_EXTENT)
80		//fprintf(inFile, "     OSStatus CSSMERR_%s (0x%08lx)\n", cssmErrorString(mStatus).c_str(), mStatus);
81                printf("Error");
82	else
83		fprintf(inFile, "     OSStatus %ld\n", mStatus);
84
85
86    tParamList::iterator		aIterator = mResultList.begin();
87    CParam *					aParam = *aIterator;
88    while(aIterator != mResultList.end()){
89        aParam->Write(inFile);
90        aParam = *(++aIterator);
91    }
92}
93
94// ���������������������������������������������������������������������������
95// 	� ReadScript
96// ���������������������������������������������������������������������������
97int
98Operation::ReadScript(
99	FILE 			*inFile,
100    eKCOperationID	&outID)
101{
102    UInt32	aID;
103    char	aBuffer[1024];
104    char	aName[256];
105    int		aResult;
106
107    while(UNIX_fgets(aBuffer, sizeof(aBuffer)-1, inFile)){
108									// Read off comment lines
109		if(aBuffer[0] == '/' && aBuffer[1] == '/') continue;
110									// instructional comments
111		if(aBuffer[0] == '#' && aBuffer[0] == '#'){
112			for(UInt16 i=0; i<strlen(aBuffer)+4; i++) fprintf(stdout, "-");
113			fprintf(stdout, "\n%s", aBuffer);
114			for(UInt16 i=0; i<strlen(aBuffer)+4; i++) fprintf(stdout, "-");
115			fprintf(stdout, "\n");
116			continue;
117		}
118
119    	aResult = sscanf(aBuffer, "%ld %s\n", &aID, aName);
120    	outID = (eKCOperationID)aID;
121    	return aResult;
122    }
123
124    return(EOF);
125}
126
127// ���������������������������������������������������������������������������
128// 	� ReadScript
129// ���������������������������������������������������������������������������
130void
131Operation::ReadScript(
132	FILE 	*inFile)
133{
134    UInt32	aNumArgs = 0;
135    UInt32	aSize = 0;
136    fscanf(inFile, "   Input Arguments : %ld\n", &aNumArgs);
137
138    ReadArguments(inFile);
139
140    fscanf(inFile, "   Results : %ld\n", &aSize);
141}
142
143// ���������������������������������������������������������������������������
144// 	� WriteScript
145// ���������������������������������������������������������������������������
146void
147Operation::WriteScript(
148	FILE 	*inFile)
149{
150    fprintf(inFile, "%d %s\n", GetID(), COpRegister::GetOperationName(GetID()));
151    fprintf(inFile, "   Input Arguments : %ld\n", mParamList.size());
152    WriteArguments(inFile);
153										// Count OSStatus as one of the result values
154    fprintf(inFile, "   Results : %ld\n", mResultList.size()+1);
155    WriteResults(inFile);
156}
157
158
159// ���������������������������������������������������������������������������
160// 	� GenerateScript
161// ���������������������������������������������������������������������������
162void
163Operation::GenerateScript(
164	FILE 	*inFile)
165{
166                                    // By default, just generate one script
167    WriteScript(inFile);
168}
169
170// ���������������������������������������������������������������������������
171// 	� RunScript
172// ���������������������������������������������������������������������������
173bool
174Operation::RunScript(
175	FILE 	*inFile)
176{
177    ReadScript(inFile);
178    Operate();
179    return CompareResults(inFile);
180}
181
182
183// ���������������������������������������������������������������������������
184// 	� CompareResults
185// ���������������������������������������������������������������������������
186bool
187Operation::CompareResults(
188	FILE 	*inFile)
189{
190    OSStatus	aStatus;
191    fscanf(inFile, "     OSStatus %ld\n", &aStatus);
192
193	bool		aResult = true;
194										// if gRelaxErrorChecking is on, don't bother
195										// checking the actual error code, just check
196										// for noErr-ness.
197	if(aStatus != mStatus){
198		if(!mClient->IsRelaxErrorChecking()) aResult = false;
199		if(mClient->IsRelaxErrorChecking() && ((aStatus == noErr) || (mStatus == noErr))) aResult = false;
200	}
201
202    tParamList::iterator		aIterator = mResultList.begin();
203    CParam *					aParam = *aIterator;
204    while(aIterator != mResultList.end()){
205        if(aParam->Compare(inFile) == false)
206            aResult = false;
207        aParam = *(++aIterator);
208    }
209    return aResult;
210}
211
212