From 03f1c43fd3514d637814b63b84de207d79f2bd61 Mon Sep 17 00:00:00 2001 From: Miro Jurisic Date: Wed, 21 Jul 1999 17:21:56 +0000 Subject: [PATCH] Profile library now uses MacOS native file specifiers on MacOS, and file paths on all other OSes git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11566 dc483132-0cff-0310-8789-dd5450dbe970 --- src/util/profile/prof_file.c | 116 +++++++++++++++++++++++++++-------- src/util/profile/prof_int.h | 80 +++++------------------- src/util/profile/profile.hin | 30 ++++++++- 3 files changed, 136 insertions(+), 90 deletions(-) diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c index 8606bf79e..32ba66d68 100644 --- a/src/util/profile/prof_file.c +++ b/src/util/profile/prof_file.c @@ -28,8 +28,17 @@ #define stat _stat #endif -static int rw_access(filename) - const char *filename; +#ifndef PROFILE_USES_PATHS +#include + +static OSErr GetMacOSTempFilespec ( + const FSSpec* inFilespec, + FSSpec* outFilespec); + +#endif + +static int rw_access(filespec) + profile_filespec_t *filespec; { #ifdef HAVE_ACCESS if (access(filename, W_OK) == 0) @@ -44,7 +53,11 @@ static int rw_access(filename) */ FILE *f; - f = fopen(filename, "r+"); +#ifdef PROFILE_USES_PATHS + f = fopen(filespec, "r+"); +#else + f = FSp_fopen(&filespec, "r+"); +#endif if (f) { fclose(f); return 1; @@ -53,8 +66,8 @@ static int rw_access(filename) #endif } -errcode_t profile_open_file(filename, ret_prof) - const char *filename; +errcode_t profile_open_file(filespec, ret_prof) + profile_filespec_t filespec; prf_file_t *ret_prof; { prf_file_t prf; @@ -66,23 +79,28 @@ errcode_t profile_open_file(filename, ret_prof) if (!prf) return ENOMEM; memset(prf, 0, sizeof(struct _prf_file_t)); - len = strlen(filename)+1; - if (filename[0] == '~' && filename[1] == '/') { + +#ifndef macintosh + len = strlen(filespec)+1; + if (filespec[0] == '~' && filespec[1] == '/') { home_env = getenv("HOME"); if (home_env) len += strlen(home_env); } - prf->filename = malloc(len); - if (!prf->filename) { + prf->filespec = malloc(len); + if (!prf->filespec) { free(prf); return ENOMEM; } if (home_env) { - strcpy(prf->filename, home_env); - strcat(prf->filename, filename+1); + strcpy(prf->filespec, home_env); + strcat(prf->filespec, filespec+1); } else - strcpy(prf->filename, filename); + strcpy(prf->filespec, filespec); prf->magic = PROF_MAGIC_FILE; +#else + prf->filespec = filespec; +#endif retval = profile_update_file(prf); if (retval) { @@ -126,7 +144,11 @@ errcode_t profile_update_file(prf) return 0; #endif errno = 0; - f = fopen(prf->filename, "r"); +#ifdef PROFILE_USES_PATHS + f = fopen(prf->filespec, "r"); +#else + f = FSp_fopen (&prf->filespec, "r"); +#endif if (f == NULL) { retval = errno; if (retval == 0) @@ -135,7 +157,7 @@ errcode_t profile_update_file(prf) } prf->upd_serial++; prf->flags = 0; - if (rw_access(prf->filename)) + if (rw_access(prf->filespec)) prf->flags |= PROFILE_FILE_RW; retval = profile_parse_file(f, &prf->root); fclose(f); @@ -147,11 +169,30 @@ errcode_t profile_update_file(prf) return 0; } +#ifndef PROFILE_USES_PATHS +OSErr GetMacOSTempFilespec ( + const FSSpec* inFileSpec, + FSSpec* outFileSpec) +{ + OSErr err; + + err = FindFolder (inFileSpec -> vRefNum, kTemporaryFolderType, + kCreateFolder, &(outFileSpec -> vRefNum), &(outFileSpec -> parID)); + if (err != noErr) + return err; + + BlockMoveData (&(inFileSpec -> name), &(outFileSpec -> name), StrLength (inFileSpec -> name) + 1); + return noErr; +} +#endif + + errcode_t profile_flush_file(prf) prf_file_t prf; { FILE *f; - char *new_name = 0, *old_name = 0; + profile_filespec_t new_file; + profile_filespec_t olf_file; errcode_t retval = 0; if (!prf || prf->magic != PROF_MAGIC_FILE) @@ -161,18 +202,29 @@ errcode_t profile_flush_file(prf) return 0; retval = ENOMEM; - new_name = malloc(strlen(prf->filename) + 5); + +#ifdef PROFILE_USES_PATHS + new_file = old_file = 0; + new_file = malloc(strlen(prf->filespec) + 5); if (!new_name) goto errout; - old_name = malloc(strlen(prf->filename) + 5); + old_file = malloc(strlen(prf->filespec) + 5); if (!old_name) goto errout; - sprintf(new_name, "%s.$$$", prf->filename); - sprintf(old_name, "%s.bak", prf->filename); + sprintf(new_file, "%s.$$$", prf->filespec); + sprintf(old_file, "%s.bak", prf->filespec); errno = 0; + f = fopen(new_name, "w"); +#else + /* On MacOS, we do this by writing to a new file and then atomically + swapping the files with a file system call */ + GetMacOSTempFilespec (&prf->filespec, &new_file); + f = FSp_fopen (&new_file, "w"); +#endif + if (!f) { retval = errno; if (retval == 0) @@ -186,27 +238,41 @@ errcode_t profile_flush_file(prf) goto errout; } +#ifdef PROFILE_USES_PATHS unlink(old_name); - if (rename(prf->filename, old_name)) { + if (rename(prf->filespec, old_name)) { retval = errno; goto errout; } - if (rename(new_name, prf->filename)) { + if (rename(new_name, prf->filespec)) { retval = errno; rename(old_name, prf->filename); /* back out... */ goto errout; } +#else + { + OSErr err = FSpExchangeFiles (&prf->filespec, &new_file); + if (err != noErr) { + retval = ENFILE; + goto errout; + } + FSpDelete (&new_file); + } +#endif + prf->flags = 0; - if (rw_access(prf->filename)) + if (rw_access(prf->filespec)) prf->flags |= PROFILE_FILE_RW; retval = 0; errout: +#ifdef PROFILE_USES_PATHS if (new_name) free(new_name); if (old_name) free(old_name); +#endif return retval; } @@ -214,8 +280,10 @@ errout: void profile_free_file(prf) prf_file_t prf; { - if (prf->filename) - free(prf->filename); +#ifdef PROFILE_USES_PATHS + if (prf->filespec) + free(prf->filespec); +#endif if (prf->root) profile_free_node(prf->root); if (prf->comment) diff --git a/src/util/profile/prof_int.h b/src/util/profile/prof_int.h index dea4fde84..90d43d716 100644 --- a/src/util/profile/prof_int.h +++ b/src/util/profile/prof_int.h @@ -5,6 +5,7 @@ #include #include "com_err.h" #include "prof_err.h" +#include "profile.h" #if defined(__STDC__) || defined(_MSDOS) || defined(_WIN32) #define PROTOTYPE(x) x @@ -39,7 +40,7 @@ typedef long prf_magic_t; struct _prf_file_t { prf_magic_t magic; char *comment; - char *filename; + profile_filespec_t filespec; struct profile_node *root; time_t timestamp; int flags; @@ -76,6 +77,16 @@ typedef struct _profile_t *profile_t; #define PROFILE_ITER_FINAL_SEEN 0x0100 +/* + * Check if a filespec is last in a list (NULL on UNIX, invalid FSSpec on MacOS + */ + +#ifdef PROFILE_USES_PATHS +#define PROFILE_LAST_FILESPEC(x) (((x) == NULL) || ((x)[0] == NULL)) +#else +#define PROFILE_LAST_FILESPEC(x) (((x).vRefNum == 0) && ((x).parID == 0) && ((x).name[0] == '\0')) +#endif + /* profile_parse.c */ errcode_t profile_parse_file @@ -164,7 +175,7 @@ errcode_t profile_rename_node /* prof_file.c */ errcode_t profile_open_file - PROTOTYPE ((const char *filename, prf_file_t *ret_prof)); + PROTOTYPE ((profile_filespec_t file, prf_file_t *ret_prof)); errcode_t profile_update_file PROTOTYPE ((prf_file_t profile)); @@ -178,72 +189,13 @@ void profile_free_file errcode_t profile_close_file PROTOTYPE ((prf_file_t profile)); -/* prof_init.c */ - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_init - PROTOTYPE ((const char **filenames, profile_t *ret_profile)); - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_init_path - PROTOTYPE ((const char *filepath, profile_t *ret_profile)); - -KRB5_DLLIMP void KRB5_CALLCONV profile_release - PROTOTYPE ((profile_t profile)); +/* prof_init.c -- included from profile.h */ /* prof_get.c */ -KRB5_DLLIMP void KRB5_CALLCONV profile_free_list - PROTOTYPE ((char **list)); - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_get_values - PROTOTYPE ((profile_t profile, const char **names, - char ***ret_values)); - errcode_t profile_get_value PROTOTYPE ((profile_t profile, const char **names, const char **ret_value)); +/* Others included from profile.h */ -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_get_string - PROTOTYPE((profile_t profile, const char *name, const char *subname, - const char *subsubname, const char *def_val, - char **ret_string)); -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_get_integer - PROTOTYPE((profile_t profile, const char *name, const char *subname, - const char *subsubname, int def_val, - int *ret_default)); - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_get_relation_names - PROTOTYPE((profile_t profile, const char **names, char ***ret_names)); - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_get_subsection_names - PROTOTYPE((profile_t profile, const char **names, char ***ret_names)); - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_iterator_create - PROTOTYPE((profile_t profile, const char **names, - int flags, void **ret_iter)); - -KRB5_DLLIMP void KRB5_CALLCONV profile_iterator_free - PROTOTYPE((void **iter_p)); - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_iterator - PROTOTYPE((void **iter_p, char **ret_name, char **ret_value)); - -KRB5_DLLIMP void KRB5_CALLCONV profile_release_string PROTOTYPE((char *str)); - - -/* prof_set.c */ -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_update_relation - PROTOTYPE((profile_t profile, const char **names, - const char *old_value, const char *new_value)); - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_clear_relation - PROTOTYPE((profile_t profile, const char **names)); - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_rename_section - PROTOTYPE((profile_t profile, const char **names, - const char *new_name)); - -KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_add_relation - PROTOTYPE((profile_t profile, const char **names, - const char *new_value)); - - +/* prof_set.c -- included from profile.h */ diff --git a/src/util/profile/profile.hin b/src/util/profile/profile.hin index 51724b3e5..420b955d4 100644 --- a/src/util/profile/profile.hin +++ b/src/util/profile/profile.hin @@ -36,15 +36,36 @@ typedef struct _profile_t *profile_t; #define PROFILE_ITER_SECTIONS_ONLY 0x0002 #define PROFILE_ITER_RELATIONS_ONLY 0x0004 +/* Macintoh CFM-68K magic incantation */ +#if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__) +#pragma import on +#endif + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +/* On everything but MacOS, we use file paths as unique file identifiers */ +#ifndef macintosh +#define PROFILE_USES_PATHS +#endif + +#ifdef PROFILE_USES_PATHS +typedef char* profile_filespec_t; /* path as C string */ +typedef char* profile_filespec_list_t; /* list of : separated paths, C string */ +#else +/* On MacOS, we use native file specifiers as unique file identifiers */ +#include +typedef FSSpec profile_filespec_t; +typedef FSSpec* profile_filespec_list_t; + /* array should be terminated with {0, 0, ""} */ +#endif + KRB5_DLLIMP long KRB5_CALLCONV profile_init - PROTOTYPE ((const char **filenames, profile_t *ret_profile)); + PROTOTYPE ((profile_filespec_t *files, profile_t *ret_profile)); KRB5_DLLIMP long KRB5_CALLCONV profile_init_path - PROTOTYPE ((const char *filepath, profile_t *ret_profile)); + PROTOTYPE ((profile_filespec_list_t filelist, profile_t *ret_profile)); KRB5_DLLIMP long KRB5_CALLCONV profile_flush PROTOTYPE ((profile_t profile)); @@ -107,4 +128,9 @@ KRB5_DLLIMP long KRB5_CALLCONV profile_add_relation } #endif /* __cplusplus */ +/* Macintoh CFM-68K magic incantation */ +#if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__) +#pragma import reset +#endif + #endif /* _KRB5_PROFILE_H */ -- 2.26.2