1 /* $Id: macstore.c,v 1.6 2002/12/30 18:21:17 ben Exp $ */
4 * macstore.c: Macintosh-specific impementation of the interface
11 #include <Resources.h>
12 #include <TextUtils.h>
20 #define PUTTY_CREATOR FOUR_CHAR_CODE('pTTY')
21 #define SESS_TYPE FOUR_CHAR_CODE('Sess')
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
;
137 if (ResError() != noErr
)
138 fatalbox("Failed to open saved session (%d)", ResError());
140 error
= PtrToHand(value
, &h
, strlen(value
));
142 fatalbox("Failed to allocate memory");
143 /* Put the data in a resource. */
144 id
= Unique1ID(FOUR_CHAR_CODE('TEXT'));
145 if (ResError() != noErr
)
146 fatalbox("Failed to get ID for resource %s (%d)", key
, ResError());
147 addresource(h
, FOUR_CHAR_CODE('TEXT'), id
, key
);
148 if (ResError() != noErr
)
149 fatalbox("Failed to add resource %s (%d)", key
, ResError());
152 void write_setting_i(void *handle
, char *key
, int value
) {
153 int fd
= *(int *)handle
;
159 if (ResError() != noErr
)
160 fatalbox("Failed to open saved session (%d)", ResError());
162 /* XXX assume all systems have the same "int" format */
163 error
= PtrToHand(&value
, &h
, sizeof(int));
165 fatalbox("Failed to allocate memory (%d)", error
);
167 /* Put the data in a resource. */
168 id
= Unique1ID(FOUR_CHAR_CODE('Int '));
169 if (ResError() != noErr
)
170 fatalbox("Failed to get ID for resource %s (%d)", key
, ResError());
171 addresource(h
, FOUR_CHAR_CODE('Int '), id
, key
);
172 if (ResError() != noErr
)
173 fatalbox("Failed to add resource %s (%d)", key
, ResError());
176 void close_settings_w(void *handle
) {
177 struct write_settings
*ws
= handle
;
180 CloseResFile(ws
->fd
);
181 if ((error
= ResError()) != noErr
)
183 error
= FSpExchangeFiles(&ws
->tmpfile
, &ws
->dstfile
);
184 if (error
!= noErr
) goto out
;
185 error
= FSpDelete(&ws
->tmpfile
);
186 if (error
!= noErr
) goto out
;
190 fatalbox("Close of saved session failed (%d)", error
);
194 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 return open_settings_r_fsp(&sessfile
);
213 void *open_settings_r_fsp(FSSpec
*sessfile
)
219 fd
= FSpOpenResFile(sessfile
, fsRdPerm
);
220 if (fd
== 0) {error
= ResError(); goto out
;}
222 handle
= safemalloc(sizeof *handle
);
230 char *read_setting_s(void *handle
, char *key
, char *buffer
, int buflen
) {
235 if (handle
== NULL
) goto out
;
238 if (ResError() != noErr
) goto out
;
239 h
= get1namedresource(FOUR_CHAR_CODE('TEXT'), key
);
240 if (h
== NULL
) goto out
;
242 len
= GetHandleSize(h
);
243 if (len
+ 1 > buflen
) goto out
;
244 memcpy(buffer
, *h
, len
);
248 if (ResError() != noErr
) goto out
;
255 int read_setting_i(void *handle
, char *key
, int defvalue
) {
260 if (handle
== NULL
) goto out
;
263 if (ResError() != noErr
) goto out
;
264 h
= get1namedresource(FOUR_CHAR_CODE('Int '), key
);
265 if (h
== NULL
) goto out
;
268 if (ResError() != noErr
) goto out
;
275 void close_settings_r(void *handle
) {
278 if (handle
== NULL
) return;
281 if (ResError() != noErr
)
282 fatalbox("Close of saved session failed (%d)", ResError());
286 void del_settings(char *sessionname
) {
293 error
= get_session_dir(kDontCreateFolder
, &sessVRefNum
, &sessDirID
);
295 c2pstrcpy(psessionname
, sessionname
);
296 error
= FSMakeFSSpec(sessVRefNum
, sessDirID
, psessionname
, &sessfile
);
297 if (error
!= noErr
) goto out
;
299 error
= FSpDelete(&sessfile
);
302 fatalbox("Delete session failed (%d)", error
);
305 struct enum_settings_state
{
311 void *enum_settings_start(void) {
313 struct enum_settings_state
*state
;
315 state
= safemalloc(sizeof(*state
));
316 error
= get_session_dir(kDontCreateFolder
, &state
->vRefNum
, &state
->dirID
);
317 if (error
!= noErr
) {
325 char *enum_settings_next(void *handle
, char *buffer
, int buflen
) {
326 struct enum_settings_state
*e
= handle
;
331 if (e
== NULL
) return NULL
;
333 pb
.hFileInfo
.ioNamePtr
= name
;
334 pb
.hFileInfo
.ioVRefNum
= e
->vRefNum
;
335 pb
.hFileInfo
.ioDirID
= e
->dirID
;
336 pb
.hFileInfo
.ioFDirIndex
= e
->index
++;
337 error
= PBGetCatInfoSync(&pb
);
338 if (error
!= noErr
) return NULL
;
339 } while (!((pb
.hFileInfo
.ioFlAttrib
& ioDirMask
) == 0 &&
340 pb
.hFileInfo
.ioFlFndrInfo
.fdCreator
== PUTTY_CREATOR
&&
341 pb
.hFileInfo
.ioFlFndrInfo
.fdType
== SESS_TYPE
&&
344 p2cstrcpy(buffer
, name
);
348 void enum_settings_finish(void *handle
) {
357 * c-file-style: "simon"