| 904 | } |
| 905 | |
| 906 | int diff (int argc, const char** argv) |
| 907 | { |
| 908 | const char* key_name = 0; |
| 909 | const char* key_path = 0; |
| 910 | const char* filename = 0; |
| 911 | const char* legacy_key_path = 0; |
| 912 | |
| 913 | int argi = parse_plumbing_options(&key_name, &key_path, argc, argv); |
| 914 | if (argc - argi == 1) { |
| 915 | filename = argv[argi]; |
| 916 | } else if (!key_name && !key_path && argc - argi == 2) { // Deprecated - for compatibility with pre-0.4 |
| 917 | legacy_key_path = argv[argi]; |
| 918 | filename = argv[argi + 1]; |
| 919 | } else { |
| 920 | std::clog << "Usage: git-crypt diff [--key-name=NAME] [--key-file=PATH] FILENAME" << std::endl; |
| 921 | return 2; |
| 922 | } |
| 923 | Key_file key_file; |
| 924 | load_key(key_file, key_name, key_path, legacy_key_path); |
| 925 | |
| 926 | // Open the file |
| 927 | std::ifstream in(filename, std::fstream::binary); |
| 928 | if (!in) { |
| 929 | std::clog << "git-crypt: " << filename << ": unable to open for reading" << std::endl; |
| 930 | return 1; |
| 931 | } |
| 932 | in.exceptions(std::fstream::badbit); |
| 933 | |
| 934 | // Read the header to get the nonce and determine if it's actually encrypted |
| 935 | unsigned char header[10 + Aes_ctr_decryptor::NONCE_LEN]; |
| 936 | in.read(reinterpret_cast<char*>(header), sizeof(header)); |
| 937 | if (in.gcount() != sizeof(header) || std::memcmp(header, "\0GITCRYPT\0", 10) != 0) { |
| 938 | // File not encrypted - just copy it out to stdout |
| 939 | std::cout.write(reinterpret_cast<char*>(header), in.gcount()); // include the bytes which we already read |
| 940 | std::cout << in.rdbuf(); |
| 941 | return 0; |
| 942 | } |
| 943 | |
| 944 | // Go ahead and decrypt it |
| 945 | return decrypt_file_to_stdout(key_file, header, in); |
| 946 | } |
| 947 | |
| 948 | void help_init (std::ostream& out) |
| 949 | { |
no test coverage detected