extern GPrivate *glk_data_key;
-/* Internal function: create a fileref using the given parameters. */
+/* Internal function: create a fileref using the given parameters. If @basename
+is NULL, compute a basename from @filename. */
frefid_t
-fileref_new(gchar *filename, glui32 rock, glui32 usage, glui32 orig_filemode)
+fileref_new(char *filename, char *basename, glui32 rock, glui32 usage, glui32 orig_filemode)
{
g_return_val_if_fail(filename != NULL, NULL);
f->disprock = (*glk_data->register_obj)(f, gidisp_Class_Fileref);
f->filename = g_strdup(filename);
+ if(basename)
+ f->basename = g_strdup(basename);
+ else
+ f->basename = g_path_get_basename(filename);
f->usage = usage;
f->orig_filemode = orig_filemode;
fref->disprock.ptr = NULL;
}
- if(fref->filename)
- g_free(fref->filename);
+ g_free(fref->filename);
+ g_free(fref->basename);
fref->magic = MAGIC_FREE;
g_free(fref);
return NULL;
}
- frefid_t f = fileref_new(filename, rock, usage, filemode_Write);
+ /* Pass a basename of "" to ensure that this file can't be repurposed */
+ frefid_t f = fileref_new(filename, "", rock, usage, filemode_Write);
g_free(filename);
return f;
}
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_action(GTK_FILE_CHOOSER(chooser), GTK_FILE_CHOOSER_ACTION_SAVE);
-
- /* COMPAT: */
-#if GTK_CHECK_VERSION(2,8,0)
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(chooser), TRUE);
-#endif
break;
case filemode_ReadWrite:
case filemode_WriteAppend:
return NULL;
}
gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(chooser) );
- frefid_t f = fileref_new(filename, rock, usage, fmode);
+ frefid_t f = fileref_new(filename, NULL, rock, usage, fmode);
g_free(filename);
gtk_widget_destroy(chooser);
ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
/* Do any string-munging here to remove illegal Latin-1 characters from
- filename. On ext3, the only illegal characters are '/' and '\0'. */
- g_strdelimit(name, "/", '_');
+ filename. On ext3, the only illegal characters are '/' and '\0', but the Glk
+ spec calls for removing any other tricky characters. */
+ char *buf = g_malloc(strlen(name));
+ char *ptr, *filename, *extension;
+ int len;
+ for(ptr = name, len = 0; *ptr && *ptr != '.'; ptr++)
+ {
+ switch(*ptr)
+ {
+ case '"': case '\\': case '/': case '>': case '<':
+ case ':': case '|': case '?': case '*':
+ break;
+ default:
+ buf[len++] = *ptr;
+ }
+ }
+ buf[len] = '\0';
+
+ /* If there is nothing left, make the name "null" */
+ if(len == 0) {
+ strcpy(buf, "null");
+ len = strlen(buf);
+ }
+
+ switch(usage & fileusage_TypeMask)
+ {
+ case fileusage_Data:
+ extension = ".glkdata";
+ break;
+ case fileusage_SavedGame:
+ extension = ".glksave";
+ break;
+ case fileusage_InputRecord:
+ case fileusage_Transcript:
+ extension = ".txt";
+ break;
+ default:
+ ILLEGAL_PARAM("Unknown file usage: %u", usage);
+ return NULL;
+ }
+ filename = g_strconcat(buf, extension, NULL);
/* Find out what encoding filenames are in */
const gchar **charsets; /* Do not free */
/* Convert name to that encoding */
GError *error = NULL;
- gchar *osname = g_convert(name, -1, charsets[0], "ISO-8859-1", NULL, NULL,
- &error);
+ char *osname = g_convert(filename, -1, charsets[0], "ISO-8859-1", NULL, NULL, &error);
if(osname == NULL)
{
WARNING_S("Error during latin1->filename conversion", error->message);
path = g_strdup(osname);
g_free(osname);
- frefid_t f = fileref_new(path, rock, usage, filemode_ReadWrite);
+ frefid_t f = fileref_new(path, buf, rock, usage, filemode_ReadWrite);
g_free(path);
+ g_free(buf);
return f;
}
glk_fileref_create_from_fileref(glui32 usage, frefid_t fref, glui32 rock)
{
VALID_FILEREF(fref, return NULL);
- return fileref_new(fref->filename, rock, usage, fref->orig_filemode);
+ return fileref_new(fref->filename, fref->basename, rock, usage, fref->orig_filemode);
}
/**