irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

irods_parse_command_line_options.cpp
Go to the documentation of this file.
1 #include "getRodsEnv.h"
3 #include "boost/program_options.hpp"
4 #include "boost/filesystem.hpp"
5 #include "rodsErrorTable.h"
6 #include "rcMisc.h"
7 namespace fs = boost::filesystem;
8 
9 #include <vector>
10 #include <string>
11 #include <iostream>
12 
13 typedef std::vector< std::string > path_list_t;
14 
15 // this is global due to the fact that the storage of the
16 // various strings used by _rods_args is managed by the
17 // lifetime of this map - only used by icommand client execs
18 static boost::program_options::variables_map global_prog_ops_var_map;
19 
20 // currently only written to support iput. needs to be expanded to
21 // support the full range of icommand options
23  int _argc,
24  char** _argv,
25  rodsArguments_t& _rods_args,
26  path_list_t& _paths ) {
27  namespace po = boost::program_options;
28 
29  po::options_description opt_desc( "options" );
30  opt_desc.add_options()
31  ( "help,h", "show command usage" )
32  ( "all,a", "all - update all existing copies" )
33  ( "bulk,b", "bulk upload to reduce overhead" )
34  ( "force,f", "force - write data-object even it exists already; overwrite it" )
35  ( "redirect,I", "redirect connection - redirect the connection to connect directly to the resource server." )
36  ( "checksum,k", "checksum - calculate a checksum on the data server-side, and store it in the catalog" )
37  ( "verify_checksum,K", "verify checksum - calculate and verify the checksum on the data, both client-side and server-side, without storing in the catalog." )
38  ( "repl_num,n", po::value<std::string>(), "replNum - the replica to be replaced, typically not needed" )
39  ( "num_threads,N", po::value<int>(), "numThreads - the number of threads to use for the transfer. A value of 0 means no threading. By default (-N option not used) the server decides the number of threads to use." )
40  ( "physical_path,p", po::value<std::string>(), "physicalPath - the absolute physical path of the uploaded file on the server" )
41  ( "progress,P", "output the progress of the upload." )
42  ( "rbudp,Q", "use RBUDP (datagram) protocol for the data transfer" )
43  ( "recursive,r", "recursive - store the whole subdirectory" )
44  ( "dest_resc,R", po::value<std::string>(), "resource - specifies the resource to store to. This can also be specified in your environment or via a rule set up by the administrator" )
45  ( "ticket,t", po::value<std::string>(), "ticket - ticket (string) to use for ticket-based access" )
46  ( "renew_socket,T", "renew socket connection after 10 minutes" )
47  ( "verbose,v", "verbose" )
48  ( "very_verbose,V", "very verbose" )
49  ( "data_type,D", po::value<std::string>(), "dataType - the data type string" )
50  ( "restart_file,X", po::value<std::string>(), "restartFile - specifies that the restart option is on and the restartFile input specifies a local file that contains the restart information." )
51  ( "link", "ignore symlink." )
52  ( "lfrestart", po::value<std::string>(), "lfRestartFile - specifies that the large file restart option is on and the lfRestartFile input specifies a local file that contains the restart information." )
53  ( "retries", po::value<int>(), "count - Retry the iput in case of error. The 'count' input specifies the number of times to retry. It must be used with the -X option" )
54  ( "wlock", "use advisory write (exclusive) lock for the upload" )
55  ( "rlock", "use advisory read lock for the download" )
56  ( "purgec", "Purge the staged cache copy after uploading an object to a" )
57  ( "kv_pass", po::value<std::string>(), "pass key-value strings through to the plugin infrastructure" )
58  ( "metadata", po::value<std::string>(), "atomically assign metadata after a data object is put" )
59  ( "acl", po::value<std::string>(), "atomically apply an access control list after a data object is put" )
60  ( "path_args", po::value<path_list_t>( &_paths )->composing(), "some files and stuffs" );
61 
62  po::positional_options_description pos_desc;
63  pos_desc.add( "path_args", -1 );
64 
65  try {
66  po::store(
67  po::command_line_parser(
68  _argc, _argv ).options(
69  opt_desc ).positional(
70  pos_desc ).run(), global_prog_ops_var_map );
71  po::notify( global_prog_ops_var_map );
72  }
73  catch ( po::error& _e ) {
74  std::cout << std::endl
75  << "Error: "
76  << _e.what()
77  << std::endl
78  << std::endl;
80 
81  }
82 
83  bool have_verify = global_prog_ops_var_map.count( "verify_checksum" ) > 0;
84  bool have_stdout = _paths.end() !=
85  std::find(
86  _paths.begin(),
87  _paths.end(),
88  std::string( STDOUT_FILE_NAME ) );
89  if ( have_verify && have_stdout ) {
90  std::cerr << "Cannot verify checksum if data is piped to stdout." << std::endl << std::endl;
92  }
93 
94  memset( &_rods_args, 0, sizeof( _rods_args ) );
95  if ( global_prog_ops_var_map.count( "help" ) ) {
96  _rods_args.help = 1;
97  return 0;
98  }
99  if ( global_prog_ops_var_map.count( "all" ) ) {
100  _rods_args.all = 1;
101  }
102  if ( global_prog_ops_var_map.count( "bulk" ) ) {
103  _rods_args.bulk = 1;
104  }
105  if ( global_prog_ops_var_map.count( "force" ) ) {
106  _rods_args.force = 1;
107  }
108  if ( global_prog_ops_var_map.count( "redirect" ) ) {
109  _rods_args.redirectConn = 1;
110  }
111  if ( global_prog_ops_var_map.count( "checksum" ) ) {
112  _rods_args.checksum = 1;
113  }
114  if ( global_prog_ops_var_map.count( "verify_checksum" ) ) {
115  _rods_args.verifyChecksum = 1;
116  }
117  if ( global_prog_ops_var_map.count( "" ) ) {
118  _rods_args.verifyChecksum = 1;
119  }
120  if ( global_prog_ops_var_map.count( "repl_num" ) ) {
121  _rods_args.replNum = 1;
122  try {
123  _rods_args.replNumValue = ( char* )global_prog_ops_var_map[ "repl_num" ].as<std::string>().c_str();
124  }
125  catch ( const boost::bad_any_cast& ) {
126  return INVALID_ANY_CAST;
127  }
128  }
129  if ( global_prog_ops_var_map.count( "num_threads" ) ) {
130  _rods_args.number = 1;
131  try {
132  _rods_args.numberValue = global_prog_ops_var_map[ "num_threads" ].as<int>();
133  }
134  catch ( const boost::bad_any_cast& ) {
135  return INVALID_ANY_CAST;
136  }
137  }
138  if ( global_prog_ops_var_map.count( "physical_path" ) ) {
139  _rods_args.physicalPath = 1;
140  try {
141  _rods_args.physicalPathString = ( char* )global_prog_ops_var_map[ "physical_path" ].as< std::string >().c_str();
142  }
143  catch ( const boost::bad_any_cast& ) {
144  return INVALID_ANY_CAST;
145  }
146  }
147  if ( global_prog_ops_var_map.count( "progress" ) ) {
148  _rods_args.progressFlag = 1;
149  }
150  if ( global_prog_ops_var_map.count( "rbudp" ) ) {
151  _rods_args.rbudp = 1;
152  }
153  if ( global_prog_ops_var_map.count( "recursive" ) ) {
154  _rods_args.recursive = 1;
155  }
156  if ( global_prog_ops_var_map.count( "dest_resc" ) ) {
157  _rods_args.resource = 1;
158  try {
159  _rods_args.resourceString = ( char* )global_prog_ops_var_map[ "dest_resc" ].as< std::string >().c_str();
160  }
161  catch ( const boost::bad_any_cast& ) {
162  return INVALID_ANY_CAST;
163  }
164  }
165  if ( global_prog_ops_var_map.count( "ticket" ) ) {
166  _rods_args.ticket = 1;
167  try {
168  _rods_args.ticketString = ( char* )global_prog_ops_var_map[ "ticket" ].as< std::string >().c_str();
169  }
170  catch ( const boost::bad_any_cast& ) {
171  return INVALID_ANY_CAST;
172  }
173  }
174  if ( global_prog_ops_var_map.count( "renew_socket" ) ) {
175  _rods_args.reconnect = 1;
176  }
177  if ( global_prog_ops_var_map.count( "verbose" ) ) {
178  _rods_args.verbose = 1;
179  }
180  if ( global_prog_ops_var_map.count( "very_verbose" ) ) {
181  _rods_args.verbose = 1;
182  _rods_args.veryVerbose = 1;
184  }
185  if ( global_prog_ops_var_map.count( "data_type" ) ) {
186  _rods_args.dataType = 1;
187  try {
188  _rods_args.dataTypeString = ( char* )global_prog_ops_var_map[ "data_type" ].as< std::string >().c_str();
189  }
190  catch ( const boost::bad_any_cast& ) {
191  return INVALID_ANY_CAST;
192  }
193  }
194  if ( global_prog_ops_var_map.count( "restart_file" ) ) {
195  _rods_args.restart = 1;
196  try {
197  _rods_args.restartFileString = ( char* )global_prog_ops_var_map[ "restart_file" ].as< std::string >().c_str();
198  }
199  catch ( const boost::bad_any_cast& ) {
200  return INVALID_ANY_CAST;
201  }
202  }
203  if ( global_prog_ops_var_map.count( "link" ) ) {
204  _rods_args.link = 1;
205  }
206  if ( global_prog_ops_var_map.count( "lfrestart" ) ) {
207  _rods_args.lfrestart = 1;
208  try {
209  _rods_args.lfrestartFileString = ( char* )global_prog_ops_var_map[ "lfrestart" ].as< std::string >().c_str();
210  }
211  catch ( const boost::bad_any_cast& ) {
212  return INVALID_ANY_CAST;
213  }
214  }
215  if ( global_prog_ops_var_map.count( "retries" ) ) {
216  _rods_args.retries = 1;
217  try {
218  _rods_args.retriesValue = global_prog_ops_var_map[ "retries" ].as< int >();
219  }
220  catch ( const boost::bad_any_cast& ) {
221  return INVALID_ANY_CAST;
222  }
223  }
224  if ( global_prog_ops_var_map.count( "wlock" ) ) {
225  _rods_args.wlock = 1;
226  }
227  if ( global_prog_ops_var_map.count( "rlock" ) ) {
228  _rods_args.rlock = 1;
229  }
230  if ( global_prog_ops_var_map.count( "purgec" ) ) {
231  _rods_args.purgeCache = 1;
232  }
233  if ( global_prog_ops_var_map.count( "kv_pass" ) ) {
234  _rods_args.kv_pass = 1;
235  try {
236  _rods_args.kv_pass_string = ( char* )global_prog_ops_var_map[ "kv_pass" ].as< std::string >().c_str();
237  }
238  catch ( const boost::bad_any_cast& ) {
239  return INVALID_ANY_CAST;
240  }
241  }
242  if ( global_prog_ops_var_map.count( "metadata" ) ) {
243  try {
244  _rods_args.metadata_string = ( char* )global_prog_ops_var_map[ "metadata" ].as< std::string >().c_str();
245  }
246  catch ( const boost::bad_any_cast& ) {
247  return INVALID_ANY_CAST;
248  }
249  }
250  if ( global_prog_ops_var_map.count( "acl" ) ) {
251  try {
252  _rods_args.acl_string = ( char* )global_prog_ops_var_map[ "acl" ].as< std::string >().c_str();
253  }
254  catch ( const boost::bad_any_cast& ) {
255  return INVALID_ANY_CAST;
256  }
257  }
258 
259  return 0;
260 
261 } // parse_program_options
262 
264  const path_list_t& _path_list,
265  rodsEnv* _rods_env,
266  int _src_type,
267  int _dst_type,
268  int _flag,
269  rodsPathInp_t* _rods_paths ) {
270 
271  int numSrc = 0;
272 
273  if ( _rods_paths == NULL ) {
274  return USER__NULL_INPUT_ERR;
275  }
276 
277  memset( _rods_paths, 0, sizeof( rodsPathInp_t ) );
278 
279  if ( _path_list.size() <= 0 ) {
280  if ( ( _flag & ALLOW_NO_SRC_FLAG ) == 0 ) {
281  return USER__NULL_INPUT_ERR;
282  }
283  else {
284  numSrc = 1;
285  }
286  }
287  else if ( _path_list.size() == 1 ) {
288  numSrc = 1;
289  }
290  else if ( _dst_type == NO_INPUT_T ) { /* no dest input */
291  numSrc = _path_list.size();
292  }
293  else {
294  numSrc = _path_list.size() - 1;
295  }
296 
297  int status = 0;
298  for ( int i = 0; i < numSrc; i++ ) {
299  if ( _path_list.size() <= 0 ) {
300  /* just add cwd */
301  addSrcInPath( _rods_paths, "." );
302  }
303  else {
304  addSrcInPath( _rods_paths, _path_list[ i ].c_str() );
305  }
306  if ( _src_type <= COLL_OBJ_T ) {
307  status = parseRodsPath( &_rods_paths->srcPath[i], _rods_env );
308 
309  if (status == 0) {
310  auto* escaped_path = escape_path(_rods_paths->srcPath->outPath);
311  rstrcpy(_rods_paths->srcPath->outPath, escaped_path, MAX_NAME_LEN);
312  std::free(escaped_path);
313  }
314  }
315  else {
316  status = parseLocalPath( &_rods_paths->srcPath[i] );
317  }
318  if ( status < 0 ) {
319  return status;
320  }
321  }
322 
323  if ( _dst_type != NO_INPUT_T ) {
324  _rods_paths->destPath = ( rodsPath_t* )malloc( sizeof( rodsPath_t ) );
325  memset( _rods_paths->destPath, 0, sizeof( rodsPath_t ) );
326  if ( _path_list.size() > 1 ) {
327  rstrcpy(
328  _rods_paths->destPath->inPath,
329  _path_list.rbegin()->c_str(),
330  MAX_NAME_LEN );
331  }
332  else {
333  rstrcpy( _rods_paths->destPath->inPath, ".", MAX_NAME_LEN );
334  }
335 
336  if ( _dst_type <= COLL_OBJ_T ) {
337  status = parseRodsPath( _rods_paths->destPath, _rods_env );
338 
339  if (status == 0) {
340  auto* escaped_path = escape_path(_rods_paths->destPath->outPath);
341  rstrcpy(_rods_paths->destPath->outPath, escaped_path, MAX_NAME_LEN);
342  std::free(escaped_path);
343  }
344  }
345  else if ( strcmp( _rods_paths->destPath->inPath, STDOUT_FILE_NAME ) == 0 ) {
346  snprintf( _rods_paths->destPath->outPath, sizeof( _rods_paths->destPath->outPath ), "%s", STDOUT_FILE_NAME );
347  _rods_paths->destPath->objType = UNKNOWN_FILE_T;
348  _rods_paths->destPath->objState = NOT_EXIST_ST;
350  }
351  else {
352  status = parseLocalPath( _rods_paths->destPath );
353  }
354  }
355 
356  return status;
357 
358 } // build_irods_path_structure
359 
360 void set_sp_option( const char* _exec ) {
361  if( !_exec ) {
362  return;
363  }
364 
365  fs::path p( _exec );
366  setenv( SP_OPTION, p.filename().c_str(), 1 );
367 
368 } // set_sp_option
369 
370 // single C-friendly interface for the above two functions
372  int _argc,
373  char** _argv,
374  rodsArguments_t& _rods_args,
375  rodsEnv* _rods_env,
376  int _src_type,
377  int _dst_type,
378  int _flag,
379  rodsPathInp_t* _rods_paths ) {
380  if( !_argv || !_argv[0] ) {
382  }
383 
384  set_sp_option( _argv[0] );
385 
386  path_list_t paths;
387  int p_err = parse_program_options(
388  _argc,
389  _argv,
390  _rods_args,
391  paths );
392  if ( p_err < 0 ) {
393  return p_err;
394 
395  }
396 
397  if ( _rods_args.help ) {
398  return 0;
399  }
400 
402  paths,
403  _rods_env,
404  _src_type,
405  _dst_type,
406  _flag,
407  _rods_paths );
408  if ( p_err < 0 ) {
409  return p_err;
410  }
411 
412  return 0;
413 
414 } // parse_opts_and_paths
rodsArguments_t::restartFileString
char * restartFileString
Definition: parseCommandLine.h:117
NULL
#define NULL
Definition: rodsDef.h:70
ALLOW_NO_SRC_FLAG
#define ALLOW_NO_SRC_FLAG
Definition: rodsPath.h:44
rodsArguments_t::ticketString
char * ticketString
Definition: parseCommandLine.h:99
rodsArguments_t::all
int all
Definition: parseCommandLine.h:18
rodsArguments_t
Definition: parseCommandLine.h:14
rodsArguments_t::retriesValue
int retriesValue
Definition: parseCommandLine.h:122
rodsArguments_t::rbudp
int rbudp
Definition: parseCommandLine.h:83
UNKNOWN_FILE_T
@ UNKNOWN_FILE_T
Definition: rodsType.h:40
RodsPathInp
Definition: rodsPath.h:33
rodsArguments_t::verbose
int verbose
Definition: parseCommandLine.h:107
rodsArguments_t::help
int help
Definition: parseCommandLine.h:47
rodsArguments_t::dataTypeString
char * dataTypeString
Definition: parseCommandLine.h:55
path_list_t
std::vector< std::string > path_list_t
Definition: irods_parse_command_line_options.cpp:13
rcMisc.h
pid_age.p
p
Definition: pid_age.py:13
global_prog_ops_var_map
static boost::program_options::variables_map global_prog_ops_var_map
Definition: irods_parse_command_line_options.cpp:18
RodsPath::inPath
char inPath[(1024+64)]
Definition: rodsPath.h:23
rodsArguments_t::rlock
int rlock
Definition: parseCommandLine.h:58
RodsPath::objState
objStat_t objState
Definition: rodsPath.h:20
rodsArguments_t::bulk
int bulk
Definition: parseCommandLine.h:27
NO_INPUT_T
@ NO_INPUT_T
Definition: rodsType.h:43
rodsArguments_t::physicalPathString
char * physicalPathString
Definition: parseCommandLine.h:71
rodsArguments_t::resource
int resource
Definition: parseCommandLine.h:86
RodsPathInp::srcPath
rodsPath_t * srcPath
Definition: rodsPath.h:35
rodsArguments_t::kv_pass_string
char * kv_pass_string
Definition: parseCommandLine.h:141
RodsPath::objType
objType_t objType
Definition: rodsPath.h:19
SYS_INVALID_INPUT_PARAM
@ SYS_INVALID_INPUT_PARAM
Definition: rodsErrorTable.h:195
COLL_OBJ_T
@ COLL_OBJ_T
Definition: rodsType.h:39
SP_OPTION
#define SP_OPTION
Definition: rodsDef.h:263
rodsArguments_t::checksum
int checksum
Definition: parseCommandLine.h:52
rodsArguments_t::metadata_string
char * metadata_string
Definition: parseCommandLine.h:138
rodsArguments_t::redirectConn
int redirectConn
Definition: parseCommandLine.h:51
rodsArguments_t::ticket
int ticket
Definition: parseCommandLine.h:98
RodsPathInp::destPath
rodsPath_t * destPath
Definition: rodsPath.h:36
rodsArguments_t::verifyChecksum
int verifyChecksum
Definition: parseCommandLine.h:53
build_irods_path_structure
static int build_irods_path_structure(const path_list_t &_path_list, rodsEnv *_rods_env, int _src_type, int _dst_type, int _flag, rodsPathInp_t *_rods_paths)
Definition: irods_parse_command_line_options.cpp:263
rodsArguments_t::link
int link
Definition: parseCommandLine.h:57
rodsArguments_t::acl_string
char * acl_string
Definition: parseCommandLine.h:139
rodsArguments_t::purgeCache
int purgeCache
Definition: parseCommandLine.h:78
rodsArguments_t::veryVerbose
int veryVerbose
Definition: parseCommandLine.h:108
MAX_NAME_LEN
#define MAX_NAME_LEN
Definition: rodsDef.h:61
deploy_schemas_locally.options
options
Definition: deploy_schemas_locally.py:63
escape_path
char * escape_path(const char *_path)
Definition: rodsPath.cpp:497
INVALID_ANY_CAST
@ INVALID_ANY_CAST
Definition: rodsErrorTable.h:771
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
rodsArguments_t::retries
int retries
Definition: parseCommandLine.h:121
rodsArguments_t::resourceString
char * resourceString
Definition: parseCommandLine.h:87
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
rodsArguments_t::wlock
int wlock
Definition: parseCommandLine.h:59
rodsArguments_t::force
int force
Definition: parseCommandLine.h:38
rodsArguments_t::physicalPath
int physicalPath
Definition: parseCommandLine.h:70
rodsLogLevel
void rodsLogLevel(int level)
Definition: rodsLog.cpp:339
RodsPath::outPath
char outPath[(1024+64)]
Definition: rodsPath.h:24
rodsArguments_t::kv_pass
int kv_pass
Definition: parseCommandLine.h:140
parseLocalPath
int parseLocalPath(rodsPath_t *rodsPath)
Definition: rodsPath.cpp:215
rodsArguments_t::recursive
int recursive
Definition: parseCommandLine.h:85
parseRodsPath
int parseRodsPath(rodsPath_t *rodsPath, rodsEnv *myRodsEnv)
Definition: rodsPath.cpp:54
rodsArguments_t::lfrestart
int lfrestart
Definition: parseCommandLine.h:118
parse_opts_and_paths
int parse_opts_and_paths(int _argc, char **_argv, rodsArguments_t &_rods_args, rodsEnv *_rods_env, int _src_type, int _dst_type, int _flag, rodsPathInp_t *_rods_paths)
Definition: irods_parse_command_line_options.cpp:371
error
int error
Definition: filesystem.cpp:101
parse_program_options
static int parse_program_options(int _argc, char **_argv, rodsArguments_t &_rods_args, path_list_t &_paths)
Definition: irods_parse_command_line_options.cpp:22
rodsArguments_t::lfrestartFileString
char * lfrestartFileString
Definition: parseCommandLine.h:119
rodsArguments_t::replNum
int replNum
Definition: parseCommandLine.h:63
rodsErrorTable.h
rodsArguments_t::progressFlag
int progressFlag
Definition: parseCommandLine.h:74
RodsPath
Definition: rodsPath.h:18
irods_parse_command_line_options.hpp
rodsArguments_t::numberValue
int numberValue
Definition: parseCommandLine.h:69
rstrcpy
char * rstrcpy(char *dest, const char *src, int maxLen)
Definition: stringOpr.cpp:51
rodsEnv
Definition: getRodsEnv.h:8
NOT_EXIST_ST
@ NOT_EXIST_ST
Definition: rodsType.h:48
addSrcInPath
int addSrcInPath(rodsPathInp_t *rodsPathInp, const char *inPath)
Definition: rodsPath.cpp:261
rodsArguments_t::reconnect
int reconnect
Definition: parseCommandLine.h:103
rodsArguments_t::replNumValue
char * replNumValue
Definition: parseCommandLine.h:64
rodsArguments_t::restart
int restart
Definition: parseCommandLine.h:116
rodsArguments_t::dataType
int dataType
Definition: parseCommandLine.h:54
STDOUT_FILE_NAME
#define STDOUT_FILE_NAME
Definition: rodsPath.h:16
set_sp_option
void set_sp_option(const char *_exec)
Definition: irods_parse_command_line_options.cpp:360
rodsArguments_t::number
int number
Definition: parseCommandLine.h:68
USER__NULL_INPUT_ERR
@ USER__NULL_INPUT_ERR
Definition: rodsErrorTable.h:247
getRodsEnv.h