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.1 2012/02/03 19:49:57 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\
84 PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME, PROGRAM_NAME);
88 -d - Calculate message digest of input file\n\
89 -g - Generate a random 16 byte value to stdout\n\
90 -h | -help - Show help\n\
91 -u - Generate a random UUID value to stdout\n\
92 -V - Show version information\n\
94 NOTES: o There is no option grouping, all options must be distinct arguments.\n\
95 o All option arguments must be separated from the option by whitespace.\n\n");
114 bool error_flag; // true if the given options are in error or not complete
115 bool version_flag; // true if the version display option was selected
116 bool help_flag; // true if the help display option was selected
117 PathList_t filenames; // list of filenames to be processed
120 CommandOptions(int argc, const char** argv) :
121 mode(MMT_NONE), error_flag(true), version_flag(false), help_flag(false)
123 for ( int i = 1; i < argc; ++i )
126 if ( (strcmp( argv[i], "-help") == 0) )
132 if ( argv[i][0] == '-'
133 && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) )
136 switch ( argv[i][1] )
138 case 'd': mode = MMT_DIGEST; break;
139 case 'g': mode = MMT_GEN_KEY; break;
140 case 'h': help_flag = true; break;
141 case 'u': mode = MMT_GEN_ID; break;
142 case 'V': version_flag = true; break;
145 fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
151 if ( argv[i][0] != '-' )
153 filenames.push_back(argv[i]);
157 fprintf(stderr, "Unrecognized argument: %s\n", argv[i]);
163 if ( help_flag || version_flag )
166 if ( ( mode == MMT_DIGEST ) && filenames.empty() )
168 fputs("Option requires at least one filename argument.\n", stderr);
172 if ( mode == MMT_NONE && ! help_flag && ! version_flag )
174 fputs("No operation selected (use one of -[dgu] or -h for help).\n", stderr);
184 digest_file(const std::string& filename)
189 ByteString Buf(8192);
191 Result_t result = Reader.OpenRead(filename.c_str());
193 while ( ASDCP_SUCCESS(result) )
195 ui32_t read_count = 0;
196 result = Reader.Read(Buf.Data(), Buf.Capacity(), &read_count);
198 if ( result == RESULT_ENDOFFILE )
204 if ( ASDCP_SUCCESS(result) )
205 SHA1_Update(&Ctx, Buf.Data(), read_count);
208 if ( ASDCP_SUCCESS(result) )
210 const ui32_t sha_len = 20;
211 byte_t bin_buf[sha_len];
213 SHA1_Final(bin_buf, &Ctx);
215 fprintf(stdout, "%s %s\n",
216 base64encode(bin_buf, sha_len, sha_buf, 64),
225 main(int argc, const char** argv)
227 Result_t result = RESULT_OK;
229 CommandOptions Options(argc, argv);
231 if ( Options.version_flag )
234 if ( Options.help_flag )
237 if ( Options.version_flag || Options.help_flag )
240 if ( Options.error_flag )
242 fprintf(stderr, "There was a problem. Type %s -h for help.\n",
247 if ( Options.mode == MMT_GEN_KEY )
249 Kumu::FortunaRNG RNG;
250 byte_t bin_buf[ASDCP::KeyLen];
252 RNG.FillRandom(bin_buf, ASDCP::KeyLen);
253 printf("%s\n", Kumu::bin2hex(bin_buf, ASDCP::KeyLen, str_buf, 64));
255 else if ( Options.mode == MMT_GEN_ID )
258 Kumu::GenRandomValue(TmpID);
259 printf("%s\n", TmpID.EncodeHex(str_buf, 64));
261 else if ( Options.mode == MMT_DIGEST )
263 PathList_t::iterator i;
265 for ( i = Options.filenames.begin();
266 i != Options.filenames.end() && ASDCP_SUCCESS(result); ++i )
267 result = digest_file(*i);
271 fprintf(stderr, "Unhandled mode: %d.\n", Options.mode);
275 if ( ASDCP_FAILURE(result) )
277 fputs("Program stopped on error.\n", stderr);
279 if ( result != RESULT_FAIL )
281 fputs(result, stderr);
293 // end asdcp-util.cpp