1/*
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
3 * The contents of this file constitute Original Code as defined in and are
4 * subject to the Apple Public Source License Version 1.2 (the 'License').
5 * You may not use this file except in compliance with the License. Please
6 * obtain a copy of the License at http://www.apple.com/publicsource and
7 * read it before using this file.
8 *
9 * This Original Code and all software distributed under the License are
10 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
11 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
12 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
13 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
14 * see the License for the specific language governing rights and
15 * limitations under the License.
16 */
17
18/******************************************************************
19
20	MUSCLE SmartCard Development ( http://www.linuxnet.com )
21	Title  : bundleTool.c
22	Package: MuscleCard Framework
23	Author : David Corcoran
24	Date   : 03/11/01
25	License: Copyright (C) 2002 David Corcoran
26			<corcoran@linuxnet.com>
27	Purpose: This automatically updates the Info.plist
28
29	You may not remove this header from this file
30	without prior permission from the author.
31
32$Id: bundleTool.c 123 2010-03-27 10:50:42Z ludovic.rousseau@gmail.com $
33
34********************************************************************/
35
36#include "wintypes.h"
37#include "winscard.h"
38#include "tokenfactory.h"
39
40#include <string.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <unistd.h>
44#include <dirent.h>
45#include <stdio.h>
46#include <fcntl.h>
47#include <stdlib.h>
48
49/*
50 * End of personalization
51 */
52
53#define CHECK_ERR(cond, msg) { if (cond) { \
54  printf("Error: %s\n", msg); return -1; } }
55
56int main(int argc, char **argv)
57{
58
59	LONG rv;
60	SCARDCONTEXT hContext;
61	SCARD_READERSTATE_A rgReaderStates;
62	DWORD readerListSize;
63	struct stat statBuffer;
64	char spAtrValue[100];
65	char chosenInfoPlist[1024];
66	char *readerList;
67	char *restFile;
68	char atrInsertion[256];
69	FILE *fp;
70	DIR *bundleDir;
71	struct dirent *currBundle;
72	int i, p;
73	int userChoice;
74	int totalBundles;
75	int filePosition;
76	int restFileSize;
77	int restOffset;
78	int getsSize;
79
80	if (argc > 1)
81	{
82		printf("Invalid arguments\n");
83		printf("./bundleTool\n");
84		return -1;
85	}
86
87	currBundle = 0;
88
89	bundleDir = opendir(MSC_SVC_DROPDIR);
90	CHECK_ERR(bundleDir == 0, "Could not open services directory.");
91
92	printf("Select the approprate token driver:\n");
93	printf("-----------------------------------\n");
94
95	i = 1;
96	totalBundles = 0;
97
98	while ((currBundle = readdir(bundleDir)) != 0)
99	{
100		if (strstr(currBundle->d_name, ".bundle") != 0)
101		{
102			printf("  %d.     %s\n", i++, currBundle->d_name);
103			totalBundles += 1;
104		}
105	}
106	printf("-----------------------------------\n");
107
108	if (totalBundles == 0)
109	{
110		printf("No services are present - exiting.\n");
111		return 1;
112	}
113
114	do
115	{
116		printf("Enter the number: ");
117		scanf("%d", &userChoice);
118	}
119	while (userChoice < 1 && userChoice > totalBundles);
120
121	closedir(bundleDir);
122
123	bundleDir = opendir(MSC_SVC_DROPDIR);
124	CHECK_ERR(bundleDir == 0, "Could not open services directory.");
125	CHECK_ERR(bundleDir == 0, MSC_SVC_DROPDIR);
126
127	do
128	{
129		if ((currBundle = readdir(bundleDir)) != 0)
130		{
131			if (strstr(currBundle->d_name, ".bundle") != 0)
132			{
133				userChoice -= 1;
134			}
135		}
136	}
137	while (userChoice != 0);
138
139	snprintf(chosenInfoPlist, sizeof(chosenInfoPlist),
140		"%s%s/Contents/Info.plist", MSC_SVC_DROPDIR, currBundle->d_name);
141	closedir(bundleDir);
142	printf("\n");
143
144	rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, &hContext);
145	CHECK_ERR(rv != SCARD_S_SUCCESS, "PC/SC SCardEstablishContext Failed");
146
147	readerListSize = 0;
148	rv = SCardListReaders(hContext, 0, 0, &readerListSize);
149	CHECK_ERR(rv != SCARD_S_SUCCESS, "PC/SC SCardListReaders Failed");
150
151	readerList = (char *) malloc(sizeof(char) * readerListSize);
152	CHECK_ERR(readerList == 0, "Malloc Failed");
153
154	rv = SCardListReaders(hContext, 0, readerList, &readerListSize);
155	CHECK_ERR(rv != SCARD_S_SUCCESS, "PC/SC SCardListReaders Alloc Failed");
156
157	printf("Insert your token in: %s\n", readerList);
158
159	rgReaderStates.szReader = readerList;
160	rgReaderStates.dwCurrentState = SCARD_STATE_EMPTY;
161
162	rv = SCardGetStatusChange(hContext, INFINITE, &rgReaderStates, 1);
163	CHECK_ERR(rv != SCARD_S_SUCCESS, "PC/SC SCardGetStatusChange Failed");
164
165	p = 0;
166	for (i = 0; i < rgReaderStates.cbAtr; i++)
167	{
168		sprintf(&spAtrValue[p], "%02X", rgReaderStates.rgbAtr[i]);
169		p += 2;
170	}
171	printf("\n");
172
173	snprintf(atrInsertion, sizeof(atrInsertion),
174		"        <string>%s</string>\n", spAtrValue);
175
176	fp = fopen(chosenInfoPlist, "r+");
177	if (fp == 0)
178	{
179		printf("Could not open %s\n", chosenInfoPlist);
180	}
181	CHECK_ERR(fp == 0, "Opening of Info.plist failed.");
182
183	rv = stat(chosenInfoPlist, &statBuffer);
184	CHECK_ERR(rv != 0, "File Stat failed\n");
185
186	restFileSize = statBuffer.st_size + strlen(atrInsertion);
187	restFile = (char *) malloc(sizeof(char) * restFileSize);
188	CHECK_ERR(restFile == 0, "Malloc failed");
189
190	filePosition = 0;
191	restOffset = 0;
192	getsSize = 0;
193
194	do
195	{
196		if (fgets(&restFile[restOffset], restFileSize, fp) == 0)
197		{
198			break;
199		}
200
201		if (strstr(&restFile[restOffset], "<key>spAtrValue</key>"))
202		{
203			filePosition = ftell(fp);
204		}
205
206		getsSize = strlen(&restFile[restOffset]);
207		restOffset += getsSize;
208	}
209	while (1);
210
211	rewind(fp);
212	fwrite(restFile, 1, filePosition, fp);
213	fwrite(atrInsertion, 1, strlen(atrInsertion), fp);
214	fwrite(&restFile[filePosition], 1,
215		statBuffer.st_size - filePosition, fp);
216
217	fclose(fp);
218
219	printf("Token support updated successfully !\n");
220
221	return 0;
222}
223
224