1 /* $Id: macstore.c,v 1.1 2002/11/19 02:13:46 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
;
93 struct write_settings
*ws
;
95 ws
= safemalloc(sizeof *ws
);
96 error
= get_session_dir(kCreateFolder
, &sessVRefNum
, &sessDirID
);
97 if (error
!= noErr
) goto out
;
99 c2pstrcpy(psessionname
, sessionname
);
100 error
= FSMakeFSSpec(sessVRefNum
, sessDirID
, psessionname
, &ws
->dstfile
);
101 if (error
!= noErr
&& error
!= fnfErr
) goto out
;
102 if (error
== fnfErr
) {
103 FSpCreateResFile(&ws
->dstfile
, PUTTY_CREATOR
, SESS_TYPE
,
105 if ((error
= ResError()) != noErr
) goto out
;
108 /* Create a temporary file to save to first. */
109 error
= FindFolder(sessVRefNum
, kTemporaryFolderType
, kCreateFolder
,
110 &tmpVRefNum
, &tmpDirID
);
111 if (error
!= noErr
) goto out
;
112 error
= FSMakeFSSpec(tmpVRefNum
, tmpDirID
, psessionname
, &ws
->tmpfile
);
113 if (error
!= noErr
&& error
!= fnfErr
) goto out
;
114 if (error
== noErr
) {
115 error
= FSpDelete(&ws
->tmpfile
);
116 if (error
!= noErr
) goto out
;
118 FSpCreateResFile(&ws
->tmpfile
, PUTTY_CREATOR
, SESS_TYPE
, smSystemScript
);
119 if ((error
= ResError()) != noErr
) goto out
;
121 ws
->fd
= FSpOpenResFile(&ws
->tmpfile
, fsWrPerm
);
122 if (ws
->fd
== -1) {error
= ResError(); goto out
;}
128 fatalbox("Failed to open session for write (%d)", error
);
131 void write_setting_s(void *handle
, char *key
, char *value
) {
132 int fd
= *(int *)handle
;
138 if (ResError() != noErr
)
139 fatalbox("Failed to open saved session (%d)", ResError());
141 error
= PtrToHand(value
, &h
, strlen(value
));
143 fatalbox("Failed to allocate memory");
144 /* Put the data in a resource. */
145 id
= Unique1ID(FOUR_CHAR_CODE('TEXT'));
146 if (ResError() != noErr
)
147 fatalbox("Failed to get ID for resource %s (%d)", key
, ResError());
148 addresource(h
, FOUR_CHAR_CODE('TEXT'), id
, key
);
149 if (ResError() != noErr
)
150 fatalbox("Failed to add resource %s (%d)", key
, ResError());
153 void write_setting_i(void *handle
, char *key
, int value
) {
154 int fd
= *(int *)handle
;
160 if (ResError() != noErr
)
161 fatalbox("Failed to open saved session (%d)", ResError());
163 /* XXX assume all systems have the same "int" format */
164 error
= PtrToHand(&value
, &h
, sizeof(int));
166 fatalbox("Failed to allocate memory (%d)", error
);
168 /* Put the data in a resource. */
169 id
= Unique1ID(FOUR_CHAR_CODE('Int '));
170 if (ResError() != noErr
)
171 fatalbox("Failed to get ID for resource %s (%d)", key
, ResError());
172 addresource(h
, FOUR_CHAR_CODE('Int '), id
, key
);
173 if (ResError() != noErr
)
174 fatalbox("Failed to add resource %s (%d)", key
, ResError());
177 void close_settings_w(void *handle
) {
178 struct write_settings
*ws
= handle
;
181 CloseResFile(ws
->fd
);
182 if ((error
= ResError()) != noErr
)
184 error
= FSpExchangeFiles(&ws
->tmpfile
, &ws
->dstfile
);
185 if (error
!= noErr
) goto out
;
186 error
= FSpDelete(&ws
->tmpfile
);
187 if (error
!= noErr
) goto out
;
191 fatalbox("Close of saved session failed (%d)", error
);
195 void *open_settings_r(char *sessionname
) {
204 error
= get_session_dir(kDontCreateFolder
, &sessVRefNum
, &sessDirID
);
206 c2pstrcpy(psessionname
, sessionname
);
207 error
= FSMakeFSSpec(sessVRefNum
, sessDirID
, psessionname
, &sessfile
);
208 if (error
!= noErr
) goto out
;
209 fd
= FSpOpenResFile(&sessfile
, fsRdPerm
);
210 if (fd
== 0) {error
= ResError(); goto out
;}
212 handle
= safemalloc(sizeof *handle
);
221 char *read_setting_s(void *handle
, char *key
, char *buffer
, int buflen
) {
226 if (handle
== NULL
) goto out
;
229 if (ResError() != noErr
) goto out
;
230 h
= get1namedresource(FOUR_CHAR_CODE('TEXT'), key
);
231 if (h
== NULL
) goto out
;
233 if (GetHandleSize(h
) > buflen
) goto out
;
234 p2cstrcpy(buffer
, (StringPtr
)*h
);
236 if (ResError() != noErr
) goto out
;
243 int read_setting_i(void *handle
, char *key
, int defvalue
) {
249 if (handle
== NULL
) goto out
;
252 if (ResError() != noErr
) goto out
;
253 h
= get1namedresource(FOUR_CHAR_CODE('Int '), key
);
254 if (h
== NULL
) goto out
;
257 if (ResError() != noErr
) goto out
;
264 void close_settings_r(void *handle
) {
267 if (handle
== NULL
) return;
270 if (ResError() != noErr
)
271 fatalbox("Close of saved session failed (%d)", ResError());
275 void del_settings(char *sessionname
) {
282 error
= get_session_dir(kDontCreateFolder
, &sessVRefNum
, &sessDirID
);
284 c2pstrcpy(psessionname
, sessionname
);
285 error
= FSMakeFSSpec(sessVRefNum
, sessDirID
, psessionname
, &sessfile
);
286 if (error
!= noErr
) goto out
;
288 error
= FSpDelete(&sessfile
);
291 fatalbox("Delete session failed (%d)", error
);
294 struct enum_settings_state
{
300 void *enum_settings_start(void) {
302 struct enum_settings_state
*state
;
304 state
= safemalloc(sizeof(*state
));
305 error
= get_session_dir(kDontCreateFolder
, &state
->vRefNum
, &state
->dirID
);
306 if (error
!= noErr
) {
314 char *enum_settings_next(void *handle
, char *buffer
, int buflen
) {
315 struct enum_settings_state
*e
= handle
;
320 if (e
== NULL
) return NULL
;
322 pb
.hFileInfo
.ioNamePtr
= name
;
323 pb
.hFileInfo
.ioVRefNum
= e
->vRefNum
;
324 pb
.hFileInfo
.ioDirID
= e
->dirID
;
325 pb
.hFileInfo
.ioFDirIndex
= e
->index
++;
326 error
= PBGetCatInfoSync(&pb
);
327 if (error
!= noErr
) return NULL
;
328 } while (!((pb
.hFileInfo
.ioFlAttrib
& ioDirMask
) == 0 &&
329 pb
.hFileInfo
.ioFlFndrInfo
.fdCreator
== PUTTY_CREATOR
&&
330 pb
.hFileInfo
.ioFlFndrInfo
.fdType
== SESS_TYPE
&&
333 p2cstrcpy(buffer
, name
);
337 void enum_settings_finish(void *handle
) {
346 * c-file-style: "simon"