enum { N_CLASSES = sizeof classes / sizeof *classes };
int
-any_reader_detect (const char *file_name,
+any_reader_detect (const struct file_handle *file_handle,
const struct any_reader_class **classp)
{
struct detector
if (classp)
*classp = NULL;
- file = fn_open (file_name, "rb");
+ file = fn_open (file_handle, "rb");
if (file == NULL)
{
msg (ME, _("An error occurred while opening `%s': %s."),
- file_name, strerror (errno));
+ fh_get_file_name (file_handle), strerror (errno));
return -errno;
}
}
if (retval < 0)
- msg (ME, _("Error reading `%s': %s."), file_name, strerror (-retval));
+ msg (ME, _("Error reading `%s': %s."), fh_get_file_name (file_handle), strerror (-retval));
- fn_close (file_name, file);
+ fn_close (file_handle, file);
return retval;
}
const struct any_reader_class *class;
int retval;
- retval = any_reader_detect (fh_get_file_name (handle), &class);
+ retval = any_reader_detect (handle, &class);
if (retval <= 0)
{
if (retval == 0)
struct file_handle;
struct dictionary;
-int any_reader_detect (const char *file_name,
+int any_reader_detect (const struct file_handle *file_name,
const struct any_reader_class **);
struct any_reader *any_reader_open (struct file_handle *);
struct casewriter *writer;
char *extension;
- extension = fn_extension (fh_get_file_name (handle));
+ extension = fn_extension (handle);
str_lowercase (extension);
if (!strcmp (extension, ".por"))
#include <config.h>
#include "data/encrypted-file.h"
+#include "data/file-handle-def.h"
#include <errno.h>
#include <stdlib.h>
If FILENAME cannot be open or read, returns a negative errno value. */
int
-encrypted_file_open (struct encrypted_file **fp, const char *filename)
+encrypted_file_open (struct encrypted_file **fp, const struct file_handle *fh)
{
struct encrypted_file *f;
char header[36 + 16];
f = xmalloc (sizeof *f);
f->error = 0;
- f->file = fn_open (filename, "rb");
+ f->file = fn_open (fh, "rb");
if (f->file == NULL)
{
msg (ME, _("An error occurred while opening `%s': %s."),
- filename, strerror (errno));
+ fh_get_file_name (fh), strerror (errno));
retval = -errno;
goto error;
}
int error = feof (f->file) ? 0 : errno;
if (error)
msg (ME, _("An error occurred while reading `%s': %s."),
- filename, strerror (error));
+ fh_get_file_name (fh), strerror (error));
retval = -error;
goto error;
}
error:
if (f->file)
- fn_close (filename, f->file);
+ fn_close (fh, f->file);
free (f);
*fp = NULL;
/* Reading encrypted SPSS files. */
struct encrypted_file;
+struct file_handle;
-int encrypted_file_open (struct encrypted_file **, const char *filename);
+int encrypted_file_open (struct encrypted_file **, const struct file_handle *);
bool encrypted_file_unlock (struct encrypted_file *, const char *password);
size_t encrypted_file_read (struct encrypted_file *, void *, size_t);
int encrypted_file_close (struct encrypted_file *);
#include <string.h>
#include "data/dataset.h"
-#include "data/file-name.h"
#include "data/variable.h"
#include "libpspp/cast.h"
#include "libpspp/compiler.h"
#include "data/settings.h"
#include "libpspp/hash-functions.h"
#include "libpspp/message.h"
+#include "libpspp/i18n.h"
#include "libpspp/str.h"
#include "libpspp/version.h"
\f
/* Functions for performing operations on file names. */
-/* Searches for a configuration file with name NAME in the directories given in
+
+/* Returns the extension part of FILE_NAME as a malloc()'d string.
+ If FILE_NAME does not have an extension, returns an empty
+ string. */
+char *
+fn_extension (const struct file_handle *fh)
+{
+ const char *file_name = fh_get_file_name (fh);
+
+ const char *extension = strrchr (file_name, '.');
+ if (extension == NULL)
+ extension = "";
+ return xstrdup (extension);
+}
+\f
+/* Find out information about files. */
+
+/* Returns true iff NAME specifies an absolute file name. */
+static bool
+fn_is_absolute (const char *name)
+{
+ return IS_ABSOLUTE_FILE_NAME (name);
+}
+
+
+/* Searches for a file with name NAME in the directories given in
PATH, which is terminated by a null pointer. Returns the full name of the
first file found, which the caller is responsible for freeing with free(),
or NULL if none is found. */
else
file = xasprintf ("%s/%s", dir, base_name);
- if (fn_exists (file))
- return file;
+ struct stat temp;
+ if (( (stat (file, &temp) == 0 ) && ( ! S_ISDIR (temp.st_mode) )))
+ return file;
+
free (file);
}
return NULL;
}
-/* Returns the extension part of FILE_NAME as a malloc()'d string.
- If FILE_NAME does not have an extension, returns an empty
- string. */
-char *
-fn_extension (const char *file_name)
-{
- const char *extension = strrchr (file_name, '.');
- if (extension == NULL)
- extension = "";
- return xstrdup (extension);
-}
-\f
-/* Find out information about files. */
-
-/* Returns true iff NAME specifies an absolute file name. */
-bool
-fn_is_absolute (const char *name)
-{
- return IS_ABSOLUTE_FILE_NAME (name);
-}
/* Returns true if file with name NAME exists, and that file is not a
directory */
bool
-fn_exists (const char *name)
+fn_exists (const struct file_handle *fh)
{
+ const char *name = fh_get_file_name (fh);
struct stat temp;
if ( stat (name, &temp) != 0 )
return false;
NULL on failure. If NULL is returned then errno is set to a
sensible value. */
FILE *
-fn_open (const char *fn, const char *mode)
+fn_open (const struct file_handle *fh, const char *mode)
{
+ const char *fn = fh_get_file_name (fh);
+
assert (mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a');
if (mode[0] == 'r')
}
else
#endif
+
+#if WIN32
+ {
+ wchar_t *ss = convert_to_filename_encoding (fn, strlen (fn), fh_get_file_name_encoding (fh));
+ wchar_t *m = (wchar_t *) recode_string ("UTF-16LE", "ASCII", mode, strlen (mode));
+ FILE *fp = _wfopen (ss, m);
+ free (m);
+ free (ss);
+ return fp;
+ }
+#else
return fopen (fn, mode);
+#endif
}
/* Counterpart to fn_open that closes file F with name FN; returns 0
on success, EOF on failure. If EOF is returned, errno is set to a
sensible value. */
int
-fn_close (const char *fn, FILE *f)
+fn_close (const struct file_handle *fh, FILE *f)
{
+ const char *fn = fh_get_file_name (fh);
if (fileno (f) == STDIN_FILENO
|| fileno (f) == STDOUT_FILENO
|| fileno (f) == STDERR_FILENO)
{
/* Windows NT defines HOMEDRIVE and HOMEPATH. But give preference
to HOME, because the user can change HOME. */
-
const char *home_dir = getenv ("HOME");
int i;
#include <stdbool.h>
#include <sys/types.h>
+struct file_handle ;
+
char *fn_search_path (const char *base_name, char **path);
-char *fn_extension (const char *fn);
+char *fn_extension (const struct file_handle *);
+
+bool fn_exists (const struct file_handle *);
-bool fn_is_absolute (const char *fn);
-bool fn_exists (const char *fn);
-FILE *fn_open (const char *fn, const char *mode);
-int fn_close (const char *fn, FILE *file);
+FILE *fn_open (const struct file_handle *fn, const char *mode);
+int fn_close (const struct file_handle *fn, FILE *file);
const char * default_output_path (void);
+#if defined _WIN32 || defined __WIN32__
+#define WIN32_LEAN_AND_MEAN /* avoid including junk */
+#define UNICODE 1
+#include <windows.h>
+#else
+typedef char TCHAR;
+#endif
+
+TCHAR * convert_to_filename_encoding (const char *s, size_t len, const char *current_encoding);
+
+
#endif /* file-name.h */
#if defined _WIN32 || defined __WIN32__
#define WIN32_LEAN_AND_MEAN /* avoid including junk */
-#define UNICODE 1
#include <windows.h>
#define TS_stat _stat
#define Tunlink _wunlink
return -1;
}
-static TCHAR *
+TCHAR *
convert_to_filename_encoding (const char *s, size_t len, const char *current_encoding)
{
const char *enc = current_encoding;
#define Topen open
#define Tstat stat
-static TCHAR *
+TCHAR *
convert_to_filename_encoding (const char *s, size_t len UNUSED, const char *current_encoding UNUSED)
{
/* Non-windows systems don't care about the encoding.
goto error;
/* Open file. */
- r->file = fn_open (fh_get_file_name (fh), "rb");
+ r->file = fn_open (fh, "rb");
if (r->file == NULL)
{
msg (ME, _("Error opening `%s' for reading as an SPSS/PC+ "
if (r->file)
{
- if (fn_close (fh_get_file_name (r->fh), r->file) == EOF)
+ if (fn_close (r->fh, r->file) == EOF)
{
msg (ME, _("Error closing system file `%s': %s."),
fh_get_file_name (r->fh), strerror (errno));
any_read_info_destroy (&r->info);
if (r->file)
{
- if (fn_close (fh_get_file_name (r->fh), r->file) == EOF)
+ if (fn_close (r->fh, r->file) == EOF)
{
msg (ME, _("Error closing portable file `%s': %s."),
fh_get_file_name (r->fh), strerror (errno));
goto error;
/* Open file. */
- r->file = fn_open (fh_get_file_name (r->fh), "rb");
+ r->file = fn_open (r->fh, "rb");
if (r->file == NULL)
{
msg (ME, _("An error occurred while opening `%s' for reading "
if (r->lock == NULL)
goto error;
- r->file = fn_open (fh_get_file_name (fh), "rb");
+ r->file = fn_open (fh, "rb");
if (r->file == NULL)
{
msg (ME, _("Error opening `%s' for reading as a system file: %s."),
if (r->file)
{
- if (fn_close (fh_get_file_name (r->fh), r->file) == EOF)
+ if (fn_close (r->fh, r->file) == EOF)
{
msg (ME, _("Error closing system file `%s': %s."),
fh_get_file_name (r->fh), strerror (errno));
/* This was the last client, so close the underlying file. */
if (fh_get_referent (r->fh) != FH_REF_INLINE)
- fn_close (fh_get_file_name (r->fh), r->file);
+ fn_close (r->fh, r->file);
else
{
/* Skip any remaining data on the inline file. */
{
struct stat s;
r->line_number = 0;
- r->file = fn_open (fh_get_file_name (fh), "rb");
+ r->file = fn_open (fh, "rb");
if (r->file == NULL)
{
msg (ME, _("Could not open `%s' for reading as a data file: %s."),
if (w->file != NULL)
{
const char *file_name = fh_get_file_name (w->fh);
- ok = !dfm_write_error (w) && !fn_close (file_name, w->file);
+ ok = !dfm_write_error (w) && !fn_close (w->fh, w->file);
if (!ok)
msg (ME, _("I/O error occurred writing data file `%s'."), file_name);
lex_sbc_missing ("OUTFILE");
goto error;
}
- else if (!replace && fn_exists (fh_get_file_name (handle)))
+ else if (!replace && fn_exists (handle))
{
msg (SE, _("Output file `%s' exists but %s was not specified."),
fh_get_file_name (handle), "REPLACE");
#include <uniwidth.h>
#include "data/file-name.h"
+#include "data/file-handle-def.h"
#include "data/settings.h"
#include "libpspp/assertion.h"
#include "libpspp/cast.h"
char *command_name;
char *title;
char *subtitle;
- char *file_name; /* Output file name. */
+ struct file_handle *handle;
FILE *file; /* Output file. */
bool error; /* Output error? */
int page_number; /* Current page number. */
}
static struct output_driver *
-ascii_create (const char *file_name, enum settings_output_devices device_type,
+ascii_create (struct file_handle *fh, enum settings_output_devices device_type,
struct string_map *o)
{
enum { BOX_ASCII, BOX_UNICODE } box;
a = xzalloc (sizeof *a);
d = &a->driver;
- output_driver_init (&a->driver, &ascii_driver_class, file_name, device_type);
+ output_driver_init (&a->driver, &ascii_driver_class, fh_get_file_name (fh), device_type);
a->append = parse_boolean (opt (d, o, "append", "false"));
a->headers = parse_boolean (opt (d, o, "headers", "false"));
a->paginate = parse_boolean (opt (d, o, "paginate", "false"));
"none", EMPH_NONE,
NULL_SENTINEL);
- a->chart_file_name = parse_chart_file_name (opt (d, o, "charts", file_name));
+ a->chart_file_name = parse_chart_file_name (opt (d, o, "charts", fh_get_file_name (fh)));
+ a->handle = fh;
a->top_margin = parse_int (opt (d, o, "top-margin", "0"), 0, INT_MAX);
a->bottom_margin = parse_int (opt (d, o, "bottom-margin", "0"), 0, INT_MAX);
a->command_name = NULL;
a->title = xstrdup ("");
a->subtitle = xstrdup ("");
- a->file_name = xstrdup (file_name);
a->file = NULL;
a->error = false;
a->page_number = 0;
ascii_close_page (a);
if (a->file != NULL)
- fn_close (a->file_name, a->file);
+ fn_close (a->handle, a->file);
+ fh_unref (a->handle);
free (a->command_name);
free (a->title);
free (a->subtitle);
- free (a->file_name);
free (a->chart_file_name);
for (i = 0; i < a->allocated_lines; i++)
u8_line_destroy (&a->lines[i]);
{
ascii_close_page (a);
- if (fn_close (a->file_name, a->file) != 0)
- msg_error (errno, _("ascii: closing output file `%s'"), a->file_name);
+ if (fn_close (a->handle, a->file) != 0)
+ msg_error (errno, _("ascii: closing output file `%s'"), fh_get_file_name (a->handle));
a->file = NULL;
}
}
if (a->file == NULL)
{
- a->file = fn_open (a->file_name, a->append ? "a" : "w");
+ a->file = fn_open (a->handle, a->append ? "a" : "w");
if (a->file != NULL)
{
if ( isatty (fileno (a->file)))
else
{
msg_error (errno, _("ascii: opening output file `%s'"),
- a->file_name);
+ fh_get_file_name (a->handle));
a->error = true;
return false;
}
#include "libpspp/str.h"
#include "libpspp/string-map.h"
#include "libpspp/version.h"
+#include "data/file-handle-def.h"
#include "output/cairo-chart.h"
#include "output/chart-item-provider.h"
#include "output/charts/boxplot.h"
}
static struct output_driver *
-xr_pdf_create (const char *file_name, enum settings_output_devices device_type,
+xr_pdf_create (struct file_handle *fh, enum settings_output_devices device_type,
struct string_map *o)
{
- return xr_create (file_name, device_type, o, XR_PDF);
+ struct output_driver *od = xr_create (fh_get_file_name (fh), device_type, o, XR_PDF);
+ fh_unref (fh);
+ return od ;
}
static struct output_driver *
-xr_ps_create (const char *file_name, enum settings_output_devices device_type,
+xr_ps_create (struct file_handle *fh, enum settings_output_devices device_type,
struct string_map *o)
{
- return xr_create (file_name, device_type, o, XR_PS);
+ struct output_driver *od = xr_create (fh_get_file_name (fh), device_type, o, XR_PS);
+ fh_unref (fh);
+ return od ;
}
static struct output_driver *
-xr_svg_create (const char *file_name, enum settings_output_devices device_type,
+xr_svg_create (struct file_handle *fh, enum settings_output_devices device_type,
struct string_map *o)
{
- return xr_create (file_name, device_type, o, XR_SVG);
+ struct output_driver *od = xr_create (fh_get_file_name (fh), device_type, o, XR_SVG);
+ fh_unref (fh);
+ return od ;
}
static void
#include <stdlib.h>
#include "data/file-name.h"
+#include "data/file-handle-def.h"
#include "libpspp/assertion.h"
#include "libpspp/compiler.h"
#include "libpspp/message.h"
bool titles; /* Print table titles? */
bool captions; /* Print table captions? */
- char *file_name; /* Output file name. */
+ struct file_handle *handle;
char *command_name; /* Current command. */
FILE *file; /* Output file. */
int n_items; /* Number of items output so far. */
}
static struct output_driver *
-csv_create (const char *file_name, enum settings_output_devices device_type,
+csv_create (struct file_handle *fh, enum settings_output_devices device_type,
struct string_map *o)
{
struct output_driver *d;
csv = xzalloc (sizeof *csv);
d = &csv->driver;
- output_driver_init (&csv->driver, &csv_driver_class, file_name, device_type);
+ output_driver_init (&csv->driver, &csv_driver_class, fh_get_file_name (fh), device_type);
csv->separator = parse_string (opt (d, o, "separator", ","));
quote = parse_string (opt (d, o, "quote", "\""));
csv->quote_set = xasprintf ("\n\r\t%s%c", csv->separator, csv->quote);
csv->titles = parse_boolean (opt (d, o, "titles", "true"));
csv->captions = parse_boolean (opt (d, o, "captions", "true"));
- csv->file_name = xstrdup (file_name);
- csv->file = fn_open (csv->file_name, "w");
+ csv->handle = fh;
+ csv->file = fn_open (fh, "w");
csv->n_items = 0;
if (csv->file == NULL)
{
- msg_error (errno, _("error opening output file `%s'"), csv->file_name);
+ msg_error (errno, _("error opening output file `%s'"), fh_get_file_name (fh));
output_driver_destroy (d);
return NULL;
}
struct csv_driver *csv = csv_driver_cast (driver);
if (csv->file != NULL)
- fn_close (csv->file_name, csv->file);
+ fn_close (csv->handle, csv->file);
free (csv->separator);
free (csv->quote_set);
- free (csv->file_name);
+ fh_unref (csv->handle);
free (csv);
}
struct output_item;
struct string_map;
+struct file_handle;
/* A configured output driver. */
struct output_driver
void output_driver_init (struct output_driver *,
const struct output_driver_class *,
- const char *name, enum settings_output_devices);
+ const char *, enum settings_output_devices);
+
void output_driver_destroy (struct output_driver *);
const char *output_driver_get_name (const struct output_driver *);
The returned driver should not have been registered (with
output_driver_register). The caller will register the driver (if this
is desirable). */
- struct output_driver *(*create) (const char *name,
+ struct output_driver *(*create) (struct file_handle *,
enum settings_output_devices type,
struct string_map *options);
};
#include <stdlib.h>
#include <string.h>
+#include "data/file-handle-def.h"
#include "data/settings.h"
#include "libpspp/array.h"
#include "libpspp/assertion.h"
device_string, "terminal", "listing");
device_type = default_device_type (file_name);
}
+
+ struct file_handle *fh = fh_create_file (NULL, file_name, NULL, fh_default_properties ());
- driver = f->create (file_name, device_type, options);
+ driver = f->create (fh, device_type, options);
if (driver != NULL)
{
const struct string_map_node *node;
#include <unistd.h>
#include "data/file-name.h"
+#include "data/file-handle-def.h"
#include "libpspp/assertion.h"
#include "libpspp/cast.h"
#include "libpspp/compiler.h"
struct xr_color fg;
struct xr_color bg;
#endif
- char *file_name;
+ struct file_handle *handle;
char *chart_file_name;
char *command_name;
}
static struct output_driver *
-html_create (const char *file_name, enum settings_output_devices device_type,
+html_create (struct file_handle *fh, enum settings_output_devices device_type,
struct string_map *o)
{
struct output_driver *d;
html = xzalloc (sizeof *html);
d = &html->driver;
- output_driver_init (&html->driver, &html_driver_class, file_name,
+ output_driver_init (&html->driver, &html_driver_class, fh_get_file_name (fh),
device_type);
html->css = parse_boolean (opt (d, o, "css", "true"));
html->borders = parse_boolean (opt (d, o, "borders", "true"));
- html->file_name = xstrdup (file_name);
+ html->handle = fh;
html->chart_file_name = parse_chart_file_name (opt (d, o, "charts",
- file_name));
+ fh_get_file_name (fh)));
html->file = NULL;
html->chart_cnt = 1;
#ifdef HAVE_CAIRO
parse_color (d, o, "background-color", "#FFFFFFFFFFFF", &html->bg);
parse_color (d, o, "foreground-color", "#000000000000", &html->fg);
#endif
- html->file = fn_open (html->file_name, "w");
+ html->file = fn_open (html->handle, "w");
if (html->file == NULL)
{
- msg_error (errno, _("error opening output file `%s'"), html->file_name);
+ msg_error (errno, _("error opening output file `%s'"), fh_get_file_name (html->handle));
goto error;
}
"</BODY>\n"
"</HTML>\n"
"<!-- end of file -->\n");
- fn_close (html->file_name, html->file);
+ fn_close (html->handle, html->file);
}
free (html->chart_file_name);
- free (html->file_name);
+ fh_unref (html->handle);
free (html->command_name);
free (html);
}
#include <unistd.h>
#include "data/file-name.h"
+#include "data/file-handle-def.h"
#include "data/settings.h"
#include "libpspp/cast.h"
#include "libpspp/message.h"
{
struct output_driver driver;
FILE *file;
- char *file_name;
+ struct file_handle *handle;
char *command_name;
};
struct msglog_driver *ml;
FILE *file;
- file = fn_open (file_name, "w");
+ struct file_handle *handle = fh_create_file (NULL, file_name, NULL, fh_default_properties ());
+
+ file = fn_open (handle, "w");
if (file == NULL)
{
msg_error (errno, _("error opening output file `%s'"), file_name);
: SETTINGS_DEVICE_UNFILTERED);
ml = xzalloc (sizeof *ml);
+ ml->handle = handle;
output_driver_init (&ml->driver, &msglog_class, file_name, type);
ml->file = file;
- ml->file_name = xstrdup (file_name);
ml->command_name = NULL;
output_driver_register (&ml->driver);
{
struct msglog_driver *ml = msglog_driver_cast (driver);
- fn_close (ml->file_name, ml->file);
- free (ml->file_name);
+ fn_close (ml->handle, ml->file);
free (ml->command_name);
+ fh_unref (ml->handle);
free (ml);
}
#include "libpspp/temp-file.h"
#include "libpspp/version.h"
#include "libpspp/zip-writer.h"
+#include "data/file-handle-def.h"
#include "output/driver-provider.h"
#include "output/message-item.h"
#include "output/options.h"
}
static struct output_driver *
-odt_create (const char *file_name, enum settings_output_devices device_type,
+odt_create (struct file_handle *fh, enum settings_output_devices device_type,
struct string_map *o UNUSED)
{
struct output_driver *d;
struct odt_driver *odt;
struct zip_writer *zip;
+ const char *file_name = fh_get_file_name (fh);
zip = zip_writer_create (file_name);
if (zip == NULL)
odt = xzalloc (sizeof *odt);
d = &odt->driver;
+
output_driver_init (d, &odt_driver_class, file_name, device_type);
odt->zip = zip;
#define N_(msgid) msgid
#include "data/any-reader.h"
+#include "data/file-handle-def.h"
#include "data/dataset.h"
#include "libpspp/version.h"
gchar *name =
gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
- gchar *sysname = convert_glib_filename_to_system_filename (name, NULL);
+ const gchar **cs = NULL;
+ g_get_filename_charsets (&cs);
gchar *encoding = psppire_encoding_selector_get_encoding (
gtk_file_chooser_get_extra_widget (GTK_FILE_CHOOSER (dialog)));
- int retval = any_reader_detect (sysname, NULL);
+ struct file_handle *fh = fh_create_file (NULL, name, cs[0], fh_default_properties ());
+
+ int retval = any_reader_detect (fh, NULL);
if (retval == 1)
open_data_window (de, name, encoding, NULL);
else if (retval == 0)
open_syntax_window (name, encoding);
g_free (encoding);
- g_free (sysname);
+ fh_unref (fh);
g_free (name);
}
break;
#include "gl/relocatable.h"
static void create_icon_factory (void);
-static gchar *local_to_filename_encoding (const char *fn);
-
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
{
if (is->file)
{
- gchar *filename = local_to_filename_encoding (is->file);
+ const gchar *local_encoding = NULL;
+ g_get_charset (&local_encoding);
+
+ struct file_handle *fh = fh_create_file (NULL, is->file, local_encoding, fh_default_properties ());
+ const char *filename = fh_get_file_name (fh);
- int retval = any_reader_detect (filename, NULL);
+ int retval = any_reader_detect (fh, NULL);
/* Check to see if the file is a .sav or a .por file. If not
assume that it is a syntax file */
create_data_window ();
open_syntax_window (filename, NULL);
}
- g_free (filename);
+
+ fh_unref (fh);
}
else
{
gtk_icon_factory_add_default (factory);
}
-\f
-/*
- Convert a filename from the local encoding into "filename" encoding.
- The return value will be allocated on the heap. It is the responsibility
- of the caller to free it.
- */
-static gchar *
-local_to_filename_encoding (const char *fn)
-{
- gchar *filename = NULL;
- gchar *utf8 = NULL;
- const gchar *local_encoding = NULL;
- gsize written = -1;
- const gboolean local_is_utf8 = g_get_charset (&local_encoding);
-
- /* There seems to be no Glib function to convert from local encoding
- to filename encoding. Therefore it has to be done in two steps:
- the intermediate encoding is UTF8.
-
- Either step could fail. However, in many cases the file can still
- be loaded even if the conversion fails. So in those cases, after showing
- a warning, we simply copy the locally encoded filename to the destination
- and hope for the best.
- */
-
- if ( local_is_utf8)
- {
- utf8 = xstrdup (fn);
- }
- else
- {
- GError *err = NULL;
- utf8 = g_locale_to_utf8 (fn, -1, NULL, &written, &err);
- if ( NULL == utf8)
- {
- g_warning ("Cannot convert filename from local encoding `%s' to UTF-8: %s",
- local_encoding,
- err->message);
- g_clear_error (&err);
- }
- }
-
- if ( NULL != utf8)
- {
- GError *err = NULL;
- filename = g_filename_from_utf8 (utf8, written, NULL, NULL, &err);
- if ( NULL == filename)
- {
- g_warning ("Cannot convert filename from UTF8 to filename encoding: %s",
- err->message);
- g_clear_error (&err);
- }
- }
- g_free (utf8);
-
- if ( filename == NULL)
- filename = xstrdup (fn);
-
- return filename;
-}
+\f
static void
handle_msg (const struct msg *m_, void *lexer_)
static void usage (void);
static void decrypt_file (struct encrypted_file *enc,
- const char *input_filename,
- const char *output_filename,
+ const struct file_handle *input_filename,
+ const struct file_handle *output_filename,
const char *password);
int
input_filename = argv[optind];
output_filename = argv[optind + 1];
+ input_fh = fh_create_file (NULL, input_filename, NULL, fh_default_properties ());
+
if (output_format == NULL)
{
const char *dot = strrchr (output_filename, '.');
output_format = dot + 1;
}
- if (encrypted_file_open (&enc, input_filename) > 0)
+ output_fh = fh_create_file (NULL, output_filename, NULL, fh_default_properties ());
+ if (encrypted_file_open (&enc, input_fh) > 0)
{
if (encrypted_file_is_sav (enc))
{
"format"));
}
- decrypt_file (enc, input_filename, output_filename, password);
+ decrypt_file (enc, input_fh, output_fh, password);
goto exit;
}
- input_fh = fh_create_file (NULL, input_filename, NULL, fh_default_properties ());
+
reader = any_reader_open_and_decode (input_fh, encoding, &dict, NULL);
if (reader == NULL)
exit (1);
- output_fh = fh_create_file (NULL, output_filename, NULL, fh_default_properties ());
+
if (!strcmp (output_format, "csv") || !strcmp (output_format, "txt"))
{
struct csv_writer_options options;
static void
decrypt_file (struct encrypted_file *enc,
- const char *input_filename,
- const char *output_filename,
+ const struct file_handle *ifh,
+ const struct file_handle *ofh,
const char *password)
{
FILE *out;
int err;
+ const char *input_filename = fh_get_file_name (ifh);
+ const char *output_filename = fh_get_file_name (ofh);
if (password == NULL)
{
if (!encrypted_file_unlock (enc, password))
error (1, 0, _("sorry, wrong password"));
- out = fn_open (output_filename, "wb");
+ out = fn_open (ofh, "wb");
if (out == NULL)
error (1, errno, ("%s: error opening output file"), output_filename);
if (fflush (out) == EOF)
error (1, errno, ("%s: write error"), output_filename);
- fn_close (output_filename, out);
+ fn_close (ofh, out);
}
static void