2 Copyright (c) 2003-2012, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 /*! \file asdcp-util.cpp
28 \version $Id: asdcp-util.cpp,v 1.3 2015/05/21 00:10:39 jhurst Exp $
29 \brief Utility functions for working with AS-DCP files
31 This program provides utility features commonly useful in DCP workflows.
33 For more information about asdcplib, please refer to the header file AS_DCP.h
36 #include <KM_fileio.h>
39 #include <openssl/sha.h>
44 //------------------------------------------------------------------------------------------
46 // command line option parser class
48 static const char* PROGRAM_NAME = "asdcp-util"; // program name for messages
50 // Increment the iterator, test for an additional non-option command line argument.
51 // Causes the caller to return if there are no remaining arguments or if the next
52 // argument begins with '-'.
53 #define TEST_EXTRA_ARG(i,c) \
54 if ( ++i >= argc || argv[(i)][0] == '-' ) { \
55 fprintf(stderr, "Argument not found for option -%c.\n", (c)); \
61 banner(FILE* stream = stdout)
65 Copyright (c) 2003-2012 John Hurst\n\n\
66 asdcplib may be copied only under the terms of the license found at\n\
67 the top of every file in the asdcplib distribution kit.\n\n\
68 Specify the -h (help) option for further information about %s\n\n",
69 PROGRAM_NAME, ASDCP::Version(), PROGRAM_NAME);
74 usage(FILE* stream = stdout)
77 USAGE: %s [-h|-help] [-V]\n\
82 PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME);
86 -d - Calculate message digest of input file\n\
87 -g - Generate a random 16 byte value to stdout\n\
88 -h | -help - Show help\n\
89 -u - Generate a random UUID value to stdout\n\
90 -V - Show version information\n\
92 NOTES: o There is no option grouping, all options must be distinct arguments.\n\
93 o All option arguments must be separated from the option by whitespace.\n\n");
112 bool error_flag; // true if the given options are in error or not complete
113 bool version_flag; // true if the version display option was selected
114 bool help_flag; // true if the help display option was selected
115 PathList_t filenames; // list of filenames to be processed
118 CommandOptions(int argc, const char** argv) :
119 mode(MMT_NONE), error_flag(true), version_flag(false), help_flag(false)
121 for ( int i = 1; i < argc; ++i )
124 if ( (strcmp( argv[i], "-help") == 0) )
130 if ( argv[i][0] == '-'
131 && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) )
134 switch ( argv[i][1] )
136 case 'd': mode = MMT_DIGEST; break;
137 case 'g': mode = MMT_GEN_KEY; break;
138 case 'h': help_flag = true; break;
139 case 'u': mode = MMT_GEN_ID; break;
140 case 'V': version_flag = true; break;
143 fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
149 if ( argv[i][0] != '-' )
151 filenames.push_back(argv[i]);
155 fprintf(stderr, "Unrecognized argument: %s\n", argv[i]);
161 if ( help_flag || version_flag )
164 if ( ( mode == MMT_DIGEST ) && filenames.empty() )
166 fputs("Option requires at least one filename argument.\n", stderr);
170 if ( mode == MMT_NONE && ! help_flag && ! version_flag )
172 fputs("No operation selected (use one of -[dgu] or -h for help).\n", stderr);
182 digest_file(const std::string& filename)
187 ByteString Buf(8192);
189 Result_t result = Reader.OpenRead(filename.c_str());
191 while ( ASDCP_SUCCESS(result) )
193 ui32_t read_count = 0;
194 result = Reader.Read(Buf.Data(), Buf.Capacity(), &read_count);
196 if ( result == RESULT_ENDOFFILE )
202 if ( ASDCP_SUCCESS(result) )
203 SHA1_Update(&Ctx, Buf.Data(), read_count);
206 if ( ASDCP_SUCCESS(result) )
208 const ui32_t sha_len = 20;
209 byte_t bin_buf[sha_len];
211 SHA1_Final(bin_buf, &Ctx);
213 fprintf(stdout, "%s %s\n",
214 base64encode(bin_buf, sha_len, sha_buf, 64),
223 main(int argc, const char** argv)
225 Result_t result = RESULT_OK;
227 CommandOptions Options(argc, argv);
229 if ( Options.version_flag )
232 if ( Options.help_flag )
235 if ( Options.version_flag || Options.help_flag )
238 if ( Options.error_flag )
240 fprintf(stderr, "There was a problem. Type %s -h for help.\n",
245 if ( Options.mode == MMT_GEN_KEY )
247 Kumu::FortunaRNG RNG;
248 byte_t bin_buf[ASDCP::KeyLen];
250 RNG.FillRandom(bin_buf, ASDCP::KeyLen);
251 printf("%s\n", Kumu::bin2hex(bin_buf, ASDCP::KeyLen, str_buf, 64));
253 else if ( Options.mode == MMT_GEN_ID )
256 Kumu::GenRandomValue(TmpID);
257 printf("%s\n", TmpID.EncodeHex(str_buf, 64));
259 else if ( Options.mode == MMT_DIGEST )
261 PathList_t::iterator i;
263 for ( i = Options.filenames.begin();
264 i != Options.filenames.end() && ASDCP_SUCCESS(result); ++i )
265 result = digest_file(*i);
269 fprintf(stderr, "Unhandled mode: %d.\n", Options.mode);
273 if ( ASDCP_FAILURE(result) )
275 fputs("Program stopped on error.\n", stderr);
277 if ( result != RESULT_FAIL )
279 fputs(result, stderr);
291 // end asdcp-util.cpp