1 /* $Id: macstore.c,v 1.4 2002/12/28 22:25:31 ben Exp $ */
4 * macstore.c: Macintosh-specific impementation of the interface
11 #include <Resources.h>
12 #include <TextUtils.h>
19 #define PUTTY_CREATOR FOUR_CHAR_CODE('pTTY')
20 #define SESS_TYPE FOUR_CHAR_CODE('Sess')
23 OSErr get_session_dir(Boolean makeit, short *pVRefNum, long *pDirID);
24 OSErr FSpGetDirID(FSSpec *f, long *idp, Boolean makeit);
27 * We store each session as a file in the "PuTTY" sub-directory of the
28 * preferences folder. Each (key,value) pair is stored as a resource.
31 OSErr get_session_dir(Boolean makeit, short *pVRefNum, long *pDirID) {
34 FSSpec puttydir, sessdir;
35 long prefDirID, puttyDirID, sessDirID;
37 error = FindFolder(kOnSystemDisk, kPreferencesFolderType, makeit,
38 &prefVRefNum, &prefDirID);
39 if (error != noErr) goto out;
41 error = FSMakeFSSpec(prefVRefNum, prefDirID, "\pPuTTY", &puttydir);
42 if (error != noErr && error != fnfErr) goto out;
43 error = FSpGetDirID(&puttydir, &puttyDirID, makeit);
44 if (error != noErr) goto out;
46 error = FSMakeFSSpec(prefVRefNum, puttyDirID, "\pSaved Sessions",
48 if (error != noErr && error != fnfErr) goto out;
49 error = FSpGetDirID(&sessdir, &sessDirID, makeit);
50 if (error != noErr) goto out;
52 *pVRefNum = prefVRefNum;
59 OSErr FSpGetDirID(FSSpec *f, long *idp, Boolean makeit) {
63 pb.dirInfo.ioNamePtr = f->name;
64 pb.dirInfo.ioVRefNum = f->vRefNum;
65 pb.dirInfo.ioDrDirID = f->parID;
66 pb.dirInfo.ioFDirIndex = 0;
67 error = PBGetCatInfoSync(&pb);
68 if (error == fnfErr && makeit)
69 return FSpDirCreate(f, smSystemScript, idp);
70 if (error != noErr) goto out;
71 if ((pb.dirInfo.ioFlAttrib & ioDirMask) == 0) {
75 *idp = pb.dirInfo.ioDrDirID;
81 struct write_settings {
87 void *open_settings_w(char *sessionname) {
88 short sessVRefNum, tmpVRefNum;
89 long sessDirID, tmpDirID;
92 struct write_settings *ws;
94 ws = safemalloc(sizeof *ws);
95 error = get_session_dir(kCreateFolder, &sessVRefNum, &sessDirID);
96 if (error != noErr) goto out;
98 c2pstrcpy(psessionname, sessionname);
99 error = FSMakeFSSpec(sessVRefNum, sessDirID, psessionname, &ws->dstfile);
100 if (error != noErr && error != fnfErr) goto out;
101 if (error == fnfErr) {
102 FSpCreateResFile(&ws->dstfile, PUTTY_CREATOR, SESS_TYPE,
104 if ((error = ResError()) != noErr) goto out;
107 /* Create a temporary file to save to first. */
108 error = FindFolder(sessVRefNum, kTemporaryFolderType, kCreateFolder,
109 &tmpVRefNum, &tmpDirID);
110 if (error != noErr) goto out;
111 error = FSMakeFSSpec(tmpVRefNum, tmpDirID, psessionname, &ws->tmpfile);
112 if (error != noErr && error != fnfErr) goto out;
113 if (error == noErr) {
114 error = FSpDelete(&ws->tmpfile);
115 if (error != noErr) goto out;
117 FSpCreateResFile(&ws->tmpfile, PUTTY_CREATOR, SESS_TYPE, smSystemScript);
118 if ((error = ResError()) != noErr) goto out;
120 ws->fd = FSpOpenResFile(&ws->tmpfile, fsWrPerm);
121 if (ws->fd == -1) {error = ResError(); goto out;}
127 fatalbox("Failed to open session for write (%d)", error);
130 void write_setting_s(void *handle, char *key, char *value) {
131 int fd = *(int *)handle;
136 if (ResError() != noErr)
137 fatalbox("Failed to open saved session (%d)", ResError());
139 error = PtrToHand(value, &h, strlen(value));
141 fatalbox("Failed to allocate memory");
142 /* Put the data in a resource. */
143 id = Unique1ID(FOUR_CHAR_CODE('TEXT'));
144 if (ResError() != noErr)
145 fatalbox("Failed to get ID for resource %s (%d)", key, ResError());
146 addresource(h, FOUR_CHAR_CODE('TEXT'), id, key);
147 if (ResError() != noErr)
148 fatalbox("Failed to add resource %s (%d)", key, ResError());
151 void write_setting_i(void *handle, char *key, int value) {
152 int fd = *(int *)handle;
158 if (ResError() != noErr)
159 fatalbox("Failed to open saved session (%d)", ResError());
161 /* XXX assume all systems have the same "int" format */
162 error = PtrToHand(&value, &h, sizeof(int));
164 fatalbox("Failed to allocate memory (%d)", error);
166 /* Put the data in a resource. */
167 id = Unique1ID(FOUR_CHAR_CODE('Int '));
168 if (ResError() != noErr)
169 fatalbox("Failed to get ID for resource %s (%d)", key, ResError());
170 addresource(h, FOUR_CHAR_CODE('Int '), id, key);
171 if (ResError() != noErr)
172 fatalbox("Failed to add resource %s (%d)", key, ResError());
175 void close_settings_w(void *handle) {
176 struct write_settings *ws = handle;
179 CloseResFile(ws->fd);
180 if ((error = ResError()) != noErr)
182 error = FSpExchangeFiles(&ws->tmpfile, &ws->dstfile);
183 if (error != noErr) goto out;
184 error = FSpDelete(&ws->tmpfile);
185 if (error != noErr) goto out;
189 fatalbox("Close of saved session failed (%d)", error);
193 void *open_settings_r(char *sessionname) {
202 error = get_session_dir(kDontCreateFolder, &sessVRefNum, &sessDirID);
204 c2pstrcpy(psessionname, sessionname);
205 error = FSMakeFSSpec(sessVRefNum, sessDirID, psessionname, &sessfile);
206 if (error != noErr) goto out;
207 fd = FSpOpenResFile(&sessfile, fsRdPerm);
208 if (fd == 0) {error = ResError(); goto out;}
210 handle = safemalloc(sizeof *handle);
219 char *read_setting_s(void *handle, char *key, char *buffer, int buflen) {
225 if (handle == NULL) goto out;
228 if (ResError() != noErr) goto out;
229 h = get1namedresource(FOUR_CHAR_CODE('TEXT'), key);
230 if (h == NULL) goto out;
232 len = GetHandleSize(h);
233 if (len + 1 > buflen) goto out;
234 memcpy(buffer, *h, len);
238 if (ResError() != noErr) goto out;
245 int read_setting_i(void *handle, char *key, int defvalue) {
250 if (handle == NULL) goto out;
253 if (ResError() != noErr) goto out;
254 h = get1namedresource(FOUR_CHAR_CODE('Int '), key);
255 if (h == NULL) goto out;
258 if (ResError() != noErr) goto out;
265 void close_settings_r(void *handle) {
268 if (handle == NULL) return;
271 if (ResError() != noErr)
272 fatalbox("Close of saved session failed (%d)", ResError());
276 void del_settings(char *sessionname) {
283 error = get_session_dir(kDontCreateFolder, &sessVRefNum, &sessDirID);
285 c2pstrcpy(psessionname, sessionname);
286 error = FSMakeFSSpec(sessVRefNum, sessDirID, psessionname, &sessfile);
287 if (error != noErr) goto out;
289 error = FSpDelete(&sessfile);
292 fatalbox("Delete session failed (%d)", error);
295 struct enum_settings_state {
301 void *enum_settings_start(void) {
303 struct enum_settings_state *state;
305 state = safemalloc(sizeof(*state));
306 error = get_session_dir(kDontCreateFolder, &state->vRefNum, &state->dirID);
307 if (error != noErr) {
315 char *enum_settings_next(void *handle, char *buffer, int buflen) {
316 struct enum_settings_state *e = handle;
321 if (e == NULL) return NULL;
323 pb.hFileInfo.ioNamePtr = name;
324 pb.hFileInfo.ioVRefNum = e->vRefNum;
325 pb.hFileInfo.ioDirID = e->dirID;
326 pb.hFileInfo.ioFDirIndex = e->index++;
327 error = PBGetCatInfoSync(&pb);
328 if (error != noErr) return NULL;
329 } while (!((pb.hFileInfo.ioFlAttrib & ioDirMask) == 0 &&
330 pb.hFileInfo.ioFlFndrInfo.fdCreator == PUTTY_CREATOR &&
331 pb.hFileInfo.ioFlFndrInfo.fdType == SESS_TYPE &&
334 p2cstrcpy(buffer, name);
338 void enum_settings_finish(void *handle) {
347 * c-file-style: "simon"