diff --git a/mac/mac.c b/mac/mac.c index 50d3199c..cea87fbf 100644 --- a/mac/mac.c +++ b/mac/mac.c @@ -1,4 +1,4 @@ -/* $Id: mac.c,v 1.40 2003/02/01 17:24:26 simon Exp $ */ +/* $Id: mac.c,v 1.41 2003/02/01 21:44:05 ben Exp $ */ /* * Copyright (c) 1999 Ben Harris * All rights reserved. @@ -771,9 +771,9 @@ Filename platform_default_filename(const char *name) { Filename ret; if (!strcmp(name, "LogFileName")) - strcpy(ret.path, "putty.log"); + FSMakeFSSpec(0, 0, "\pputty.log", &ret.fss); else - *ret.path = '\0'; + memset(&ret, 0, sizeof(ret)); return ret; } @@ -804,24 +804,80 @@ void platform_get_x11_auth(char *display, int *proto, Filename filename_from_str(const char *str) { Filename ret; - strncpy(ret.path, str, sizeof(ret.path)); - ret.path[sizeof(ret.path)-1] = '\0'; + Str255 tmp; + + /* XXX This fails for filenames over 255 characters long. */ + c2pstrcpy(tmp, str); + FSMakeFSSpec(0, 0, tmp, &ret.fss); return ret; } +/* + * Convert a filename to a string for display purposes. + * See pp 2-44--2-46 of IM:Files + * + * XXX static storage considered harmful + */ const char *filename_to_str(const Filename *fn) { - return fn->path; + CInfoPBRec pb; + Str255 dirname; + OSErr err; + static char *path = NULL; + char *newpath; + + if (path != NULL) sfree(path); + path = smalloc(fn->fss.name[0]); + p2cstrcpy(path, fn->fss.name); + pb.dirInfo.ioNamePtr = dirname; + pb.dirInfo.ioVRefNum = fn->fss.vRefNum; + pb.dirInfo.ioDrParID = fn->fss.parID; + pb.dirInfo.ioFDirIndex = -1; + do { + pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; + err = PBGetCatInfoSync(&pb); + + /* XXX Assume not A/UX */ + newpath = smalloc(strlen(path) + dirname[0] + 2); + p2cstrcpy(newpath, dirname); + strcat(newpath, ":"); + strcat(newpath, path); + sfree(path); + path = newpath; + } while (pb.dirInfo.ioDrDirID != fsRtDirID); + return path; } int filename_equal(Filename f1, Filename f2) { - return !strcmp(f1.path, f2.path); + + return f1.fss.vRefNum == f2.fss.vRefNum && + f1.fss.parID == f2.fss.parID && + f1.fss.name[0] == f2.fss.name[0] && + memcmp(f1.fss.name + 1, f2.fss.name + 1, f1.fss.name[0]) == 0; } int filename_is_null(Filename fn) { - return !*fn.path; + + return fn.fss.vRefNum == 0 && fn.fss.parID == 0 && fn.fss.name[0] == 0; +} + +FILE *f_open(Filename fn, char const *mode) +{ + short savevol; + long savedir; + char tmp[256]; + FILE *ret; + + HGetVol(NULL, &savevol, &savedir); + if (HSetVol(NULL, fn.fss.vRefNum, fn.fss.parID) == noErr) { + p2cstrcpy(tmp, fn.fss.name); + ret = fopen(tmp, mode); + } else + ret = NULL; + HSetVol(NULL, savevol, savedir); + return ret; } /* diff --git a/mac/macstore.c b/mac/macstore.c index 57ed7721..244569e9 100644 --- a/mac/macstore.c +++ b/mac/macstore.c @@ -1,4 +1,4 @@ -/* $Id: macstore.c,v 1.14 2003/02/01 15:44:08 ben Exp $ */ +/* $Id: macstore.c,v 1.15 2003/02/01 21:44:05 ben Exp $ */ /* * macstore.c: Macintosh-specific impementation of the interface @@ -360,12 +360,92 @@ void write_setting_fontspec(void *handle, const char *name, FontSpec font) int read_setting_filename(void *handle, const char *name, Filename *result) { - return !!read_setting_s(handle, name, result->path, sizeof(result->path)); + int fd; + AliasHandle h; + Boolean changed; + OSErr err; + + if (handle == NULL) goto out; + fd = *(int *)handle; + UseResFile(fd); + if (ResError() != noErr) goto out; + h = (AliasHandle)get1namedresource(rAliasType, name); + if (h == NULL) goto out; + if ((*h)->userType == 'pTTY' && (*h)->aliasSize == sizeof(**h)) + memset(result, 0, sizeof(*result)); + else { + err = ResolveAlias(NULL, h, &result->fss, &changed); + if (err != noErr && err != fnfErr) goto out; + if ((*h)->userType == 'pTTY') { + long dirid; + StrFileName fname; + + /* Tail of record is pascal string contaning leafname */ + if (FSpGetDirID(&result->fss, &dirid, FALSE) != noErr) goto out; + memcpy(fname, (char *)*h + (*h)->aliasSize, + GetHandleSize((Handle)h) - (*h)->aliasSize); + err = FSMakeFSSpec(result->fss.vRefNum, dirid, fname, + &result->fss); + if (err != noErr && err != fnfErr) goto out; + } + } + ReleaseResource((Handle)h); + if (ResError() != noErr) goto out; + return 1; + + out: + return 0; } -void write_setting_filename(void *handle, const char *name, Filename result) +void write_setting_filename(void *handle, const char *name, Filename fn) { - write_setting_s(handle, name, result.path); + int fd = *(int *)handle; + AliasHandle h; + int id; + OSErr error; + + UseResFile(fd); + if (ResError() != noErr) + fatalbox("Failed to open saved session (%d)", ResError()); + + if (filename_is_null(fn)) { + /* Generate a special "null" alias */ + h = (AliasHandle)NewHandle(sizeof(**h)); + if (h == NULL) + fatalbox("Failed to create fake alias"); + (*h)->userType = 'pTTY'; + (*h)->aliasSize = sizeof(**h); + } else { + error = NewAlias(NULL, &fn.fss, &h); + if (error == fnfErr) { + /* + * NewAlias can't create an alias for a nonexistent file. + * Create an alias for the directory, and record the + * filename as well. + */ + FSSpec tmpfss; + + FSMakeFSSpec(fn.fss.vRefNum, fn.fss.parID, NULL, &tmpfss); + error = NewAlias(NULL, &tmpfss, &h); + if (error != noErr) + fatalbox("Failed to create alias"); + (*h)->userType = 'pTTY'; + SetHandleSize((Handle)h, (*h)->aliasSize + fn.fss.name[0] + 1); + if (MemError() != noErr) + fatalbox("Failed to create alias"); + memcpy((char *)*h + (*h)->aliasSize, fn.fss.name, + fn.fss.name[0] + 1); + } + if (error != noErr) + fatalbox("Failed to create alias"); + } + /* Put the data in a resource. */ + id = Unique1ID(rAliasType); + if (ResError() != noErr) + fatalbox("Failed to get ID for resource %s (%d)", name, ResError()); + addresource((Handle)h, rAliasType, id, name); + if (ResError() != noErr) + fatalbox("Failed to add resource %s (%d)", name, ResError()); } void close_settings_r(void *handle) { diff --git a/mac/macstuff.h b/mac/macstuff.h index 1193e005..c0728859 100644 --- a/mac/macstuff.h +++ b/mac/macstuff.h @@ -5,17 +5,21 @@ typedef void *Context; /* FIXME */ #include -#include /* for FILENAME_MAX */ +#include + +#include struct Filename { - char path[FILENAME_MAX]; + FSSpec fss; }; -#define f_open(filename, mode) ( fopen((filename).path, (mode)) ) + +extern FILE * f_open(struct Filename, char const *); /* Suspiciously similar to an ICFontRecord */ struct FontSpec { short size; Style face; + char pad; Str255 name; };