#define stat _stat
#endif
-static int rw_access(filename)
- const char *filename;
+#ifndef PROFILE_USES_PATHS
+#include <FSp_fopen.h>
+
+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)
*/
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;
#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;
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) {
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)
}
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);
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)
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)
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;
}
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)
#include <time.h>
#include "com_err.h"
#include "prof_err.h"
+#include "profile.h"
#if defined(__STDC__) || defined(_MSDOS) || defined(_WIN32)
#define PROTOTYPE(x) x
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;
#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
/* 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));
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 */
#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 <Files.h>
+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));
}
#endif /* __cplusplus */
+/* Macintoh CFM-68K magic incantation */
+#if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
+#pragma import reset
+#endif
+
#endif /* _KRB5_PROFILE_H */