X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utilities%2Fpspp-convert.c;h=ebd340ec3599e3cf942fa0e015a09d51c4c10e56;hb=refs%2Fheads%2Fpivot-table2;hp=233bfbffbf6691b927720770e49cc36886e6cd34;hpb=02a682272552710b1c4c869db3fea1d83b0eb3a7;p=pspp diff --git a/utilities/pspp-convert.c b/utilities/pspp-convert.c index 233bfbffbf..ebd340ec35 100644 --- a/utilities/pspp-convert.c +++ b/utilities/pspp-convert.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2013 Free Software Foundation, Inc. + Copyright (C) 2013, 2014 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,16 +16,20 @@ #include +#include #include #include #include +#include #include "data/any-reader.h" #include "data/casereader.h" #include "data/casewriter.h" #include "data/csv-file-writer.h" +#include "data/file-name.h" #include "data/por-file-writer.h" #include "data/settings.h" +#include "data/sys-file-encryption.h" #include "data/sys-file-writer.h" #include "data/file-handle-def.h" #include "libpspp/assertion.h" @@ -33,6 +37,7 @@ #include "libpspp/i18n.h" #include "gl/error.h" +#include "gl/getpass.h" #include "gl/progname.h" #include "gl/version-etc.h" @@ -41,21 +46,28 @@ static void usage (void); +static void decrypt_sav_file (struct encrypted_sys_file *enc, + const char *input_filename, + const char *output_filename, + const char *password); + int main (int argc, char *argv[]) { const char *input_filename; const char *output_filename; - struct fh_properties properties; long long int max_cases = LLONG_MAX; struct dictionary *dict; struct casereader *reader; struct file_handle *input_fh; + const char *encoding = NULL; + struct encrypted_sys_file *enc; const char *output_format = NULL; struct file_handle *output_fh; struct casewriter *writer; + const char *password = NULL; long long int i; @@ -64,13 +76,13 @@ main (int argc, char *argv[]) fh_init (); settings_init (); - properties = *fh_default_properties (); for (;;) { static const struct option long_options[] = { { "cases", required_argument, NULL, 'c' }, { "encoding", required_argument, NULL, 'e' }, + { "password", required_argument, NULL, 'p' }, { "output-format", required_argument, NULL, 'O' }, @@ -81,7 +93,7 @@ main (int argc, char *argv[]) int c; - c = getopt_long (argc, argv, "c:e:O:hv", long_options, NULL); + c = getopt_long (argc, argv, "c:e:p:O:hv", long_options, NULL); if (c == -1) break; @@ -92,7 +104,11 @@ main (int argc, char *argv[]) break; case 'e': - properties.encoding = optarg; + encoding = optarg; + break; + + case 'p': + password = optarg; break; case 'O': @@ -129,8 +145,18 @@ main (int argc, char *argv[]) output_format = dot + 1; } - input_fh = fh_create_file (NULL, input_filename, &properties); - reader = any_reader_open (input_fh, properties.encoding, &dict); + if (encrypted_sys_file_open (&enc, input_filename) > 0) + { + if (strcmp (output_format, "sav") && strcmp (output_format, "sys")) + error (1, 0, _("can only convert encrypted data file to sav or sys " + "format")); + + decrypt_sav_file (enc, input_filename, output_filename, password); + goto exit; + } + + input_fh = fh_create_file (NULL, input_filename, fh_default_properties ()); + reader = any_reader_open_and_decode (input_fh, encoding, &dict, NULL); if (reader == NULL) exit (1); @@ -180,12 +206,58 @@ main (int argc, char *argv[]) if (!casewriter_destroy (writer)) error (1, 0, _("%s: error writing output file"), output_filename); +exit: fh_done (); i18n_done (); return 0; } +static void +decrypt_sav_file (struct encrypted_sys_file *enc, + const char *input_filename, + const char *output_filename, + const char *password) +{ + FILE *out; + int err; + + if (password == NULL) + { + password = getpass ("password: "); + if (password == NULL) + exit (1); + } + + if (!encrypted_sys_file_unlock (enc, password)) + error (1, 0, _("sorry, wrong password")); + + out = fn_open (output_filename, "wb"); + if (out == NULL) + error (1, errno, ("%s: error opening output file"), output_filename); + + for (;;) + { + uint8_t buffer[1024]; + size_t n; + + n = encrypted_sys_file_read (enc, buffer, sizeof buffer); + if (n == 0) + break; + + if (fwrite (buffer, 1, n, out) != n) + error (1, errno, ("%s: write error"), output_filename); + } + + err = encrypted_sys_file_close (enc); + if (err) + error (1, err, ("%s: read error"), input_filename); + + if (fflush (out) == EOF) + error (1, errno, ("%s: write error"), output_filename); + fn_close (output_filename, out); +} + static void usage (void) { @@ -205,6 +277,7 @@ Options:\n\ is one of the extensions listed above\n\ -e, --encoding=CHARSET override encoding of input data file\n\ -c MAXCASES limit number of cases to copy (default is all cases)\n\ + -p PASSWORD password for encrypted .sav files\n\ --help display this help and exit\n\ --version output version information and exit\n", program_name, program_name);