зеркало из https://github.com/github/putty.git
Rather more natural (if much more complex) Mac Filename implementation.
Filenames are represented as a FSSpec, which is converted to and from an alias record ('alis' resource) when saving and loading sessions. . It might be an idea to allow in-core Filenames to contain alias records too, so that they can refer to directories that don't exist on the current system, but that requires Filenames to be dynamically allocated, which is likely to be a pain. [originally from svn r2771]
This commit is contained in:
Родитель
4f76d033d5
Коммит
61711b9594
72
mac/mac.c
72
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
|
* Copyright (c) 1999 Ben Harris
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -771,9 +771,9 @@ Filename platform_default_filename(const char *name)
|
||||||
{
|
{
|
||||||
Filename ret;
|
Filename ret;
|
||||||
if (!strcmp(name, "LogFileName"))
|
if (!strcmp(name, "LogFileName"))
|
||||||
strcpy(ret.path, "putty.log");
|
FSMakeFSSpec(0, 0, "\pputty.log", &ret.fss);
|
||||||
else
|
else
|
||||||
*ret.path = '\0';
|
memset(&ret, 0, sizeof(ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,24 +804,80 @@ void platform_get_x11_auth(char *display, int *proto,
|
||||||
Filename filename_from_str(const char *str)
|
Filename filename_from_str(const char *str)
|
||||||
{
|
{
|
||||||
Filename ret;
|
Filename ret;
|
||||||
strncpy(ret.path, str, sizeof(ret.path));
|
Str255 tmp;
|
||||||
ret.path[sizeof(ret.path)-1] = '\0';
|
|
||||||
|
/* XXX This fails for filenames over 255 characters long. */
|
||||||
|
c2pstrcpy(tmp, str);
|
||||||
|
FSMakeFSSpec(0, 0, tmp, &ret.fss);
|
||||||
return ret;
|
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)
|
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)
|
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)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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
|
* 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)
|
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) {
|
void close_settings_r(void *handle) {
|
||||||
|
|
|
@ -5,17 +5,21 @@
|
||||||
typedef void *Context; /* FIXME */
|
typedef void *Context; /* FIXME */
|
||||||
|
|
||||||
#include <MacTypes.h>
|
#include <MacTypes.h>
|
||||||
#include <stdio.h> /* for FILENAME_MAX */
|
#include <Files.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
struct Filename {
|
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 */
|
/* Suspiciously similar to an ICFontRecord */
|
||||||
struct FontSpec {
|
struct FontSpec {
|
||||||
short size;
|
short size;
|
||||||
Style face;
|
Style face;
|
||||||
|
char pad;
|
||||||
Str255 name;
|
Str255 name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче