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)  

libstructfile.cpp
Go to the documentation of this file.
1 // =-=-=-=-=-=-=-
3 #include "irods_file_object.hpp"
10 #include "apiHeaderAll.h"
11 #include "rsFileOpen.hpp"
12 #include "rsFileStat.hpp"
13 #include "rsFileRead.hpp"
14 #include "rsFileClose.hpp"
15 #include "rsFileWrite.hpp"
16 #include "rsFileMkdir.hpp"
17 #include "rsFileRmdir.hpp"
18 #include "rsFileCreate.hpp"
19 #include "rsFileOpen.hpp"
20 #include "rsFileUnlink.hpp"
21 #include "rsFileLseek.hpp"
22 #include "rsFileOpendir.hpp"
23 #include "rsFileClosedir.hpp"
24 #include "rsFileReaddir.hpp"
25 #include "rsFileRename.hpp"
26 #include "rsFileTruncate.hpp"
27 
28 // =-=-=-=-=-=-=-
29 // stl includes
30 #include <iostream>
31 #include <sstream>
32 #include <vector>
33 #include <string>
34 #include <sstream>
35 #include <fstream>
36 
37 // =-=-=-=-=-=-=-
38 // boost includes
39 #include "boost/filesystem/operations.hpp"
40 #include "boost/filesystem/path.hpp"
41 
42 // =-=-=-=-=-=-=-
43 // system includes
44 #include "archive.h"
45 #include "archive_entry.h"
46 
47 // =-=-=-=-=-=-=-
48 // structures and defines
49 typedef struct structFileDesc {
50  int inuseFlag;
53  int openCnt;
54  char dataType[NAME_LEN]; // JMC - backport 4634
56 
57 #define CACHE_DIR_STR "cacheDir"
58 
59 typedef struct tarSubFileDesc {
60  int inuseFlag;
62  int fd; /* the fd of the opened cached subFile */
63  char cacheFilePath[MAX_NAME_LEN]; /* the phy path name of the cached
64  * subFile */
66 
67 #define NUM_TAR_SUB_FILE_DESC 20
68 
69 // =-=-=-=-=-=-=-
70 // irods includes
71 #include "rsGlobalExtern.hpp"
72 #include "modColl.h"
73 #include "apiHeaderAll.h"
74 #include "objMetaOpr.hpp"
75 #include "dataObjOpr.hpp"
76 #include "collection.hpp"
77 #include "specColl.hpp"
78 #include "resource.hpp"
79 #include "miscServerFunct.hpp"
80 #include "physPath.hpp"
81 #include "fileOpen.h"
82 
83 
84 // =-=-=-=-=-=-=-=-
85 // file descriptor tables which hold references to struct files
86 // which are currently in flight
87 const int NUM_STRUCT_FILE_DESC = 16;
90 
91 // =-=-=-=-=-=-=-=-
92 // manager of resource plugins which are resolved and cached
94 
95 
96 // =-=-=-=-=-=-=-
97 // start operation used to allocate the FileDesc tables
98 // must be C linkage for delay_load
102  return SUCCESS();
103 }
104 
105 // =-=-=-=-=-=-=-
106 // stop operation used to free the FileDesc tables
107 // must be C linkage for delay_load
111  return SUCCESS();
112 }
113 
114 // =-=-=-=-=-=-=-
115 // 2. Define operations which will be called by the file*
116 // calls declared in server/driver/include/fileDriver.h
117 // =-=-=-=-=-=-=-
118 
119 // =-=-=-=-=-=-=-
120 // NOTE :: to access properties in the _prop_map do the
121 // :: following :
122 // :: double my_var = 0.0;
123 // :: irods::error ret = _prop_map.get< double >( "my_key", my_var );
124 // =-=-=-=-=-=-=-
125 
126 // =-=-=-=-=-=-=-
127 // helper function to check incoming parameters
129  irods::plugin_context& _ctx ) {
130  // =-=-=-=-=-=-=-
131  // ask the context if it is valid
133  if ( !ret.ok() ) {
134  return PASSMSG( "resource context is invalid", ret );
135 
136  }
137 
138  return SUCCESS();
139 
140 } // tar_check_params
141 
142 // =-=-=-=-=-=-=-
143 // @brief simple struct to pass into libarchive callbacks
144 struct cb_ctx_t {
145  int idx_;
146  char loc_[ NAME_LEN ];
149 };
150 
151 // =-=-=-=-=-=-=-
152 // OPEN callback for use by libarchive which makes use of the
153 // irods rsFile API for file access
155  struct archive* _arch,
156  void* _data,
157  int mode ) {
158  if ( !_arch ||
159  !_data ) {
160  rodsLog( LOG_ERROR, "irods_file_open - null input" );
161  return ARCHIVE_FATAL;
162  }
163 
164  // =-=-=-=-=-=-=-
165  // cast data pointer to the cb_struct
166  cb_ctx_t* cb_ctx = static_cast< cb_ctx_t* >( _data );
167 
168  // =-=-=-=-=-=-=-
169  // handy pointer to special collection
170  specColl_t* spec_coll = cb_ctx->desc_->specColl;
171 
172  // =-=-=-=-=-=-=-
173  // prepare a file inp to call a rsFileOpen
174  fileOpenInp_t f_inp;
175  memset( &f_inp, 0, sizeof( f_inp ) );
176  rstrcpy( f_inp.resc_name_, spec_coll->resource, MAX_NAME_LEN );
177  rstrcpy( f_inp.resc_hier_, spec_coll->rescHier, MAX_NAME_LEN );
178  rstrcpy( f_inp.objPath, spec_coll->objPath, MAX_NAME_LEN );
179  rstrcpy( f_inp.addr.hostAddr, cb_ctx->loc_, NAME_LEN );
180  rstrcpy( f_inp.fileName, spec_coll->phyPath, MAX_NAME_LEN );
181  f_inp.mode = getDefFileMode();
182  f_inp.flags = mode;
183  //rstrcpy( f_inp.in_pdmo, dataObjInfo->in_pdmo, MAX_NAME_LEN );
184  cb_ctx->idx_ = rsFileOpen( cb_ctx->desc_->rsComm, &f_inp );
185 
186  return ARCHIVE_OK;
187 
188 } // irods_file_open
189 
191  struct archive* _arch,
192  void* _data ) {
193  return irods_file_open( _arch, _data, O_RDONLY );
194 }
195 
197  struct archive* _arch,
198  void* _data ) {
199  return irods_file_open( _arch, _data, O_WRONLY | O_CREAT );
200 }
201 
202 // =-=-=-=-=-=-=-
203 // READ callback for use by libarchive which makes use of the
204 // irods rsFile API for file access
206  struct archive* _arch,
207  void* _data,
208  const void** _block) {
209  if ( !_arch ||
210  !_data ||
211  !_block ) {
212  rodsLog( LOG_ERROR, "irods_file_read - null input" );
213  return ARCHIVE_FATAL;
214  }
215 
216  // =-=-=-=-=-=-=-
217  // cast data pointer to the cb_struct
218  cb_ctx_t* cb_ctx = static_cast< cb_ctx_t* >( _data );
219 
220  // =-=-=-=-=-=-=-
221  // build a read inp and read the buffer
222  if ( cb_ctx->read_buf.buf ) {
223  free( cb_ctx->read_buf.buf );
224  }
225 
226  // Based on some performance testing, it was determined that there were little
227  // or no performance gains beyond a block size of 1MB.
228  constexpr auto block_size_in_bytes = 1 * 1024 * 1024;
229 
230  memset( &cb_ctx->read_buf, 0, sizeof( cb_ctx->read_buf ) );
231  cb_ctx->read_buf.buf = malloc( block_size_in_bytes );
232  cb_ctx->read_buf.len = block_size_in_bytes;
233 
234  fileReadInp_t r_inp{};
235  r_inp.fileInx = cb_ctx->idx_;
236  r_inp.len = block_size_in_bytes;
237  const auto status = rsFileRead( cb_ctx->desc_->rsComm, &r_inp, &cb_ctx->read_buf );
238  if ( status < 0 ) {
239  return -1;
240  }
241  else {
242  ( *_block ) = cb_ctx->read_buf.buf;
243  return status;
244  }
245 
246 } // irods_file_read
247 
248 // =-=-=-=-=-=-=-
249 // CLOSE callback for use by libarchive which makes use of the
250 // irods rsFile API for file access
252  struct archive* _arch,
253  void* _data ) {
254  // =-=-=-=-=-=-=-
255  // parameter check
256  if ( !_arch ||
257  !_data ) {
258  rodsLog( LOG_ERROR, "irods_file_close - null input" );
259  return ARCHIVE_FATAL;
260  }
261  // =-=-=-=-=-=-=-
262  // cast data pointer to the cb_struct
263  cb_ctx_t* cb_ctx = static_cast< cb_ctx_t* >( _data );
264 
265  fileCloseInp_t fileCloseInp;
266  memset( &fileCloseInp, 0, sizeof( fileCloseInp ) );
267  fileCloseInp.fileInx = cb_ctx->idx_;
268  return rsFileClose( cb_ctx->desc_->rsComm, &fileCloseInp );
269 
270 } // irods_file_close
271 
272 // =-=-=-=-=-=-=-
273 //
275  struct archive* _arch,
276  void* _data,
277  const void* _buff,
278  size_t _len ) {
279  // =-=-=-=-=-=-=-
280  // parameter check
281  if ( !_arch ||
282  !_data ||
283  !_buff ) {
284  rodsLog( LOG_ERROR, "irods_file_write - null input" );
285  return ARCHIVE_FATAL;
286  }
287 
288  // =-=-=-=-=-=-=-
289  // cast data pointer to the cb_struct
290  cb_ctx_t* cb_ctx = static_cast< cb_ctx_t* >( _data );
291 
292  fileWriteInp_t fileWriteInp;
293  memset( &fileWriteInp, 0, sizeof( fileWriteInp ) );
294  fileWriteInp.fileInx = cb_ctx->idx_;
295  fileWriteInp.len = _len;
296 
297  bytesBuf_t write_buf;
298  write_buf.buf = const_cast< void* >( _buff );
299  write_buf.len = _len;
300  int sz = rsFileWrite(
301  cb_ctx->desc_->rsComm,
302  &fileWriteInp,
303  &write_buf );
304  if ( sz < 0 ) {
305  return -1;
306  }
307  else {
308  return sz;
309  }
310 
311 } // irods_file_write
312 
313 // =-=-=-=-=-=-=-
314 // call archive file extraction for struct file
315 irods::error extract_file( int _index ) {
316  // =-=-=-=-=-=-=-
317  // check struct desc table in use flag
318  if ( PluginStructFileDesc[ _index ].inuseFlag <= 0 ) {
319  std::stringstream msg;
320  msg << "extract_file - struct file index: ";
321  msg << _index;
322  msg << " is not in use";
323  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
324  }
325 
326  // =-=-=-=-=-=-=-
327  // check struct desc table in use flag
328  specColl_t* spec_coll = PluginStructFileDesc[ _index ].specColl;
329  if ( spec_coll == NULL ||
330  strlen( spec_coll->cacheDir ) == 0 ||
331  strlen( spec_coll->phyPath ) == 0 ) {
332  std::stringstream msg;
333  msg << "extract_file - bad special collection for index: ";
334  msg << _index;
335  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
336 
337  }
338 
339  // =-=-=-=-=-=-=-
340  // select which attributes we want to restore
341  int flags = ARCHIVE_EXTRACT_TIME;
342  //flags |= ARCHIVE_EXTRACT_PERM;
343  //flags |= ARCHIVE_EXTRACT_ACL;
344  //flags |= ARCHIVE_EXTRACT_FFLAGS;
345 
346  // =-=-=-=-=-=-=-
347  // initialize archive struct and set flags for format etc
348  struct archive* arch = archive_read_new();
349  archive_read_support_filter_all( arch );
350  archive_read_support_format_all( arch );
351 
352  // =-=-=-=-=-=-=-
353  // extract the host location from the resource hierarchy
354  std::string location;
355  irods::error ret = irods::get_loc_for_hier_string( spec_coll->rescHier, location );
356  if ( !ret.ok() ) {
357  return PASSMSG( "extract_file - failed in get_loc_for_hier_string", ret );
358  }
359 
360  cb_ctx_t cb_ctx{};
361  cb_ctx.desc_ = &PluginStructFileDesc[ _index ];
362  snprintf( cb_ctx.loc_, sizeof( cb_ctx.loc_ ), "%s", location.c_str() );
363 
364  // =-=-=-=-=-=-=-
365  // open the archive and and prepare to read
366  if ( archive_read_open(
367  arch,
368  &cb_ctx,
371  irods_file_close ) != ARCHIVE_OK ) {
372  std::stringstream msg;
373  msg << "extract_file - failed to open archive [";
374  msg << spec_coll->phyPath;
375  msg << "]";
376  return ERROR( -1, msg.str() );
377  }
378 
379  // =-=-=-=-=-=-=-
380  // build a cache directory string
381  std::string cache_dir( spec_coll->cacheDir );
382  if ( cache_dir[ cache_dir.size() - 1 ] != '/' ) {
383  cache_dir += "/";
384  }
385 
386  // =-=-=-=-=-=-=-
387  // iterate over entries in the archive and write them to a resource
388  struct archive_entry* entry;
389  while ( ARCHIVE_OK == archive_read_next_header( arch, &entry ) ) {
390  // =-=-=-=-=-=-=-
391  // redirect the path to the cache directory
392  std::string path = cache_dir + std::string( archive_entry_pathname( entry ) );
393  archive_entry_set_pathname( entry, path.c_str() );
394 
395  // =-=-=-=-=-=-=-
396  // read data from entry and write it to a resource
397  if ( ARCHIVE_OK != archive_read_extract( arch, entry, flags ) ) {
398  std::stringstream msg;
399  msg << "extract_file - failed to write [";
400  msg << path;
401  msg << "]";
402  rodsLog( LOG_NOTICE, "%s", msg.str().c_str() );
403  }
404 
405  } // while
406 
407  // =-=-=-=-=-=-=-
408  // release the archive back into the wild
409  archive_read_free( arch );
410 
411  // =-=-=-=-=-=-=-
412  // release the last read buffer
413  if ( cb_ctx.read_buf.buf ) {
414  free( cb_ctx.read_buf.buf );
415  }
416 
417  return SUCCESS();
418 
419 } // extract_file
420 
421 // =-=-=-=-=-=-=-
422 // recursively create a cache directory for a spec coll via irods api
423 irods::error make_tar_cache_dir( int _index, std::string _host ) {
424  // =-=-=-=-=-=-=-
425  // extract and test comm pointer
426  rsComm_t* rs_comm = PluginStructFileDesc[ _index ].rsComm;
427  if ( !rs_comm ) {
428  std::stringstream msg;
429  msg << "make_tar_cache_dir - null rsComm pointer for index: ";
430  msg << _index;
431  return ERROR( SYS_INTERNAL_NULL_INPUT_ERR, msg.str() );
432  }
433 
434  // =-=-=-=-=-=-=-
435  // extract and test special collection pointer
436  specColl_t* spec_coll = PluginStructFileDesc[ _index ].specColl;
437  if ( !spec_coll ) {
438  std::stringstream msg;
439  msg << "make_tar_cache_dir - null specColl pointer for index: ";
440  msg << _index;
441  return ERROR( SYS_INTERNAL_NULL_INPUT_ERR, msg.str() );
442  }
443 
444  // =-=-=-=-=-=-=-
445  // construct a mkdir structure
446  fileMkdirInp_t fileMkdirInp;
447  memset( &fileMkdirInp, 0, sizeof( fileMkdirInp ) );
448  fileMkdirInp.mode = DEFAULT_DIR_MODE;
449  snprintf( fileMkdirInp.addr.hostAddr, sizeof( fileMkdirInp.addr.hostAddr ), "%s", _host.c_str() );
450  snprintf( fileMkdirInp.rescHier, sizeof( fileMkdirInp.rescHier ), "%s", spec_coll->rescHier );
451 
452  // =-=-=-=-=-=-=-
453  // loop over a series of indicies for the directory suffix and
454  // try to make the directory until it succeeds
455  int dir_index = 0;
456  while ( true ) {
457  // =-=-=-=-=-=-=-
458  // build the cache directory name
459  snprintf( fileMkdirInp.dirName, MAX_NAME_LEN, "%s.%s%d",
460  spec_coll->phyPath, CACHE_DIR_STR, dir_index );
461 
462  // =-=-=-=-=-=-=-
463  // system api call to create a directory
464  int status = rsFileMkdir( rs_comm, &fileMkdirInp );
465  if ( status >= 0 ) {
466  break;
467 
468  }
469  else {
470  if ( getErrno( status ) == EEXIST ) {
471  dir_index ++;
472  continue;
473 
474  }
475  else {
476  return ERROR( status, "make_tar_cache_dir - failed to create cache directory" );
477 
478  } // else
479 
480  } // else
481 
482  } // while
483 
484  // =-=-=-=-=-=-=-
485  // copy successful cache dir out of mkdir struct
486  snprintf( spec_coll->cacheDir, sizeof( spec_coll->cacheDir ), "%s", fileMkdirInp.dirName );
487 
488  // =-=-=-=-=-=-=-
489  // Win!
490  return SUCCESS();
491 
492 } // make_tar_cache_dir
493 
494 // =-=-=-=-=-=-=-
495 // extract the tar file into a cache dir
496 irods::error stage_tar_struct_file( int _index, std::string _host ) {
497  int status = -1;
498 
499  // =-=-=-=-=-=-=-
500  // extract the special collection from the struct file table
501  specColl_t* spec_coll = PluginStructFileDesc[_index].specColl;
502  if ( spec_coll == NULL ) {
503  return ERROR( SYS_INTERNAL_NULL_INPUT_ERR, "stage_tar_struct_file - null spec coll" );
504  }
505 
506  rsComm_t* comm = PluginStructFileDesc[ _index ].rsComm;
507  if ( comm == NULL ) {
508  return ERROR( SYS_INTERNAL_NULL_INPUT_ERR, "stage_tar_struct_file - null comm" );
509  }
510 
511 
512  // =-=-=-=-=-=-=-
513  // check to see if we have a cache dir and make one if not
514  if ( strlen( spec_coll->cacheDir ) == 0 ) {
515  // =-=-=-=-=-=-=-
516  // no cache. stage one. make the CacheDir first
517  irods::error mk_err = make_tar_cache_dir( _index, _host );
518  if ( !mk_err.ok() ) {
519  return PASSMSG( "failed to create cachedir", mk_err );
520  }
521 
522  // =-=-=-=-=-=-=-
523  // expand tar file into cache dir
524  irods::error extract_err = extract_file( _index );
525  if ( !extract_err.ok() ) {
526  std::stringstream msg;
527  msg << "stage_tar_struct_file - extract_file failed for [";
528  msg << spec_coll->objPath;
529  msg << "] in cache directory [";
530  msg << spec_coll->cacheDir << "]";
531 
532  /* XXXX may need to remove the cacheDir too */
533  return PASSMSG( msg.str(), extract_err );
534 
535  } // if !ok
536 
537  // =-=-=-=-=-=-=-
538  // register the CacheDir
539  status = modCollInfo2( comm, spec_coll, 0 );
540  if ( status < 0 ) {
541  return ERROR( status, "stage_tar_struct_file - modCollInfo2 failed." );
542  }
543 
544  // =-=-=-=-=-=-=-
545  // if the left over cache dir has a symlink in it, remove the
546  // directory ( addresses Wisc Security Issue r4906 )
547  if ( hasSymlinkInDir( spec_coll->cacheDir ) ) {
548  rodsLog( LOG_ERROR, "extractTarFile: cacheDir %s has symlink in it",
549  spec_coll->cacheDir );
550 
551  /* remove cache */
552  fileRmdirInp_t fileRmdirInp;
553  memset( &fileRmdirInp, 0, sizeof( fileRmdirInp ) );
554  rstrcpy( fileRmdirInp.dirName, spec_coll->cacheDir, MAX_NAME_LEN );
555  rstrcpy( fileRmdirInp.addr.hostAddr, const_cast<char*>( _host.c_str() ), NAME_LEN );
556  rstrcpy( fileRmdirInp.rescHier, spec_coll->rescHier, MAX_NAME_LEN );
557  fileRmdirInp.flags = RMDIR_RECUR;
558  int status = rsFileRmdir( comm, &fileRmdirInp );
559  if ( status < 0 ) {
560  std::stringstream msg;
561  msg << "stage_tar_struct_file - rmdir error for [";
562  msg << spec_coll->cacheDir << "]";
563  return ERROR( status, msg.str() );
564  }
565 
566  } // if hasSymlinkInDir
567 
568  } // if empty cachedir
569 
570  return SUCCESS();
571 
572 } // stage_tar_struct_file
573 
574 // =-=-=-=-=-=-=-
575 // find the next free PluginStructFileDesc slot, mark it in use and return the index
577  for ( int i = 1; i < NUM_STRUCT_FILE_DESC; i++ ) {
578  if ( PluginStructFileDesc[i].inuseFlag == FD_FREE ) {
580  return i;
581  };
582  } // for i
583 
584  return SYS_OUT_OF_FILE_DESC;
585 
586 } // alloc_struct_file_desc
587 
588 int free_struct_file_desc( int _idx ) {
589  if ( _idx < 0 || _idx >= NUM_STRUCT_FILE_DESC ) {
591  "free_struct_file_desc: index %d out of range", _idx );
593  }
594 
595  memset( &PluginStructFileDesc[ _idx ], 0, sizeof( structFileDesc_t ) );
596 
597  return 0;
598 
599 } // free_struct_file_desc
600 
601 // =-=-=-=-=-=-=-
602 //
603 int match_struct_file_desc( specColl_t* _spec_coll ) {
604 
605  for ( int i = 1; i < NUM_STRUCT_FILE_DESC; i++ ) {
606  if ( PluginStructFileDesc[i].inuseFlag == FD_INUSE &&
607  PluginStructFileDesc[i].specColl != NULL &&
608  strcmp( PluginStructFileDesc[i].specColl->collection, _spec_coll->collection ) == 0 &&
609  strcmp( PluginStructFileDesc[i].specColl->objPath, _spec_coll->objPath ) == 0 ) {
610  return i;
611  };
612  } // for
613 
614  return SYS_OUT_OF_FILE_DESC;
615 
616 } // match_struct_file_desc
617 
618 // =-=-=-=-=-=-=-
619 // local function to manage the open of a tar file
621  rsComm_t* _comm,
622  specColl_t* _spec_coll,
623  int& _struct_desc_index,
624  const std::string& _resc_hier,
625  std::string& _resc_host ) {
626  int status = 0;
627  specCollCache_t* spec_cache = 0;
628 
629  // =-=-=-=-=-=-=-
630  // trap null parameters
631  if ( 0 == _spec_coll ) {
632  std::string msg( "tar_struct_file_open - null special collection parameter" );
633  return ERROR( SYS_INTERNAL_NULL_INPUT_ERR, msg );
634  }
635 
636  if ( 0 == _comm ) {
637  std::string msg( "tar_struct_file_open - null rsComm_t parameter" );
638  return ERROR( SYS_INTERNAL_NULL_INPUT_ERR, msg );
639  }
640 
641  // =-=-=-=-=-=-=-
642  // look for opened PluginStructFileDesc
643  _struct_desc_index = match_struct_file_desc( _spec_coll );
644  if ( _struct_desc_index > 0 ) {
645  return SUCCESS();
646  }
647 
648  // =-=-=-=-=-=-=-
649  // alloc and trap bad alloc
650  if ( ( _struct_desc_index = alloc_struct_file_desc() ) < 0 ) {
651  return ERROR( _struct_desc_index, "tar_struct_file_open - call to allocStructFileDesc failed." );
652  }
653 
654  // =-=-=-=-=-=-=-
655  // [ mwan? :: Have to do this because _spec_coll could come from a remote host ]
656  // NOTE :: i dont see any remote server to server comms here
657  if ( ( status = getSpecCollCache( _comm, _spec_coll->collection, 0, &spec_cache ) ) >= 0 ) {
658  // =-=-=-=-=-=-=-
659  // copy pointer to cached special collection
660  PluginStructFileDesc[ _struct_desc_index ].specColl = &spec_cache->specColl;
661  if ( !PluginStructFileDesc[ _struct_desc_index ].specColl ) {
662 
663  }
664 
665  // =-=-=-=-=-=-=-
666  // copy over physical path and resource name since getSpecCollCache
667  // does not give phyPath nor resource
668  if ( strlen( _spec_coll->phyPath ) > 0 ) { // JMC - backport 4517
669  rstrcpy( spec_cache->specColl.phyPath, _spec_coll->phyPath, MAX_NAME_LEN );
670  }
671  if ( strlen( spec_cache->specColl.resource ) == 0 ) {
672  rstrcpy( spec_cache->specColl.resource, _spec_coll->resource, NAME_LEN );
673  }
674  }
675  else {
676  // =-=-=-=-=-=-=-
677  // special collection is local to this server ??
678  PluginStructFileDesc[ _struct_desc_index ].specColl = _spec_coll;
679  }
680 
681  // =-=-=-=-=-=-=-
682  // cache pointer to comm struct
683  PluginStructFileDesc[ _struct_desc_index ].rsComm = _comm;
684 
685  // =-=-=-=-=-=-=-
686  // resolve the child resource by name
687  irods::resource_ptr resc;
688  std::string last_resc;
690  parser.set_string( _resc_hier );
691  parser.last_resc( last_resc );
692  irods::error resc_err = resc_mgr.resolve( last_resc, resc );
693  if ( !resc_err.ok() ) {
694  std::stringstream msg;
695  msg << "tar_struct_file_open - error returned from resolveResc for resource [";
696  msg << _spec_coll->resource;
697  msg << "], status: ";
698  msg << resc_err.code();
699  free_struct_file_desc( _struct_desc_index );
700  return PASSMSG( msg.str(), resc_err );
701  }
702 
703  // =-=-=-=-=-=-=-
704  // extract the name of the host of the resource from the resource plugin
705  rodsServerHost_t* rods_host = 0;
706  irods::error get_err = resc->get_property< rodsServerHost_t* >( irods::RESOURCE_HOST, rods_host );
707  if ( !get_err.ok() ) {
708  return PASSMSG( "failed to call get_property", get_err );
709  }
710 
711  if ( !rods_host ) {
712  return ERROR( -1, "null rods server host" );
713  }
714 
715  if ( !rods_host->hostName ) {
716  return ERROR( -1, "null rods server hostname" );
717  }
718 
719  _resc_host = rods_host->hostName->name;
720 
721  // =-=-=-=-=-=-=-
722  // TODO :: need to deal with remote open here
723 
724  // =-=-=-=-=-=-=-
725  // stage the tar file so we can get at its tasty innards
726  irods::error stage_err = stage_tar_struct_file( _struct_desc_index, _resc_host );
727  if ( !stage_err.ok() ) {
728  free_struct_file_desc( _struct_desc_index );
729  return PASSMSG( "stage_tar_struct_file failed.", stage_err );
730  }
731 
732  // =-=-=-=-=-=-=-
733  // Win!
734  return CODE( _struct_desc_index );
735 
736 } // tar_struct_file_open
737 
738 // =-=-=-=-=-=-=-
739 // create the phy path to the cache dir
741  specColl_t* _spec_coll,
742  const char* _sub_file_path ) {
743  // =-=-=-=-=-=-=-
744  // subFilePath is composed by appending path to the objPath which is
745  // the logical path of the tar file. So we need to substitude the
746  // objPath with cacheDir
747  int len = strlen( _spec_coll->collection );
748  if ( strncmp( _spec_coll->collection, _sub_file_path, len ) != 0 ) {
749  std::stringstream msg;
750  msg << "compose_cache_dir_physical_path - collection [";
751  msg << _spec_coll->collection;
752  msg << "] sub file path [";
753  msg << _sub_file_path;
754  msg << "] mismatch";
755  return ERROR( SYS_STRUCT_FILE_PATH_ERR, msg.str() );
756  }
757 
758  // =-=-=-=-=-=-=-
759  // compose the path
760  snprintf( _phy_path, MAX_NAME_LEN, "%s%s", _spec_coll->cacheDir, _sub_file_path + len );
761 
762  // =-=-=-=-=-=-=-
763  // Win!
764  return SUCCESS();
765 
766 } // compose_cache_dir_physical_path
767 
768 // =-=-=-=-=-=-=-
769 // assign an new entry in the tar desc table
771  for ( int i = 1; i < NUM_TAR_SUB_FILE_DESC; i++ ) {
772  if ( PluginTarSubFileDesc[i].inuseFlag == FD_FREE ) {
774  return i;
775  };
776  }
777 
779  "alloc_tar_sub_file_desc: out of PluginTarSubFileDesc" );
780 
781  return SYS_OUT_OF_FILE_DESC;
782 
783 } // alloc_tar_sub_file_desc
784 
785 // =-=-=-=-=-=-=-
786 // free an entry in the tar desc table
787 int free_tar_sub_file_desc( int _idx ) {
788  if ( _idx < 0 || _idx >= NUM_TAR_SUB_FILE_DESC ) {
790  "free_tar_sub_file_desc: index %d out of range", _idx );
792  }
793 
794  memset( &PluginTarSubFileDesc[ _idx ], 0, sizeof( tarSubFileDesc_t ) );
795 
796  return 0;
797 }
798 
799 // =-=-=-=-=-=-=-
800 // interface for POSIX create
802  irods::plugin_context& _ctx ) {
803  // =-=-=-=-=-=-=-
804  // check incoming parameters
805  irods::error chk_err = tar_check_params( _ctx );
806  if ( !chk_err.ok() ) {
807  return PASSMSG( "tar_file_create_plugin", chk_err );
808  }
809 
810  // =-=-=-=-=-=-=-
811  // cast down the chain to our understood object type
812  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
813 
814  // =-=-=-=-=-=-=-
815  // extract and check the special collection pointer
816  specColl_t* spec_coll = fco->spec_coll();
817  if ( !spec_coll ) {
818  return ERROR( -1, "tar_file_create_plugin - null spec_coll pointer in structure_object" );
819  }
820 
821  // =-=-=-=-=-=-=-
822  // extract and check the comm pointer
823  rsComm_t* comm = fco->comm();
824  if ( !comm ) {
825  return ERROR( -1, "tar_file_create_plugin - null comm pointer in structure_object" );
826  }
827 
828  // =-=-=-=-=-=-=-
829  // open and stage the tar file, get its index
830  int struct_file_index = 0;
831  std::string resc_host;
832  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
833  fco->resc_hier(), resc_host );
834  if ( !open_err.ok() ) {
835  std::stringstream msg;
836  msg << "tar_file_create_plugin - tar_struct_file_open error for [";
837  msg << spec_coll->objPath;
838  return PASSMSG( msg.str(), open_err );
839  }
840 
841  // =-=-=-=-=-=-=-
842  // use the cached specColl. specColl may have changed
843  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
844 
845  // =-=-=-=-=-=-=-
846  // allocate yet another index into another table
847  int sub_index = alloc_tar_sub_file_desc();
848  if ( sub_index < 0 ) {
849  return ERROR( sub_index, "tar_file_create_plugin - alloc_tar_sub_file_desc failed." );
850  }
851 
852  // =-=-=-=-=-=-=-
853  // cache struct file index into sub file index
854  PluginTarSubFileDesc[ sub_index ].structFileInx = struct_file_index;
855 
856  // =-=-=-=-=-=-=-
857  // build a file create structure to pass off to the server api call
858  fileCreateInp_t fileCreateInp;
859  memset( &fileCreateInp, 0, sizeof( fileCreateInp ) );
860 
861  // =-=-=-=-=-=-=-
862  // build a physical path name to the cache dir
863  irods::error comp_err = compose_cache_dir_physical_path( fileCreateInp.fileName,
864  spec_coll,
865  fco->sub_file_path().c_str() );
866  if ( !comp_err.ok() ) {
867  return PASSMSG( "compose_cache_dir_physical_path failed.", comp_err );
868 
869  }
870 
871  fileCreateInp.mode = fco->mode();
872  fileCreateInp.flags = fco->flags();
873  fileCreateInp.otherFlags = NO_CHK_PERM_FLAG; // JMC - backport 4768
874  snprintf( fileCreateInp.addr.hostAddr, sizeof( fileCreateInp.addr.hostAddr ), "%s", resc_host.c_str() );
875  snprintf( fileCreateInp.resc_hier_, sizeof( fileCreateInp.resc_hier_ ), "%s", fco->resc_hier().c_str() );
876  snprintf( fileCreateInp.objPath, sizeof( fileCreateInp.objPath ), "%s", fco->logical_path().c_str() );
877 
878  // =-=-=-=-=-=-=-
879  // make the call to create a file
880  fileCreateOut_t* create_out = NULL;
881  int status = rsFileCreate( comm, &fileCreateInp, &create_out );
882  free( create_out );
883  if ( status < 0 ) {
884  std::stringstream msg;
885  msg << "tar_file_create_plugin - rsFileCreate failed for [";
886  msg << fileCreateInp.fileName;
887  msg << "], status = ";
888  msg << status;
889  return ERROR( status, msg.str() );
890  }
891  else {
892  PluginTarSubFileDesc[ sub_index ].fd = status;
893  PluginStructFileDesc[ struct_file_index ].openCnt++;
894  fco->file_descriptor( sub_index );
895  return CODE( sub_index );
896  }
897 
898 } // tar_file_create_plugin
899 
900 // =-=-=-=-=-=-=-
901 // interface for POSIX Open
903  irods::plugin_context& _ctx ) {
904  // =-=-=-=-=-=-=-
905  // check incoming parameters
906  irods::error chk_err = tar_check_params( _ctx );
907  if ( !chk_err.ok() ) {
908  return PASSMSG( "tar_file_open_plugin", chk_err );
909  }
910 
911  // =-=-=-=-=-=-=-
912  // cast down the chain to our understood object type
913  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
914 
915  // =-=-=-=-=-=-=-
916  // extract and check the special collection pointer
917  specColl_t* spec_coll = fco->spec_coll();
918  if ( !spec_coll ) {
919  return ERROR( -1, "tar_file_open_plugin - null spec_coll pointer in structure_object" );
920  }
921 
922  // =-=-=-=-=-=-=-
923  // extract and check the comm pointer
924  rsComm_t* comm = fco->comm();
925  if ( !comm ) {
926  return ERROR( -1, "tar_file_open_plugin - null comm pointer in structure_object" );
927  }
928 
929  // =-=-=-=-=-=-=-
930  // open and stage the tar file, get its index
931  int struct_file_index = 0;
932  std::string resc_host;
933  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
934  fco->resc_hier(), resc_host );
935  if ( !open_err.ok() ) {
936  std::stringstream msg;
937  msg << "tar_struct_file_open error for [";
938  msg << spec_coll->objPath;
939  return PASSMSG( msg.str(), open_err );
940  }
941 
942  // =-=-=-=-=-=-=-
943  // use the cached specColl. specColl may have changed
944  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
945 
946  // =-=-=-=-=-=-=-
947  // allocate yet another index into another table
948  int sub_index = alloc_tar_sub_file_desc();
949  if ( sub_index < 0 ) {
950  return ERROR( sub_index, "tar_file_open_plugin - alloc_tar_sub_file_desc failed." );
951  }
952 
953  // =-=-=-=-=-=-=-
954  // cache struct file index into sub file index
955  PluginTarSubFileDesc[ sub_index ].structFileInx = struct_file_index;
956 
957  // =-=-=-=-=-=-=-
958  // build a file open structure to pass off to the server api call
959  fileOpenInp_t fileOpenInp;
960  memset( &fileOpenInp, 0, sizeof( fileOpenInp ) );
961 
962  // =-=-=-=-=-=-=-
963  // build a physical path name to the cache dir
964  irods::error comp_err = compose_cache_dir_physical_path( fileOpenInp.fileName, spec_coll, fco->sub_file_path().c_str() );
965  if ( !comp_err.ok() ) {
966  return PASSMSG( "compose_cache_dir_physical_path failed.", comp_err );
967 
968  }
969 
970  fileOpenInp.mode = fco->mode();
971  fileOpenInp.flags = fco->flags();
972  fileOpenInp.otherFlags = NO_CHK_PERM_FLAG; // JMC - backport 4768
973  snprintf( fileOpenInp.addr.hostAddr, sizeof( fileOpenInp.addr.hostAddr ), "%s", resc_host.c_str() );
974  snprintf( fileOpenInp.resc_hier_, sizeof( fileOpenInp.resc_hier_ ), "%s", fco->resc_hier().c_str() );
975  snprintf( fileOpenInp.objPath, sizeof( fileOpenInp.objPath ), "%s", fco->logical_path().c_str() );
976 
977  // =-=-=-=-=-=-=-
978  // make the call to create a file
979  int status = rsFileOpen( comm, &fileOpenInp );
980  if ( status < 0 ) {
981  std::stringstream msg;
982  msg << "tar_file_open_plugin - rsFileOpen failed for [";
983  msg << fileOpenInp.fileName;
984  msg << "], status = ";
985  msg << status;
986  return ERROR( status, msg.str() );
987  }
988  else {
989  PluginTarSubFileDesc[ sub_index ].fd = status;
990  PluginStructFileDesc[ struct_file_index ].openCnt++;
991  fco->file_descriptor( sub_index );
992  return CODE( sub_index );
993  }
994 
995 } // tar_file_open_plugin
996 
997 // =-=-=-=-=-=-=-
998 // interface for POSIX Read
1000  irods::plugin_context& _ctx,
1001  void* _buf,
1002  int _len ) {
1003  // =-=-=-=-=-=-=-
1004  // check incoming parameters
1005  irods::error chk_err = tar_check_params( _ctx );
1006  if ( !chk_err.ok() ) {
1007  return PASSMSG( "tar_file_read_plugin", chk_err );
1008  }
1009 
1010  // =-=-=-=-=-=-=-
1011  // cast down the chain to our understood object type
1012  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1013 
1014  // =-=-=-=-=-=-=-
1015  // check range on the sub file index
1016  if ( fco->file_descriptor() < 1 ||
1017  fco->file_descriptor() >= NUM_TAR_SUB_FILE_DESC ||
1018  PluginTarSubFileDesc[ fco->file_descriptor() ].inuseFlag == 0 ) {
1019  std::stringstream msg;
1020  msg << "tar_file_read_plugin - sub file index ";
1021  msg << fco->file_descriptor();
1022  msg << " is out of range.";
1023  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
1024  }
1025 
1026  // =-=-=-=-=-=-=-
1027  // build a read structure and make the rs call
1028  fileReadInp_t fileReadInp;
1029  bytesBuf_t fileReadOutBBuf;
1030  memset( &fileReadInp, 0, sizeof( fileReadInp ) );
1031  memset( &fileReadOutBBuf, 0, sizeof( fileReadOutBBuf ) );
1032  fileReadInp.fileInx = PluginTarSubFileDesc[ fco->file_descriptor() ].fd;
1033  fileReadInp.len = _len;
1034  fileReadOutBBuf.buf = _buf;
1035 
1036  // =-=-=-=-=-=-=-
1037  // make the call to read a file
1038  int status = rsFileRead( fco->comm(), &fileReadInp, &fileReadOutBBuf );
1039  if ( status < 0 ) {
1040  return ERROR( status, "rsFileRead failed" );
1041  }
1042  else {
1043  return CODE( status );
1044  }
1045 
1046 } // tar_file_read_plugin
1047 
1048 // =-=-=-=-=-=-=-
1049 // interface for POSIX Write
1051  irods::plugin_context& _ctx,
1052  void* _buf,
1053  int _len ) {
1054  // =-=-=-=-=-=-=-
1055  // check incoming parameters
1056  irods::error chk_err = tar_check_params( _ctx );
1057  if ( !chk_err.ok() ) {
1058  return PASSMSG( "tar_file_write_plugin", chk_err );
1059  }
1060 
1061  // =-=-=-=-=-=-=-
1062  // cast down the chain to our understood object type
1063  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1064 
1065  // =-=-=-=-=-=-=-
1066  // check range on the sub file index
1067  if ( fco->file_descriptor() < 1 ||
1068  fco->file_descriptor() >= NUM_TAR_SUB_FILE_DESC ||
1069  PluginTarSubFileDesc[ fco->file_descriptor() ].inuseFlag == 0 ) {
1070  std::stringstream msg;
1071  msg << "tar_file_write_plugin - sub file index ";
1072  msg << fco->file_descriptor();
1073  msg << " is out of range.";
1074  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
1075  }
1076 
1077  // =-=-=-=-=-=-=-
1078  // build a write structure and make the rs call
1079  fileWriteInp_t fileWriteInp;
1080  bytesBuf_t fileWriteOutBBuf;
1081  memset( &fileWriteInp, 0, sizeof( fileWriteInp ) );
1082  memset( &fileWriteOutBBuf, 0, sizeof( fileWriteOutBBuf ) );
1083  fileWriteInp.len = fileWriteOutBBuf.len = _len;
1084  fileWriteInp.fileInx = PluginTarSubFileDesc[ fco->file_descriptor() ].fd;
1085  fileWriteOutBBuf.buf = _buf;
1086 
1087  // =-=-=-=-=-=-=-
1088  // make the write api call
1089  int status = rsFileWrite( fco->comm(), &fileWriteInp, &fileWriteOutBBuf );
1090  if ( status > 0 ) {
1091  // =-=-=-=-=-=-=-
1092  // cache has been written
1093  int struct_idx = PluginTarSubFileDesc[ fco->file_descriptor() ].structFileInx;
1094  specColl_t* spec_coll = PluginStructFileDesc[ struct_idx ].specColl;
1095  if ( spec_coll->cacheDirty == 0 ) {
1096  spec_coll->cacheDirty = 1;
1097  int status1 = modCollInfo2( fco->comm(), spec_coll, 0 );
1098  if ( status1 < 0 ) {
1099  return CODE( status1 );
1100  }
1101  }
1102  return CODE( status );
1103  }
1104  else {
1105  return ERROR( status, "rsFileWrite failed" );
1106  }
1107 
1108 } // tar_file_write_plugin
1109 
1110 // =-=-=-=-=-=-=-
1111 // interface for POSIX Close
1113  irods::plugin_context& _ctx ) {
1114  // =-=-=-=-=-=-=-
1115  // check incoming parameters
1116  irods::error chk_err = tar_check_params( _ctx );
1117  if ( !chk_err.ok() ) {
1118  return PASSMSG( "tar_file_close_plugin", chk_err );
1119  }
1120 
1121  // =-=-=-=-=-=-=-
1122  // cast down the chain to our understood object type
1123  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1124 
1125  // =-=-=-=-=-=-=-
1126  // check range on the sub file index
1127  if ( fco->file_descriptor() < 1 ||
1128  fco->file_descriptor() >= NUM_TAR_SUB_FILE_DESC ||
1129  PluginTarSubFileDesc[ fco->file_descriptor() ].inuseFlag == 0 ) {
1130  std::stringstream msg;
1131  msg << "tar_file_close_plugin - sub file index ";
1132  msg << fco->file_descriptor();
1133  msg << " is out of range.";
1134  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
1135  }
1136 
1137  // =-=-=-=-=-=-=-
1138  // build a close structure and make the rs call
1139  fileCloseInp_t fileCloseInp;
1140  memset( &fileCloseInp, 0, sizeof( fileCloseInp ) );
1141  fileCloseInp.fileInx = PluginTarSubFileDesc[ fco->file_descriptor() ].fd;
1142  int status = rsFileClose( fco->comm(), &fileCloseInp );
1143  if ( status < 0 ) {
1144  std::stringstream msg;
1145  msg << "tar_file_close_plugin - failed in rsFileClose for fd [ ";
1146  msg << fco->file_descriptor();
1147  msg << " ]";
1148  return ERROR( status, msg.str() );
1149  }
1150 
1151  // =-=-=-=-=-=-=-
1152  // close out the sub file allocation and free the space
1153  int struct_file_index = PluginTarSubFileDesc[ fco->file_descriptor() ].structFileInx;
1154  PluginStructFileDesc[ struct_file_index ].openCnt++;
1155  free_tar_sub_file_desc( fco->file_descriptor() );
1156  fco->file_descriptor( 0 );
1157 
1158  return CODE( status );
1159 } // tar_file_close_plugin
1160 
1161 // =-=-=-=-=-=-=-
1162 // interface for POSIX Unlink
1164  irods::plugin_context& _ctx ) {
1165  // =-=-=-=-=-=-=-
1166  // check incoming parameters
1167  irods::error chk_err = tar_check_params( _ctx );
1168  if ( !chk_err.ok() ) {
1169  return PASSMSG( "tar_file_unlink_plugin", chk_err );
1170  }
1171 
1172  // =-=-=-=-=-=-=-
1173  // cast down the chain to our understood object type
1174  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1175 
1176  // =-=-=-=-=-=-=-
1177  // extract and check the special collection pointer
1178  specColl_t* spec_coll = fco->spec_coll();
1179  if ( !spec_coll ) {
1180  return ERROR( -1, "tar_file_unlink_plugin - null spec_coll pointer in structure_object" );
1181  }
1182 
1183  // =-=-=-=-=-=-=-
1184  // extract and check the comm pointer
1185  rsComm_t* comm = fco->comm();
1186  if ( !comm ) {
1187  return ERROR( -1, "tar_file_unlink_plugin - null comm pointer in structure_object" );
1188  }
1189 
1190  // =-=-=-=-=-=-=-
1191  // open and stage the tar file, get its index
1192  int struct_file_index = 0;
1193  std::string resc_host;
1194  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
1195  fco->resc_hier(), resc_host );
1196  if ( !open_err.ok() ) {
1197  std::stringstream msg;
1198  msg << "tar_file_unlink_plugin - tar_struct_file_open error for [";
1199  msg << spec_coll->objPath;
1200  return PASSMSG( msg.str(), open_err );
1201  }
1202 
1203  // =-=-=-=-=-=-=-
1204  // use the cached specColl. specColl may have changed
1205  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1206 
1207  // =-=-=-=-=-=-=-
1208  // build a file unlink structure to pass off to the server api call
1209  fileUnlinkInp_t fileUnlinkInp;
1210  memset( &fileUnlinkInp, 0, sizeof( fileUnlinkInp ) );
1211  snprintf( fileUnlinkInp.rescHier, sizeof( fileUnlinkInp.rescHier ), "%s", fco->resc_hier().c_str() );
1212  snprintf( fileUnlinkInp.objPath, sizeof( fileUnlinkInp.objPath ), "%s", fco->logical_path().c_str() );
1213 
1214  // =-=-=-=-=-=-=-
1215  // build a physical path name to the cache dir
1216  irods::error comp_err = compose_cache_dir_physical_path( fileUnlinkInp.fileName,
1217  spec_coll,
1218  fco->sub_file_path().c_str() );
1219  if ( !comp_err.ok() ) {
1220  return PASSMSG(
1221  "tar_file_unlink_plugin - compose_cache_dir_physical_path failed.", comp_err );
1222  }
1223 
1224  snprintf( fileUnlinkInp.addr.hostAddr, sizeof( fileUnlinkInp.addr.hostAddr ), "%s", resc_host.c_str() );
1225 
1226  // =-=-=-=-=-=-=-
1227  // make the call to unlink a file
1228  int status = rsFileUnlink( comm, &fileUnlinkInp );
1229  if ( status >= 0 ) {
1230  /* cache has been written */
1231  specColl_t* loc_spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1232  if ( loc_spec_coll->cacheDirty == 0 ) {
1233  loc_spec_coll->cacheDirty = 1;
1234  int status1 = modCollInfo2( comm, loc_spec_coll, 0 );
1235  if ( status1 < 0 ) {
1236  return CODE( status1 );
1237  }
1238  }
1239  return CODE( status );
1240  }
1241  else {
1242  return ERROR( status, "rsFileUnlink failed" );
1243  }
1244 
1245 
1246 } // tar_file_unlink_plugin
1247 
1248 // =-=-=-=-=-=-=-
1249 // interface for POSIX Stat
1251  irods::plugin_context& _ctx,
1252  struct stat* _statbuf ) {
1253  // =-=-=-=-=-=-=-
1254  // check incoming parameters
1255  irods::error chk_err = tar_check_params( _ctx );
1256  if ( !chk_err.ok() ) {
1257  return PASSMSG( "tar_file_stat_plugin", chk_err );
1258  }
1259 
1260  // =-=-=-=-=-=-=-
1261  // cast down the chain to our understood object type
1262  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1263 
1264  // =-=-=-=-=-=-=-
1265  // extract and check the special collection pointer
1266  specColl_t* spec_coll = fco->spec_coll();
1267  if ( !spec_coll ) {
1268  return ERROR( -1, "tar_file_stat_plugin - null spec_coll pointer in structure_object" );
1269  }
1270 
1271  // =-=-=-=-=-=-=-
1272  // extract and check the comm pointer
1273  rsComm_t* comm = fco->comm();
1274  if ( !comm ) {
1275  return ERROR( -1, "tar_file_stat_plugin - null comm pointer in structure_object" );
1276  }
1277 
1278  // =-=-=-=-=-=-=-
1279  // open and stage the tar file, get its index
1280  int struct_file_index = 0;
1281  std::string resc_host;
1282  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
1283  fco->resc_hier(), resc_host );
1284  if ( !open_err.ok() ) {
1285  std::stringstream msg;
1286  msg << "tar_file_stat_plugin - tar_struct_file_open error for [";
1287  msg << spec_coll->objPath;
1288  return PASSMSG( msg.str(), open_err );
1289  }
1290 
1291  // =-=-=-=-=-=-=-
1292  // use the cached specColl. specColl may have changed
1293  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1294 
1295 
1296  // =-=-=-=-=-=-=-
1297  // build a file stat structure to pass off to the server api call
1298  fileStatInp_t fileStatInp;
1299  memset( &fileStatInp, 0, sizeof( fileStatInp ) );
1300  snprintf( fileStatInp.rescHier, MAX_NAME_LEN, "%s", fco->resc_hier().c_str() );
1301  snprintf( fileStatInp.objPath, MAX_NAME_LEN, "%s", fco->logical_path().c_str() );
1302 
1303  // =-=-=-=-=-=-=-
1304  // build a physical path name to the cache dir
1305  irods::error comp_err = compose_cache_dir_physical_path( fileStatInp.fileName, spec_coll, fco->sub_file_path().c_str() );
1306  if ( !comp_err.ok() ) {
1307  return PASSMSG(
1308  "tar_file_stat_plugin - compose_cache_dir_physical_path failed.", comp_err );
1309  }
1310 
1311  snprintf( fileStatInp.addr.hostAddr, NAME_LEN, "%s", resc_host.c_str() );
1312  snprintf( fileStatInp.rescHier, MAX_NAME_LEN, "%s", fco->resc_hier().c_str() );
1313 
1314  // =-=-=-=-=-=-=-
1315  // make the call to stat a file
1316  rodsStat_t* rods_stat;
1317  int status = rsFileStat( comm, &fileStatInp, &rods_stat );
1318  if ( status >= 0 ) {
1319  rodsStatToStat( _statbuf, rods_stat );
1320  }
1321  else {
1322  return ERROR( status, "tar_file_stat_plugin - rsFileStat failed." );
1323  }
1324  free( rods_stat );
1325 
1326  return CODE( status );
1327 
1328 } // tar_file_stat_plugin
1329 
1330 // =-=-=-=-=-=-=-
1331 // interface for POSIX lseek
1333  irods::plugin_context& _ctx,
1334  long long _offset,
1335  int _whence ) {
1336  // =-=-=-=-=-=-=-
1337  // check incoming parameters
1338  irods::error chk_err = tar_check_params( _ctx );
1339  if ( !chk_err.ok() ) {
1340  return PASSMSG( "tar_file_lseek_plugin", chk_err );
1341  }
1342 
1343  // =-=-=-=-=-=-=-
1344  // cast down the chain to our understood object type
1345  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1346 
1347  // =-=-=-=-=-=-=-
1348  // check range on the sub file index
1349  if ( fco->file_descriptor() < 1 ||
1350  fco->file_descriptor() >= NUM_TAR_SUB_FILE_DESC ||
1351  PluginTarSubFileDesc[ fco->file_descriptor() ].inuseFlag == 0 ) {
1352  std::stringstream msg;
1353  msg << "tar_file_lseek_plugin - sub file index ";
1354  msg << fco->file_descriptor();
1355  msg << " is out of range.";
1356  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
1357  }
1358 
1359  // =-=-=-=-=-=-=-
1360  // extract and check the comm pointer
1361  rsComm_t* comm = fco->comm();
1362  if ( !comm ) {
1363  return ERROR( -1, "tar_file_lseek_plugin - null comm pointer in structure_object" );
1364  }
1365 
1366  // =-=-=-=-=-=-=-
1367  // build a lseek structure and make the rs call
1368  fileLseekInp_t fileLseekInp;
1369  memset( &fileLseekInp, 0, sizeof( fileLseekInp ) );
1370  fileLseekInp.fileInx = PluginTarSubFileDesc[ fco->file_descriptor() ].fd;
1371  fileLseekInp.offset = _offset;
1372  fileLseekInp.whence = _whence;
1373 
1374  fileLseekOut_t *fileLseekOut = NULL;
1375  int status = rsFileLseek( comm, &fileLseekInp, &fileLseekOut );
1376 
1377  if ( status < 0 || NULL == fileLseekOut ) { // JMC cppcheck - nullptr
1378  return ERROR( status, "rsFileLseek failed" );
1379  }
1380  else {
1381  rodsLong_t offset = fileLseekOut->offset;
1382  free( fileLseekOut );
1383  return CODE( offset );
1384  }
1385 
1386 } // tar_file_lseek_plugin
1387 
1388 // =-=-=-=-=-=-=-
1389 // interface for POSIX mkdir
1391  irods::plugin_context& _ctx ) {
1392  // =-=-=-=-=-=-=-
1393  // check incoming parameters
1394  irods::error chk_err = tar_check_params( _ctx );
1395  if ( !chk_err.ok() ) {
1396  return PASSMSG( "tar_file_mkdir_plugin", chk_err );
1397  }
1398 
1399  // =-=-=-=-=-=-=-
1400  // cast down the chain to our understood object type
1401  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1402 
1403  // =-=-=-=-=-=-=-
1404  // extract and check the special collection pointer
1405  specColl_t* spec_coll = fco->spec_coll();
1406  if ( !spec_coll ) {
1407  return ERROR( -1, "tar_file_mkdir_plugin - null spec_coll pointer in structure_object" );
1408  }
1409 
1410  // =-=-=-=-=-=-=-
1411  // extract and check the comm pointer
1412  rsComm_t* comm = fco->comm();
1413  if ( !comm ) {
1414  return ERROR( -1, "tar_file_mkdir_plugin - null comm pointer in structure_object" );
1415  }
1416 
1417  // =-=-=-=-=-=-=-
1418  // open and stage the tar file, get its index
1419  int struct_file_index = 0;
1420  std::string resc_host;
1421  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
1422  fco->resc_hier(), resc_host );
1423  if ( !open_err.ok() ) {
1424  std::stringstream msg;
1425  msg << "tar_file_mkdir_plugin - tar_struct_file_open error for [";
1426  msg << spec_coll->objPath;
1427  return PASSMSG( msg.str(), open_err );
1428  }
1429 
1430  // =-=-=-=-=-=-=-
1431  // use the cached specColl. specColl may have changed
1432  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1433 
1434  // =-=-=-=-=-=-=-
1435  // build a file mkdir structure to pass off to the server api call
1436  fileMkdirInp_t fileMkdirInp;
1437  memset( &fileMkdirInp, 0, sizeof( fileMkdirInp ) );
1438  snprintf( fileMkdirInp.addr.hostAddr, sizeof( fileMkdirInp.addr.hostAddr ), "%s", resc_host.c_str() );
1439  snprintf( fileMkdirInp.rescHier, sizeof( fileMkdirInp.rescHier ), "%s", spec_coll->rescHier );
1440  fileMkdirInp.mode = fco->mode();
1441 
1442  // =-=-=-=-=-=-=-
1443  // build a physical path name to the cache dir
1444  irods::error comp_err = compose_cache_dir_physical_path( fileMkdirInp.dirName,
1445  spec_coll,
1446  fco->sub_file_path().c_str() );
1447  if ( !comp_err.ok() ) {
1448  return PASSMSG(
1449  "tar_file_mkdir_plugin - compose_cache_dir_physical_path failed.", comp_err );
1450  }
1451 
1452  // =-=-=-=-=-=-=-
1453  // make the call to the mkdir api
1454  int status = rsFileMkdir( comm, &fileMkdirInp );
1455  if ( status >= 0 ) {
1456  // use the specColl in PluginStructFileDesc
1457  specColl_t* loc_spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1458  // =-=-=-=-=-=-=-
1459  // cache has been written
1460  if ( loc_spec_coll->cacheDirty == 0 ) {
1461  loc_spec_coll->cacheDirty = 1;
1462  int status1 = modCollInfo2( comm, loc_spec_coll, 0 );
1463  if ( status1 < 0 ) {
1464  return ERROR( status1, "tar_file_mkdir_plugin - Failed to call modCollInfo2" );
1465  }
1466  }
1467 
1468  return CODE( status );
1469 
1470  }
1471  else {
1472  return ERROR( status, "rsFileMkdir failed" );
1473  }
1474 
1475 } // tar_file_mkdir_plugin
1476 
1477 // =-=-=-=-=-=-=-
1478 // interface for POSIX mkdir
1480  irods::plugin_context& _ctx ) {
1481  // =-=-=-=-=-=-=-
1482  // check incoming parameters
1483  irods::error chk_err = tar_check_params( _ctx );
1484  if ( !chk_err.ok() ) {
1485  return PASSMSG( "tar_file_rmdir_plugin", chk_err );
1486  }
1487 
1488  // =-=-=-=-=-=-=-
1489  // cast down the chain to our understood object type
1490  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1491 
1492  // =-=-=-=-=-=-=-
1493  // extract and check the special collection pointer
1494  specColl_t* spec_coll = fco->spec_coll();
1495  if ( !spec_coll ) {
1496  return ERROR( -1, "tar_file_rmdir_plugin - null spec_coll pointer in structure_object" );
1497  }
1498 
1499  // =-=-=-=-=-=-=-
1500  // extract and check the comm pointer
1501  rsComm_t* comm = fco->comm();
1502  if ( !comm ) {
1503  return ERROR( -1, "tar_file_rmdir_plugin - null comm pointer in structure_object" );
1504  }
1505 
1506  // =-=-=-=-=-=-=-
1507  // open and stage the tar file, get its index
1508  int struct_file_index = 0;
1509  std::string resc_host;
1510  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
1511  fco->resc_hier(), resc_host );
1512  if ( !open_err.ok() ) {
1513  std::stringstream msg;
1514  msg << "tar_file_rmdir_plugin - tar_struct_file_open error for [";
1515  msg << spec_coll->objPath;
1516  return PASSMSG( msg.str(), open_err );
1517  }
1518 
1519  // =-=-=-=-=-=-=-
1520  // use the cached specColl. specColl may have changed
1521  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1522 
1523  // =-=-=-=-=-=-=-
1524  // build a file mkdir structure to pass off to the server api call
1525  fileRmdirInp_t fileRmdirInp;
1526  memset( &fileRmdirInp, 0, sizeof( fileRmdirInp ) );
1527  snprintf( fileRmdirInp.addr.hostAddr, NAME_LEN, "%s", resc_host.c_str() );
1528  snprintf( fileRmdirInp.rescHier, MAX_NAME_LEN, "%s", spec_coll->rescHier );
1529 
1530  // =-=-=-=-=-=-=-
1531  // build a physical path name to the cache dir
1532  irods::error comp_err = compose_cache_dir_physical_path( fileRmdirInp.dirName,
1533  spec_coll,
1534  fco->sub_file_path().c_str() );
1535  if ( !comp_err.ok() ) {
1536  return PASSMSG(
1537  "tar_file_rmdir_plugin - compose_cache_dir_physical_path failed.", comp_err );
1538  }
1539 
1540  // =-=-=-=-=-=-=-
1541  // make the call to the mkdir api
1542  int status = rsFileRmdir( comm, &fileRmdirInp );
1543  if ( status >= 0 ) {
1544  // use the specColl in PluginStructFileDesc
1545  specColl_t* loc_spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1546  // =-=-=-=-=-=-=-
1547  // cache has been written
1548  if ( loc_spec_coll->cacheDirty == 0 ) {
1549  loc_spec_coll->cacheDirty = 1;
1550  int status1 = modCollInfo2( comm, loc_spec_coll, 0 );
1551  if ( status1 < 0 ) {
1552  return ERROR( status1, "tar_file_rmdir_plugin - Failed to call modCollInfo2" );
1553  }
1554  }
1555 
1556  } // if status
1557 
1558  return CODE( status );
1559 
1560 } // tar_file_rmdir_plugin
1561 
1562 // =-=-=-=-=-=-=-
1563 // interface for POSIX opendir
1565  irods::plugin_context& _ctx ) {
1566  // =-=-=-=-=-=-=-
1567  // check incoming parameters
1568  irods::error chk_err = tar_check_params( _ctx );
1569  if ( !chk_err.ok() ) {
1570  return PASSMSG( "tar_file_opendir_plugin", chk_err );
1571  }
1572 
1573  // =-=-=-=-=-=-=-
1574  // cast down the chain to our understood object type
1575  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1576 
1577  // =-=-=-=-=-=-=-
1578  // extract and check the special collection pointer
1579  specColl_t* spec_coll = fco->spec_coll();
1580  if ( !spec_coll ) {
1581  return ERROR( -1, "tar_file_opendir_plugin - null spec_coll pointer in structure_object" );
1582  }
1583 
1584  // =-=-=-=-=-=-=-
1585  // extract and check the comm pointer
1586  rsComm_t* comm = fco->comm();
1587  if ( !comm ) {
1588  return ERROR( -1, "tar_file_opendir_plugin - null comm pointer in structure_object" );
1589  }
1590 
1591  // =-=-=-=-=-=-=-
1592  // open and stage the tar file, get its index
1593  int struct_file_index = 0;
1594  std::string resc_host;
1595  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
1596  fco->resc_hier(), resc_host );
1597  if ( !open_err.ok() ) {
1598  std::stringstream msg;
1599  msg << "tar_file_opendir_plugin - tar_struct_file_open error for [";
1600  msg << spec_coll->objPath;
1601  irods::error ret = PASSMSG( msg.str(), open_err );
1602  irods::log( ret );
1603  return ret;
1604  }
1605 
1606  // =-=-=-=-=-=-=-
1607  // use the cached specColl. specColl may have changed
1608  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1609  if ( !spec_coll ) {
1610  return ERROR( -1, "tar_file_opendir_plugin - null spec_coll pointer in PluginStructFileDesc" );
1611  }
1612 
1613  // =-=-=-=-=-=-=-
1614  // allocate yet another index into another table
1615  int sub_index = alloc_tar_sub_file_desc();
1616  if ( sub_index < 0 ) {
1617  return ERROR( sub_index, "tar_file_opendir_plugin - alloc_tar_sub_file_desc failed." );
1618  }
1619 
1620  // =-=-=-=-=-=-=-
1621  // build a file open structure to pass off to the server api call
1622  fileOpendirInp_t fileOpendirInp;
1623  memset( &fileOpendirInp, 0, sizeof( fileOpendirInp ) );
1624  snprintf( fileOpendirInp.addr.hostAddr, sizeof( fileOpendirInp.addr.hostAddr ), "%s", resc_host.c_str() );
1625  snprintf( fileOpendirInp.objPath, sizeof( fileOpendirInp.objPath ), "%s", fco->logical_path().c_str() );
1626  snprintf( fileOpendirInp.resc_hier_, sizeof( fileOpendirInp.resc_hier_ ), "%s", fco->resc_hier().c_str() );
1627 
1628  // =-=-=-=-=-=-=-
1629  // build a physical path name to the cache dir
1630  irods::error comp_err = compose_cache_dir_physical_path( fileOpendirInp.dirName,
1631  spec_coll,
1632  fco->sub_file_path().c_str() );
1633  if ( !comp_err.ok() ) {
1634  return PASSMSG(
1635  "tarFileRmdirPlugin - compose_cache_dir_physical_path failed.", comp_err );
1636  }
1637 
1638  // =-=-=-=-=-=-=-
1639  // make the api call to open a directory
1640  int status = rsFileOpendir( comm, &fileOpendirInp );
1641  if ( status < 0 ) {
1642  std::stringstream msg;
1643  msg << "tar_file_opendir_plugin - error returned from rsFileOpendir for: [";
1644  msg << fileOpendirInp.dirName;
1645  msg << "], status: ";
1646  msg << status;
1647  irods::error ret = ERROR( status, msg.str() );
1648  irods::log( ret );
1649  return ret;
1650  }
1651  else {
1652  PluginTarSubFileDesc[ sub_index ].fd = status;
1653  PluginStructFileDesc[ struct_file_index ].openCnt++;
1654  fco->file_descriptor( sub_index );
1655 
1656  return CODE( sub_index );
1657  }
1658 
1659 } // tar_file_opendir_plugin
1660 
1661 // =-=-=-=-=-=-=-
1662 // interface for POSIX closedir
1664  irods::plugin_context& _ctx ) {
1665  // =-=-=-=-=-=-=-
1666  // check incoming parameters
1667  irods::error chk_err = tar_check_params( _ctx );
1668  if ( !chk_err.ok() ) {
1669  return PASSMSG( "tar_file_closedir_plugin", chk_err );
1670  }
1671 
1672  // =-=-=-=-=-=-=-
1673  // extract the fco
1674  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1675 
1676  // =-=-=-=-=-=-=-
1677  // check range on the sub file index
1678  if ( fco->file_descriptor() < 1 ||
1679  fco->file_descriptor() >= NUM_TAR_SUB_FILE_DESC ||
1680  PluginTarSubFileDesc[ fco->file_descriptor() ].inuseFlag == 0 ) {
1681  std::stringstream msg;
1682  msg << "tar_file_closedir_plugin - sub file index ";
1683  msg << fco->file_descriptor();
1684  msg << " is out of range.";
1685  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
1686  }
1687 
1688  // =-=-=-=-=-=-=-
1689  // build a file close dir structure to pass off to the server api call
1690  fileClosedirInp_t fileClosedirInp;
1691  memset( &fileClosedirInp, 0, sizeof( fileClosedirInp ) );
1692  fileClosedirInp.fileInx = PluginTarSubFileDesc[ fco->file_descriptor() ].fd;
1693  int status = rsFileClosedir( _ctx.comm(), &fileClosedirInp );
1694  if ( status < 0 ) {
1695  return ERROR( status, "tar_file_closedir_plugin - failed on call to rsFileClosedir" );
1696  }
1697 
1698  // =-=-=-=-=-=-=-
1699  // close out the sub file index and free the allocation
1700  int struct_file_index = PluginTarSubFileDesc[ fco->file_descriptor() ].structFileInx;
1701  PluginStructFileDesc[ struct_file_index ].openCnt++;
1702  free_tar_sub_file_desc( fco->file_descriptor() );
1703  fco->file_descriptor( 0 );
1704 
1705  return CODE( status );
1706 
1707 } // tar_file_closedir_plugin
1708 
1709 // =-=-=-=-=-=-=-
1710 // interface for POSIX readdir
1712  irods::plugin_context& _ctx,
1713  struct rodsDirent** _dirent_ptr ) {
1714  // =-=-=-=-=-=-=-
1715  // check incoming parameters
1716  irods::error chk_err = tar_check_params( _ctx );
1717  if ( !chk_err.ok() ) {
1718  return PASSMSG( "tar_file_readdir_plugin", chk_err );
1719  }
1720 
1721  // =-=-=-=-=-=-=-
1722  // extract the fco
1723  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1724 
1725  // =-=-=-=-=-=-=-
1726  // check range on the sub file index
1727  if ( fco->file_descriptor() < 1 ||
1728  fco->file_descriptor() >= NUM_TAR_SUB_FILE_DESC ||
1729  PluginTarSubFileDesc[ fco->file_descriptor() ].inuseFlag == 0 ) {
1730  std::stringstream msg;
1731  msg << "tar_file_readdir_plugin - sub file index ";
1732  msg << fco->file_descriptor();
1733  msg << " is out of range.";
1734  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
1735  }
1736 
1737  // =-=-=-=-=-=-=-
1738  // build a file read dir structure to pass off to the server api call
1739  fileReaddirInp_t fileReaddirInp;
1740  memset( &fileReaddirInp, 0, sizeof( fileReaddirInp ) );
1741  fileReaddirInp.fileInx = PluginTarSubFileDesc[ fco->file_descriptor() ].fd;
1742 
1743  // =-=-=-=-=-=-=-
1744  // make the api call to read the directory
1745  int status = rsFileReaddir( _ctx.comm(), &fileReaddirInp, _dirent_ptr );
1746  if ( status < -1 ) {
1747  return ERROR( status, "tar_file_readdir_plugin - failed in call to rsFileReaddir" );
1748  }
1749 
1750  return CODE( status );
1751 
1752 } // tar_file_readdir_plugin
1753 
1754 // =-=-=-=-=-=-=-
1755 // interface for POSIX rename
1757  irods::plugin_context& _ctx,
1758  const char* _new_file_name ) {
1759  // =-=-=-=-=-=-=-
1760  // check incoming parameters
1761  irods::error chk_err = tar_check_params( _ctx );
1762  if ( !chk_err.ok() ) {
1763  return PASSMSG( "tar_file_rename_plugin", chk_err );
1764  }
1765 
1766  // =-=-=-=-=-=-=-
1767  // cast down the chain to our understood object type
1768  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1769 
1770  // =-=-=-=-=-=-=-
1771  // extract and check the special collection pointer
1772  specColl_t* spec_coll = fco->spec_coll();
1773  if ( !spec_coll ) {
1774  return ERROR( -1, "tar_file_rename_plugin - null spec_coll pointer in structure_object" );
1775  }
1776 
1777  // =-=-=-=-=-=-=-
1778  // extract and check the comm pointer
1779  rsComm_t* comm = fco->comm();
1780  if ( !comm ) {
1781  return ERROR( -1, "tar_file_rename_plugin - null comm pointer in structure_object" );
1782  }
1783 
1784  // =-=-=-=-=-=-=-
1785  // open and stage the tar file, get its index
1786  int struct_file_index = 0;
1787  std::string resc_host;
1788  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
1789  fco->resc_hier(), resc_host );
1790  if ( !open_err.ok() ) {
1791  std::stringstream msg;
1792  msg << "tar_file_rename_plugin - tar_struct_file_open error for [";
1793  msg << spec_coll->objPath;
1794  return PASSMSG( msg.str(), open_err );
1795  }
1796 
1797  // =-=-=-=-=-=-=-
1798  // use the cached specColl. specColl may have changed
1799  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1800 
1801  // =-=-=-=-=-=-=-
1802  // build a file rename structure to pass off to the server api call
1803  fileRenameInp_t fileRenameInp;
1804  memset( &fileRenameInp, 0, sizeof( fileRenameInp ) );
1805  snprintf( fileRenameInp.addr.hostAddr, NAME_LEN, "%s", resc_host.c_str() );
1806  snprintf( fileRenameInp.rescHier, MAX_NAME_LEN, "%s", fco->resc_hier().c_str() );
1807  snprintf( fileRenameInp.objPath, MAX_NAME_LEN, "%s", fco->logical_path().c_str() );
1808 
1809  // =-=-=-=-=-=-=-
1810  // build a physical path name to the cache dir
1811  irods::error comp_err_old = compose_cache_dir_physical_path( fileRenameInp.oldFileName,
1812  spec_coll,
1813  fco->sub_file_path().c_str() );
1814  if ( !comp_err_old.ok() ) {
1815  return PASSMSG(
1816  "tar_file_rename_plugin - compose_cache_dir_physical_path failed for old file name.",
1817  comp_err_old );
1818  }
1819 
1820  irods::error comp_err_new = compose_cache_dir_physical_path( fileRenameInp.newFileName,
1821  spec_coll,
1822  _new_file_name );
1823  if ( !comp_err_new.ok() ) {
1824  return PASSMSG(
1825  "tar_file_rename_plugin - compose_cache_dir_physical_path failed for new file name.",
1826  comp_err_new );
1827  }
1828 
1829  // =-=-=-=-=-=-=-
1830  // make the api call for rename
1831  fileRenameOut_t* ren_out = 0;
1832  int status = rsFileRename( comm, &fileRenameInp, &ren_out );
1833  free( ren_out );
1834  if ( status >= 0 ) {
1835  // use the specColl in PluginStructFileDesc
1836  specColl_t* loc_spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1837  // =-=-=-=-=-=-=-
1838  // cache has been written
1839  if ( loc_spec_coll->cacheDirty == 0 ) {
1840  loc_spec_coll->cacheDirty = 1;
1841  int status1 = modCollInfo2( comm, loc_spec_coll, 0 );
1842  if ( status1 < 0 ) {
1843  return ERROR( status1, "tar_file_rename_plugin - Failed to call modCollInfo2" );
1844  }
1845  }
1846 
1847  } // if status
1848 
1849  return CODE( status );
1850 
1851 } // tar_file_rename_plugin
1852 
1853 // =-=-=-=-=-=-=-
1854 // interface for POSIX truncate
1856  irods::plugin_context& _ctx ) {
1857  // =-=-=-=-=-=-=-
1858  // check incoming parameters
1859  irods::error chk_err = tar_check_params( _ctx );
1860  if ( !chk_err.ok() ) {
1861  return PASSMSG( "tar_file_truncate_plugin", chk_err );
1862  }
1863 
1864  // =-=-=-=-=-=-=-
1865  // cast down the chain to our understood object type
1866  irods::structured_object_ptr struct_obj = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1867 
1868  // =-=-=-=-=-=-=-
1869  // extract and check the special collection pointer
1870  specColl_t* spec_coll = struct_obj->spec_coll();
1871  if ( !spec_coll ) {
1872  return ERROR( -1, "tar_file_truncate_plugin - null spec_coll pointer in structure_object" );
1873  }
1874 
1875  // =-=-=-=-=-=-=-
1876  // extract and check the comm pointer
1877  rsComm_t* comm = struct_obj->comm();
1878  if ( !comm ) {
1879  return ERROR( -1, "tar_file_truncate_plugin - null comm pointer in structure_object" );
1880  }
1881 
1882  // =-=-=-=-=-=-=-
1883  // open and stage the tar file, get its index
1884  int struct_file_index = 0;
1885  std::string resc_host;
1886  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
1887  struct_obj->resc_hier(), resc_host );
1888  if ( !open_err.ok() ) {
1889  std::stringstream msg;
1890  msg << "tar_file_truncate_plugin - tar_struct_file_open error for [";
1891  msg << spec_coll->objPath;
1892  return PASSMSG( msg.str(), open_err );
1893  }
1894 
1895  // =-=-=-=-=-=-=-
1896  // use the cached specColl. specColl may have changed
1897  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
1898 
1899  // =-=-=-=-=-=-=-
1900  // allocate yet another index into another table
1901  int sub_index = alloc_tar_sub_file_desc();
1902  if ( sub_index < 0 ) {
1903  return ERROR( sub_index, "tar_file_truncate_plugin - alloc_tar_sub_file_desc failed." );
1904  }
1905 
1906  // =-=-=-=-=-=-=-
1907  // cache struct file index into sub file index
1908  PluginTarSubFileDesc[ sub_index ].structFileInx = struct_file_index;
1909 
1910  // =-=-=-=-=-=-=-
1911  // build a file create structure to pass off to the server api call
1912  fileOpenInp_t fileTruncateInp;
1913  memset( &fileTruncateInp, 0, sizeof( fileTruncateInp ) );
1914  snprintf( fileTruncateInp.addr.hostAddr, sizeof( fileTruncateInp.addr.hostAddr ), "%s", resc_host.c_str() );
1915  snprintf( fileTruncateInp.objPath, sizeof( fileTruncateInp.objPath ), "%s", struct_obj->logical_path().c_str() );
1916  fileTruncateInp.dataSize = struct_obj->offset();
1917 
1918  // =-=-=-=-=-=-=-
1919  // build a physical path name to the cache dir
1920  irods::error comp_err = compose_cache_dir_physical_path( fileTruncateInp.fileName,
1921  spec_coll,
1922  struct_obj->sub_file_path().c_str() );
1923  if ( !comp_err.ok() ) {
1924  return PASSMSG(
1925  "tar_file_truncate_plugin - compose_cache_dir_physical_path failed.", comp_err );
1926  }
1927 
1928  // =-=-=-=-=-=-=-
1929  // make the truncate api call
1930  int status = rsFileTruncate( comm, &fileTruncateInp );
1931  if ( status > 0 ) {
1932  // =-=-=-=-=-=-=-
1933  // cache has been written
1934  int struct_idx = PluginTarSubFileDesc[ struct_obj->file_descriptor() ].structFileInx;
1935  specColl_t* spec_coll = PluginStructFileDesc[ struct_idx ].specColl;
1936  if ( spec_coll->cacheDirty == 0 ) {
1937  spec_coll->cacheDirty = 1;
1938  int status1 = modCollInfo2( struct_obj->comm(), spec_coll, 0 );
1939  if ( status1 < 0 ) {
1940  return CODE( status1 );
1941  }
1942  }
1943  }
1944 
1945  return CODE( status );
1946 
1947 } // tar_file_truncate_plugin
1948 
1949 // =-=-=-=-=-=-=-
1950 // interface to extract a tar file
1952  irods::plugin_context& _ctx ) {
1953 
1954  // =-=-=-=-=-=-=-
1955  // check incoming parameters
1956  irods::error chk_err = tar_check_params( _ctx );
1957  if ( !chk_err.ok() ) {
1958  return PASSMSG( "tar_file_extract_plugin", chk_err );
1959  }
1960 
1961  // =-=-=-=-=-=-=-
1962  // cast down the chain to our understood object type
1963  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
1964 
1965  // =-=-=-=-=-=-=-
1966  // extract and check the special collection pointer
1967  specColl_t* spec_coll = fco->spec_coll();
1968  if ( !spec_coll ) {
1969  return ERROR( -1, "tar_file_extract_plugin - null spec_coll pointer in structure_object" );
1970  }
1971 
1972  // =-=-=-=-=-=-=-
1973  // extract and check the comm pointer
1974  rsComm_t* comm = fco->comm();
1975  if ( !comm ) {
1976  return ERROR( -1, "tar_file_extract_plugin - null comm pointer in structure_object" );
1977  }
1978 
1979  // =-=-=-=-=-=-=-
1980  // allocate a position in the struct table
1981  int struct_file_index = 0;
1982  if ( ( struct_file_index = alloc_struct_file_desc() ) < 0 ) {
1983  return ERROR( struct_file_index, "tar_file_extract_plugin - failed to allocate struct file descriptor" );
1984  }
1985 
1986  // =-=-=-=-=-=-=-
1987  // populate the file descriptor table
1988  PluginStructFileDesc[ struct_file_index ].inuseFlag = 1;
1989  PluginStructFileDesc[ struct_file_index ].specColl = spec_coll;
1990  PluginStructFileDesc[ struct_file_index ].rsComm = comm;
1991  snprintf( PluginStructFileDesc[ struct_file_index ].dataType,
1992  sizeof( PluginStructFileDesc[ struct_file_index ].dataType ),
1993  "%s", fco->data_type().c_str() );
1994 
1995  // =-=-=-=-=-=-=-
1996  // extract the file
1997  irods::error ext_err = extract_file( struct_file_index );
1998  if ( !ext_err.ok() ) {
1999  // NOTE:: may need to remove the cacheDir too
2000  std::stringstream msg;
2001  msg << "tar_file_extract_plugin - failed to extact structure file for [";
2002  msg << spec_coll->objPath;
2003  msg << "] in directory [";
2004  msg << spec_coll->cacheDir;
2005  msg << "] with errno of ";
2006  msg << errno;
2007  return PASSMSG( msg.str(), ext_err );
2008  }
2009 
2010  // =-=-=-=-=-=-=-
2011  // if the left over cache dir has a symlink in it, remove the
2012  // directory ( addresses Wisc Security Issue r4906 )
2013  if ( hasSymlinkInDir( spec_coll->cacheDir ) ) {
2014  rodsLog( LOG_ERROR, "extractTarFile: cacheDir %s has symlink in it",
2015  spec_coll->cacheDir );
2016 
2017  rodsHostAddr_t* host_addr = NULL;
2018  _ctx.prop_map().get< rodsHostAddr_t* >( irods::RESOURCE_LOCATION, host_addr );
2019 
2020  if ( NULL == host_addr ) {
2021  return ERROR( SYS_INTERNAL_NULL_INPUT_ERR, "host_addr is null in rmDir" );
2022  }
2023  /* remove cache */
2024  fileRmdirInp_t fileRmdirInp;
2025  memset( &fileRmdirInp, 0, sizeof( fileRmdirInp ) );
2026  rstrcpy( fileRmdirInp.dirName, spec_coll->cacheDir, MAX_NAME_LEN );
2027  rstrcpy( fileRmdirInp.addr.hostAddr, host_addr->hostAddr, NAME_LEN );
2028  rstrcpy( fileRmdirInp.rescHier, spec_coll->rescHier, MAX_NAME_LEN );
2029 
2030  fileRmdirInp.flags = RMDIR_RECUR;
2031  int status = rsFileRmdir( comm, &fileRmdirInp );
2032  if ( status < 0 ) {
2033  std::stringstream msg;
2034  msg << "tar_file_extract_plugin - rmdir error for [";
2035  msg << spec_coll->cacheDir << "]";
2036  return ERROR( status, msg.str() );
2037  }
2038 
2039  } // if hasSymlinkInDir
2040 
2041  return CODE( ext_err.code() );
2042 
2043 } // tar_file_extract_plugin
2044 
2045 // =-=-=-=-=-=-=-
2046 // helper function to write an archive entry
2047 irods::error write_file_to_archive( const boost::filesystem::path _path,
2048  const std::string& _cache_dir,
2049  struct archive* _archive ) {
2050  namespace fs = boost::filesystem;
2051  struct archive_entry* entry = archive_entry_new();
2052 
2053  // =-=-=-=-=-=-=-
2054  // strip arch path from file name for header entry
2055  std::string path_name = _path.string();
2056  std::string strip_file = path_name.substr( _cache_dir.size() + 1 ); // add one for the last '/'
2057  archive_entry_set_pathname( entry, strip_file.c_str() );
2058 
2059  // =-=-=-=-=-=-=-
2060  // ask for the file size
2061  archive_entry_set_size( entry, fs::file_size( _path ) );
2062  archive_entry_set_filetype( entry, AE_IFREG );
2063 
2064  // =-=-=-=-=-=-=-
2065  // set the permissions
2066  //fs::perms pp;
2067  //fs::permissions( _path, pp );
2068  archive_entry_set_perm( entry, 0600 );
2069 
2070  // =-=-=-=-=-=-=-
2071  // set the time for the file
2072  std::time_t tt = last_write_time( _path );
2073  archive_entry_set_mtime( entry, tt, 0 );
2074 
2075  // =-=-=-=-=-=-=-
2076  // write out the header to the archive
2077  if ( archive_write_header( _archive, entry ) != ARCHIVE_OK ) {
2078  std::stringstream msg;
2079  msg << "write_file_to_archive - failed to write entry header for [";
2080  msg << path_name;
2081  msg << "] with error string [";
2082  msg << archive_error_string( _archive );
2083  msg << "]";
2084  return ERROR( -1, msg.str() );
2085  }
2086 
2087  // =-=-=-=-=-=-=-
2088  // JMC :: i didnt use ifstream as readsome() garbled the file
2089  // :: some reason. revisit this for windows
2090  // =-=-=-=-=-=-=-
2091  // open the file in question
2092  int fd = open( path_name.c_str(), O_RDONLY );
2093  if ( -1 == fd ) {
2094  std::stringstream msg;
2095  msg << "write_file_to_archive - failed to open file for read [";
2096  msg << path_name;
2097  msg << "] with error [";
2098  msg << strerror( errno );
2099  msg << "]";
2100  return ERROR( -1, msg.str() );
2101  }
2102 
2103  // =-=-=-=-=-=-=-
2104  // read in the file and add it to the archive
2105  char buff[ 16384 ];
2106  int len = read( fd, buff, sizeof( buff ) );
2107  while ( len > 0 ) {
2108  archive_write_data( _archive, buff, len );
2109  len = read( fd, buff, sizeof( buff ) );
2110  }
2111 
2112  // =-=-=-=-=-=-=-
2113  // clean up
2114  close( fd );
2115  archive_entry_free( entry );
2116 
2117  return SUCCESS();
2118 
2119 } // write_file_to_archive
2120 
2121 // =-=-=-=-=-=-=-
2122 // helper function for recursive directory scanning
2123 irods::error build_directory_listing( const boost::filesystem::path& _path,
2124  std::vector< boost::filesystem::path >& _listing ) {
2125  // =-=-=-=-=-=-=-
2126  // namespace alias for brevity
2127  namespace fs = boost::filesystem;
2128  irods::error final_error = SUCCESS();
2129 
2130  // =-=-=-=-=-=-=-
2131  // begin iterating over the cache dir
2132  try {
2133  if ( fs::is_directory( _path ) ) {
2134  // =-=-=-=-=-=-=-
2135  // iterate over the directory and archive it
2136  fs::directory_iterator end_iter;
2137  fs::directory_iterator dir_itr( _path );
2138  for ( ; dir_itr != end_iter; ++dir_itr ) {
2139  // =-=-=-=-=-=-=-
2140  // recurse on this new directory
2141  irods::error ret = build_directory_listing( dir_itr->path(), _listing );
2142  if ( !ret.ok() ) {
2143  std::stringstream msg;
2144  msg << "build_directory_listing - failed on [";
2145  msg << dir_itr->path().string();
2146  msg << "]";
2147  final_error = PASSMSG( msg.str(), final_error );
2148  }
2149 
2150  } // for dir_itr
2151 
2152  }
2153  else if ( fs::is_regular_file( _path ) ) {
2154  // =-=-=-=-=-=-=-
2155  // add file path to the vector
2156  _listing.push_back( _path );
2157 
2158  }
2159  else {
2160  std::stringstream msg;
2161  msg << "build_directory_listing - unhandled entry [";
2162  msg << _path.filename();
2163  msg << "]";
2164  rodsLog( LOG_NOTICE, "%s", msg.str().c_str() );
2165  }
2166 
2167  }
2168  catch ( const std::exception& ex ) {
2169  std::stringstream msg;
2170  msg << "build_directory_listing - caught exception [";
2171  msg << ex.what();
2172  msg << "] for directory entry [";
2173  msg << _path.filename();
2174  msg << "]";
2175  return ERROR( -1, msg.str() );
2176 
2177  }
2178 
2179  return final_error;
2180 
2181 } // build_directory_listing
2182 
2183 // =-=-=-=-=-=-=-
2184 // create an archive from the cache directory
2186  std::string _data_type ) {
2187  // =-=-=-=-=-=-=-
2188  // namespace alias for brevity
2189  namespace fs = boost::filesystem;
2190 
2191  // =-=-=-=-=-=-=-
2192  // check struct desc table in use flag
2193  if ( PluginStructFileDesc[ _index ].inuseFlag <= 0 ) {
2194  std::stringstream msg;
2195  msg << "bundle_cache_dir - struct file index: ";
2196  msg << _index;
2197  msg << " is not in use";
2198  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
2199  }
2200 
2201  // =-=-=-=-=-=-=-
2202  // check struct desc table in use flag
2203  specColl_t* spec_coll = PluginStructFileDesc[ _index ].specColl;
2204  if ( spec_coll == NULL ||
2205  spec_coll->cacheDirty <= 0 ||
2206  strlen( spec_coll->cacheDir ) == 0 ||
2207  strlen( spec_coll->phyPath ) == 0 ) {
2208  std::stringstream msg;
2209  msg << "bundle_cache_dir - bad special collection for index: ";
2210  msg << _index;
2211  return ERROR( SYS_STRUCT_FILE_DESC_ERR, msg.str() );
2212 
2213  }
2214 
2215  // =-=-=-=-=-=-=-
2216  // create a boost filesystem path for the cache directory
2217  fs::path full_path;//( fs::initial_path<fs::path>() );
2218  full_path = fs::system_complete( fs::path( spec_coll->cacheDir ) );
2219 
2220  // =-=-=-=-=-=-=-
2221  // check if the path is really there, just in case
2222  if ( !fs::exists( full_path ) ) {
2223  std::stringstream msg;
2224  msg << "bundle_cache_dir - cache directory does not exist [";
2225  msg << spec_coll->cacheDir;
2226  msg << "]";
2227  return ERROR( -1, msg.str() );
2228  }
2229 
2230  // =-=-=-=-=-=-=-
2231  // make sure it is a directory, just in case
2232  if ( !fs::is_directory( full_path ) ) {
2233  std::stringstream msg;
2234  msg << "bundle_cache_dir - cache directory is not actually a directory [";
2235  msg << spec_coll->cacheDir;
2236  msg << "]";
2237  return ERROR( -1, msg.str() );
2238  }
2239 
2240  // =-=-=-=-=-=-=-
2241  // build a listing of all of the files in all of the subdirs
2242  // in the full_path
2243  std::vector< fs::path > listing;
2244  build_directory_listing( full_path, listing );
2245 
2246  // =-=-=-=-=-=-=-
2247  // create the archive
2248  struct archive* arch = archive_write_new();
2249  if ( !arch ) {
2250  std::stringstream msg;
2251  msg << "bundle_cache_dir - failed to create archive struct for [";
2252  msg << spec_coll->cacheDir;
2253  msg << "] into archive file [";
2254  msg << spec_coll->phyPath;
2255  msg << "]";
2256  return ERROR( -1, msg.str() );
2257 
2258  }
2259 
2260  // =-=-=-=-=-=-=-
2261  // set the compression flags given data_type
2262  if ( _data_type == ZIP_DT_STR ) {
2263  if ( archive_write_set_format_zip( arch ) != ARCHIVE_OK ) {
2264  std::stringstream msg;
2265  msg << "bundle_cache_dir - failed to set format to zip for archive [";
2266  msg << spec_coll->phyPath;
2267  msg << "] with error string [";
2268  msg << archive_error_string( arch );
2269  msg << "]";
2270  return ERROR( -1, msg.str() );
2271 
2272  }
2273 
2274  }
2275  else if ( _data_type == GZIP_TAR_DT_STR ) {
2276  if ( archive_write_add_filter_gzip( arch ) != ARCHIVE_OK ) {
2277  std::stringstream msg;
2278  msg << "bundle_cache_dir - failed to set compression to gzip for archive [";
2279  msg << spec_coll->phyPath;
2280  msg << "] with error string [";
2281  msg << archive_error_string( arch );
2282  msg << "]";
2283  return ERROR( -1, msg.str() );
2284 
2285  }
2286 
2287  // =-=-=-=-=-=-=-
2288  // set the format of the tar archive
2289  archive_write_set_format_ustar( arch );
2290 
2291  }
2292  else if ( _data_type == BZIP2_TAR_DT_STR ) {
2293  if ( archive_write_add_filter_bzip2( arch ) != ARCHIVE_OK ) {
2294  std::stringstream msg;
2295  msg << "bundle_cache_dir - failed to set compression to bzip2 for archive [";
2296  msg << spec_coll->phyPath;
2297  msg << "] with error string [";
2298  msg << archive_error_string( arch );
2299  msg << "]";
2300  return ERROR( -1, msg.str() );
2301 
2302  }
2303 
2304  // =-=-=-=-=-=-=-
2305  // set the format of the tar archive
2306  archive_write_set_format_ustar( arch );
2307 
2308  }
2309  else {
2310  if ( archive_write_add_filter_none( arch ) != ARCHIVE_OK ) {
2311  std::stringstream msg;
2312  msg << "bundle_cache_dir - failed to set compression to none for archive [";
2313  msg << spec_coll->phyPath;
2314  msg << "] with error string [";
2315  msg << archive_error_string( arch );
2316  msg << "]";
2317  return ERROR( -1, msg.str() );
2318 
2319  }
2320 
2321  // =-=-=-=-=-=-=-
2322  // set the format of the tar archive
2323  archive_write_set_format_ustar( arch );
2324 
2325  }
2326 
2327  // =-=-=-=-=-=-=-
2328  // extract the host location from the resource hierarchy
2329  std::string location;
2330  irods::error ret = irods::get_loc_for_hier_string( spec_coll->rescHier, location );
2331  if ( !ret.ok() ) {
2332  return PASSMSG( "bundle_cache_dir - failed in get_loc_for_hier_string", ret );
2333  }
2334 
2335  // =-=-=-=-=-=-=-
2336  // create a context to pass to the callbacks
2337  cb_ctx_t cb_ctx;
2338  memset( &cb_ctx, 0, sizeof( cb_ctx_t ) );
2339  cb_ctx.desc_ = &PluginStructFileDesc[ _index ];
2340  snprintf( cb_ctx.loc_, sizeof( cb_ctx.loc_ ), "%s", location.c_str() );
2341 
2342  // =-=-=-=-=-=-=-
2343  // open the spec coll physical path for archival
2344  if ( archive_write_open(
2345  arch,
2346  &cb_ctx,
2349  irods_file_close ) < ARCHIVE_OK ) {
2350  std::stringstream msg;
2351  msg << "bundle_cache_dir - failed to open archive file [";
2352  msg << spec_coll->phyPath;
2353  msg << "] with error string [";
2354  msg << archive_error_string( arch );
2355  msg << "]";
2356  return ERROR( -1, msg.str() );
2357  }
2358 
2359  // =-=-=-=-=-=-=-
2360  // iterate over the dir listing and archive the files
2361  std::string cache_dir( spec_coll->cacheDir );
2362  irods::error arch_err = SUCCESS();
2363  for ( size_t i = 0; i < listing.size(); ++i ) {
2364  // =-=-=-=-=-=-=-
2365  // strip off archive path from the filename
2366  irods::error ret = write_file_to_archive( listing[ i ].string(), cache_dir, arch );
2367 
2368  if ( !ret.ok() ) {
2369  std::stringstream msg;
2370  msg << "bundle_cache_dir - failed to archive file [";
2371  msg << listing[ i ].string();
2372  msg << "]";
2373  arch_err = PASSMSG( msg.str(), arch_err );
2374  irods::log( PASSMSG( msg.str(), ret ) );
2375  }
2376 
2377  } // for i
2378 
2379  // =-=-=-=-=-=-=-
2380  // close the archive and clean up
2381  archive_write_close( arch );
2382  archive_write_free( arch );
2383 
2384  // =-=-=-=-=-=-=-
2385  // handle errors
2386  if ( !arch_err.ok() ) {
2387  std::stringstream msg;
2388  msg << "bundle_cache_dir - failed to archive [";
2389  msg << spec_coll->cacheDir;
2390  msg << "] into archive file [";
2391  msg << spec_coll->phyPath;
2392  msg << "]";
2393  return PASSMSG( msg.str(), arch_err );
2394 
2395  }
2396  else {
2397  return SUCCESS();
2398 
2399  }
2400 
2401 } // bundle_cache_dir
2402 
2403 // =-=-=-=-=-=-=-
2404 // interface for tar / zip up of cache dir which also updates
2405 // the icat with the new file size
2407  int _opr_type,
2408  std::string _host ) {
2409  specColl_t* spec_coll = PluginStructFileDesc[ _index ].specColl;
2410  rsComm_t* comm = PluginStructFileDesc[ _index ].rsComm;
2411 
2412  // =-=-=-=-=-=-=-
2413  // call bundle helper functions
2414  irods::error bundle_err = bundle_cache_dir( _index, PluginStructFileDesc[ _index ].dataType );
2415  if ( !bundle_err.ok() ) {
2416  return PASSMSG( "sync_cache_dir_to_tar_file - failed in bundle.", bundle_err );
2417  }
2418 
2419  // =-=-=-=-=-=-=-
2420  // create a file stat structure for the rs call
2421  fileStatInp_t file_stat_inp;
2422  memset( &file_stat_inp, 0, sizeof( file_stat_inp ) );
2423  rstrcpy( file_stat_inp.fileName, spec_coll->phyPath, MAX_NAME_LEN );
2424  snprintf( file_stat_inp.addr.hostAddr, NAME_LEN, "%s", _host.c_str() );
2425  snprintf( file_stat_inp.rescHier, MAX_NAME_LEN, "%s", spec_coll->rescHier );
2426  snprintf( file_stat_inp.objPath, MAX_NAME_LEN, "%s", spec_coll->objPath );
2427 
2428  // =-=-=-=-=-=-=-
2429  // call file stat api to get the size of the new file
2430  rodsStat_t* file_stat_out = NULL;
2431  int status = rsFileStat( comm, &file_stat_inp, &file_stat_out );
2432  if ( status < 0 || NULL == file_stat_out ) {
2433  std::stringstream msg;
2434  msg << "sync_cache_dir_to_tar_file - failed on call to rsFileStat for [";
2435  msg << spec_coll->phyPath;
2436  msg << "] with status of ";
2437  msg << status;
2438  return ERROR( status, msg.str() );
2439 
2440  }
2441 
2442  // =-=-=-=-=-=-=-
2443  // update icat with the new size of the file
2444  if ( ( _opr_type & NO_REG_COLL_INFO ) == 0 ) {
2445  // NOTE :: for bundle opr, done at datObjClose
2446  status = regNewObjSize( comm, spec_coll->objPath, spec_coll->replNum, file_stat_out->st_size );
2447 
2448  }
2449 
2450  free( file_stat_out );
2451 
2452  return CODE( status );
2453 
2454 } // sync_cache_dir_to_tar_file
2455 
2456 // =-=-=-=-=-=-=-
2457 // interface for sync up of cache dir
2459  irods::plugin_context& _ctx ) {
2460  // =-=-=-=-=-=-=-
2461  // check incoming parameters
2462  irods::error chk_err = tar_check_params( _ctx );
2463  if ( !chk_err.ok() ) {
2464  return PASSMSG( "tar_file_sync_plugin", chk_err );
2465  }
2466 
2467  // =-=-=-=-=-=-=-
2468  // cast down the chain to our understood object type
2469  irods::structured_object_ptr fco = boost::dynamic_pointer_cast< irods::structured_object >( _ctx.fco() );
2470 
2471  // =-=-=-=-=-=-=-
2472  // extract and check the special collection pointer
2473  specColl_t* spec_coll = fco->spec_coll();
2474  if ( !spec_coll ) {
2475  return ERROR( -1, "tar_file_sync_plugin - null spec_coll pointer in structure_object" );
2476  }
2477 
2478  // =-=-=-=-=-=-=-
2479  // extract and check the comm pointer
2480  rsComm_t* comm = fco->comm();
2481  if ( !comm ) {
2482  return ERROR( -1, "tar_file_sync_plugin - null comm pointer in structure_object" );
2483  }
2484 
2485  // =-=-=-=-=-=-=-
2486  // open and stage the tar file, get its index
2487  int struct_file_index = 0;
2488  std::string resc_host;
2489  irods::error open_err = tar_struct_file_open( comm, spec_coll, struct_file_index,
2490  fco->resc_hier(), resc_host );
2491  if ( !open_err.ok() ) {
2492  std::stringstream msg;
2493  msg << "tar_file_sync_plugin - tar_struct_file_open error for [";
2494  msg << spec_coll->objPath;
2495  return PASSMSG( msg.str(), open_err );
2496  }
2497 
2498  // =-=-=-=-=-=-=-
2499  // copy the data type requested by user for compression
2500  snprintf( PluginStructFileDesc[ struct_file_index ].dataType, NAME_LEN, "%s", fco->data_type().c_str() );
2501 
2502  // =-=-=-=-=-=-=-
2503  // use the cached specColl. specColl may have changed
2504  spec_coll = PluginStructFileDesc[ struct_file_index ].specColl;
2505 
2506  // =-=-=-=-=-=-=-
2507  // we cant sync if the structured collection is currently in use
2508  if ( PluginStructFileDesc[ struct_file_index ].openCnt > 0 ) {
2509  return ERROR( SYS_STRUCT_FILE_BUSY_ERR, "tar_file_sync_plugin - spec coll in use" );
2510  }
2511 
2512  // =-=-=-=-=-=-=-
2513  // delete operation
2514  if ( ( fco->opr_type() & DELETE_STRUCT_FILE ) != 0 ) {
2515  /* remove cache and the struct file */
2516  free_struct_file_desc( struct_file_index );
2517  return SUCCESS();
2518  }
2519 
2520  // =-=-=-=-=-=-=-
2521  // check if there is a specified cache directory,
2522  // if not then any other operation isn't possible
2523  if ( strlen( spec_coll->cacheDir ) > 0 ) {
2524  if ( spec_coll->cacheDirty > 0 ) {
2525  // =-=-=-=-=-=-=-
2526  // write the tar file and register no dirty
2527  irods::error sync_err = sync_cache_dir_to_tar_file( struct_file_index,
2528  fco->opr_type(),
2529  resc_host );
2530  if ( !sync_err.ok() ) {
2531  std::stringstream msg;
2532  msg << "tar_file_sync_plugin - failed in sync_cache_dir_to_tar_file for [";
2533  msg << spec_coll->cacheDir;
2534  msg << "] with status of ";
2535  msg << sync_err.code() << "]";
2536 
2537  free_struct_file_desc( struct_file_index );
2538  return PASSMSG( msg.str(), sync_err );
2539  }
2540 
2541  spec_coll->cacheDirty = 0;
2542  if ( ( fco->opr_type() & NO_REG_COLL_INFO ) == 0 ) {
2543  int status = modCollInfo2( comm, spec_coll, 0 );
2544  if ( status < 0 ) {
2545  free_struct_file_desc( struct_file_index );
2546  return ERROR( status, "tar_file_sync_plugin - failed in modCollInfo2" );
2547 
2548  } // if status
2549 
2550  }
2551 
2552  } // if cache is dirty
2553 
2554  // =-=-=-=-=-=-=-
2555  // remove cache dir if necessary
2556  if ( ( fco->opr_type() & PURGE_STRUCT_FILE_CACHE ) != 0 ) {
2557  // =-=-=-=-=-=-=-
2558  // need to unregister the cache before removing it
2559  int status = modCollInfo2( comm, spec_coll, 1 );
2560  if ( status < 0 ) {
2561  free_struct_file_desc( struct_file_index );
2562  return ERROR( status, "tar_file_sync_plugin - failed in modCollInfo2" );
2563  }
2564 
2565  // =-=-=-=-=-=-=-
2566  // use the irods api to remove the directory
2567  fileRmdirInp_t rmdir_inp;
2568  memset( &rmdir_inp, 0, sizeof( rmdir_inp ) );
2569  rmdir_inp.flags = RMDIR_RECUR;
2570  rstrcpy( rmdir_inp.dirName, spec_coll->cacheDir, MAX_NAME_LEN );
2571  snprintf( rmdir_inp.addr.hostAddr, NAME_LEN, "%s", resc_host.c_str() );
2572  snprintf( rmdir_inp.rescHier, MAX_NAME_LEN, "%s", spec_coll->rescHier );
2573 
2574  status = rsFileRmdir( comm, &rmdir_inp );
2575  if ( status < 0 ) {
2576  free_struct_file_desc( struct_file_index );
2577  return ERROR( status, "tar_file_sync_plugin - failed in call to rsFileRmdir" );
2578  }
2579 
2580  } // if purge file cache
2581 
2582  } // if we have a cache dir
2583 
2584  free_struct_file_desc( struct_file_index );
2585 
2586  return SUCCESS();
2587 
2588 } // tar_file_sync_plugin
2589 
2590 // =-=-=-=-=-=-=-
2591 // interface for getting freespace of the fs
2594  return ERROR( SYS_NOT_SUPPORTED, "tar_file_getfs_freespace_plugin is not implemented" );
2595 
2596 } // tar_file_getfs_freespace_plugin
2597 
2602  // NOOP
2603  return SUCCESS();
2604 }
2605 
2610  // NOOP
2611  return SUCCESS();
2612 }
2613 
2618  // NOOP
2619  return SUCCESS();
2620 }
2621 
2622 // =-=-=-=-=-=-=-
2623 // tar_file_rebalance - code which would rebalance the subtree
2626  return SUCCESS();
2627 
2628 } // tar_file_rebalance
2629 
2630 // =-=-=-=-=-=-=-
2631 // tar_file_notify - code which would notify the subtree of a change
2634  const std::string* ) {
2635  return SUCCESS();
2636 
2637 } // tar_file_notify
2638 
2639 
2640 // =-=-=-=-=-=-=-
2641 // 3. create derived class to handle tar file system resources
2642 // necessary to do custom parsing of the context string to place
2643 // any useful values into the property map for reference in later
2644 // operations. semicolon is the preferred delimiter
2646  public:
2648  const std::string& _inst_name,
2649  const std::string& _context ) :
2650  irods::resource( _inst_name, _context ) {
2651  } // ctor
2652 
2653 }; // class tarfilesystem_resource
2654 
2655 // =-=-=-=-=-=-=-
2656 // 4. create the plugin factory function which will return a dynamically
2657 // instantiated object of the previously defined derived resource. use
2658 // the add_operation member to associate a 'call name' to the interfaces
2659 // defined above. for resource plugins these call names are standardized
2660 // as used by the irods facing interface defined in
2661 // server/drivers/src/fileDriver.c
2662 extern "C"
2663 irods::resource* plugin_factory( const std::string& _inst_name, const std::string& _context ) {
2664 
2665  // =-=-=-=-=-=-=-
2666  // 4a. create tarfilesystem_resource
2667  tarfilesystem_resource* resc = new tarfilesystem_resource( _inst_name, _context );
2668 
2669  // =-=-=-=-=-=-=-
2670  // 4b1. set start and stop operations for alloc / free of tables
2673 
2674  // =-=-=-=-=-=-=-
2675  // 4b2. map function names to operations. this map will be used to load
2676  // the symbols from the shared object in the delay_load stage of
2677  // plugin loading.
2678  using namespace irods;
2679  using namespace std;
2680  resc->add_operation(
2682  function<error(plugin_context&)>(
2683  tar_file_create ) );
2684 
2685  resc->add_operation(
2687  function<error(plugin_context&)>(
2688  tar_file_open ) );
2689 
2690  resc->add_operation<void*,int>(
2692  std::function<
2693  error(irods::plugin_context&,void*,int)>(
2694  tar_file_read ) );
2695 
2696  resc->add_operation<void*,int>(
2698  function<error(plugin_context&,void*,int)>(
2699  tar_file_write ) );
2700 
2701  resc->add_operation(
2703  function<error(plugin_context&)>(
2704  tar_file_close ) );
2705 
2706  resc->add_operation(
2708  function<error(plugin_context&)>(
2709  tar_file_unlink ) );
2710 
2711  resc->add_operation<struct stat*>(
2713  function<error(plugin_context&, struct stat*)>(
2714  tar_file_stat ) );
2715 
2716  resc->add_operation(
2718  function<error(plugin_context&)>(
2719  tar_file_mkdir ) );
2720 
2721  resc->add_operation(
2723  function<error(plugin_context&)>(
2724  tar_file_opendir ) );
2725 
2726  resc->add_operation<struct rodsDirent**>(
2728  function<error(plugin_context&,struct rodsDirent**)>(
2729  tar_file_readdir ) );
2730 
2731  resc->add_operation<const char*>(
2733  function<error(plugin_context&, const char*)>(
2734  tar_file_rename ) );
2735 
2736  resc->add_operation(
2738  function<error(plugin_context&)>(
2740 
2741  resc->add_operation<long long, int>(
2743  function<error(plugin_context&, long long, int)>(
2744  tar_file_lseek ) );
2745 
2746  resc->add_operation(
2748  function<error(plugin_context&)>(
2749  tar_file_rmdir ) );
2750 
2751  resc->add_operation(
2753  function<error(plugin_context&)>(
2754  tar_file_closedir ) );
2755 
2756  resc->add_operation(
2758  function<error(plugin_context&)>(
2759  tar_file_registered ) );
2760 
2761  resc->add_operation(
2763  function<error(plugin_context&)>(
2765 
2766  resc->add_operation(
2768  function<error(plugin_context&)>(
2769  tar_file_modified ) );
2770 
2771  resc->add_operation<const std::string*>(
2773  function<error(plugin_context&, const std::string*)>(
2774  tar_file_notify ) );
2775 
2776  resc->add_operation(
2778  function<error(plugin_context&)>(
2779  tar_file_truncate ) );
2780 
2781  resc->add_operation(
2783  function<error(plugin_context&)>(
2784  tar_file_rebalance ) );
2785 
2786  // =-=-=-=-=-=-=-
2787  // struct file specific operations
2788  resc->add_operation(
2789  "extract",
2790  function<error(plugin_context&)>(
2791  tar_file_extract ) );
2792 
2793  resc->add_operation(
2794  "sync",
2795  function<error(plugin_context&)>(
2796  tar_file_sync ) );
2797 
2798  // =-=-=-=-=-=-=-
2799  // 4c. return the pointer through the generic interface of an
2800  // irods::resource pointer
2801  return dynamic_cast<irods::resource*>( resc );
2802 
2803 } // plugin_factory
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
rsFileWrite.hpp
NULL
#define NULL
Definition: rodsDef.h:70
irods::RESOURCE_LOCATION
const std::string RESOURCE_LOCATION("resource_property_location")
fileReaddirInp_t::fileInx
int fileInx
Definition: fileReaddir.h:8
rsComm_t
Definition: rcConnect.h:145
tar_file_readdir
irods::error tar_file_readdir(irods::plugin_context &_ctx, struct rodsDirent **_dirent_ptr)
Definition: libstructfile.cpp:1711
fileOpen.h
NO_REG_COLL_INFO
#define NO_REG_COLL_INFO
Definition: syncMountedColl.h:10
rsFileRmdir
int rsFileRmdir(rsComm_t *rsComm, fileRmdirInp_t *fileRmdirInp)
Definition: rsFileRmdir.cpp:21
rsFileMkdir.hpp
SYS_INTERNAL_NULL_INPUT_ERR
@ SYS_INTERNAL_NULL_INPUT_ERR
Definition: rodsErrorTable.h:92
tarSubFileDesc_t
struct tarSubFileDesc tarSubFileDesc_t
irods::lookup_table< boost::any >
cb_ctx_t::loc_
char loc_[64]
Definition: libstructfile.cpp:146
FileReadInp::len
int len
Definition: fileRead.h:9
rsFileOpen.hpp
rsFileWrite
int rsFileWrite(rsComm_t *rsComm, fileWriteInp_t *fileWriteInp, bytesBuf_t *fileWriteInpBBuf)
Definition: rsFileWrite.cpp:20
irods::RESOURCE_OP_STAT
const std::string RESOURCE_OP_STAT("resource_stat")
specColl.hpp
irods_file_open_for_write
int irods_file_open_for_write(struct archive *_arch, void *_data)
Definition: libstructfile.cpp:196
write_file_to_archive
irods::error write_file_to_archive(const boost::filesystem::path _path, const std::string &_cache_dir, struct archive *_archive)
Definition: libstructfile.cpp:2047
tar_file_modified
irods::error tar_file_modified(irods::plugin_context &)
Definition: libstructfile.cpp:2616
tar_file_write
irods::error tar_file_write(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: libstructfile.cpp:1050
modColl.h
BytesBuf::buf
void * buf
Definition: rodsDef.h:199
irods::plugin_context::valid
virtual error valid()
Definition: irods_plugin_context.hpp:77
SpecColl::resource
char resource[64]
Definition: objInfo.h:83
irods::resource
Definition: irods_resource_plugin.hpp:25
compose_cache_dir_physical_path
irods::error compose_cache_dir_physical_path(char *_phy_path, specColl_t *_spec_coll, const char *_sub_file_path)
Definition: libstructfile.cpp:740
fileRmdirInp_t::addr
rodsHostAddr_t addr
Definition: fileRmdir.h:12
irods_file_open_for_read
int irods_file_open_for_read(struct archive *_arch, void *_data)
Definition: libstructfile.cpp:190
fileOpenInp_t::resc_name_
char resc_name_[(1024+64)]
Definition: fileOpen.h:15
tar_file_lseek
irods::error tar_file_lseek(irods::plugin_context &_ctx, long long _offset, int _whence)
Definition: libstructfile.cpp:1332
irods::RESOURCE_OP_MODIFIED
const std::string RESOURCE_OP_MODIFIED("resource_modified")
resc_mgr
irods::resource_manager resc_mgr
Definition: irods_resource_manager.cpp:31
fileClosedirInp_t
Definition: fileClosedir.h:6
irods_file_close
int irods_file_close(struct archive *_arch, void *_data)
Definition: libstructfile.cpp:251
irods_file_object.hpp
irods::RESOURCE_OP_CLOSEDIR
const std::string RESOURCE_OP_CLOSEDIR("resource_closedir")
tar_file_closedir
irods::error tar_file_closedir(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:1663
getSpecCollCache
int getSpecCollCache(rsComm_t *rsComm, char *objPath, int inCachOnly, specCollCache_t **specCollCache)
Definition: specColl.cpp:255
irods_collection_object.hpp
irods::resource_ptr
boost::shared_ptr< resource > resource_ptr
Definition: irods_resource_types.hpp:11
tar_struct_file_open
irods::error tar_struct_file_open(rsComm_t *_comm, specColl_t *_spec_coll, int &_struct_desc_index, const std::string &_resc_hier, std::string &_resc_host)
Definition: libstructfile.cpp:620
fileClosedirInp_t::fileInx
int fileInx
Definition: fileClosedir.h:7
BZIP2_TAR_DT_STR
#define BZIP2_TAR_DT_STR
Definition: objInfo.h:30
rsFileStat
int rsFileStat(rsComm_t *rsComm, fileStatInp_t *fileStatInp, rodsStat_t **fileStatOut)
Definition: rsFileStat.cpp:18
fileRenameOut_t
Definition: fileRename.h:16
SpecColl::cacheDirty
int cacheDirty
Definition: objInfo.h:92
rsFileTruncate
int rsFileTruncate(rsComm_t *rsComm, fileOpenInp_t *fileTruncateInp)
Definition: rsFileTruncate.cpp:17
irods::RESOURCE_OP_READDIR
const std::string RESOURCE_OP_READDIR("resource_readdir")
SpecColl::phyPath
char phyPath[(1024+64)]
Definition: objInfo.h:85
make_tar_cache_dir
irods::error make_tar_cache_dir(int _index, std::string _host)
Definition: libstructfile.cpp:423
irods::experimental::administration::client::v1::exists
auto exists(rcComm_t &conn, const user &user) -> bool
Definition: user_administration.cpp:359
irods::hierarchy_parser
Definition: irods_hierarchy_parser.hpp:14
alloc_tar_sub_file_desc
int alloc_tar_sub_file_desc()
Definition: libstructfile.cpp:770
NO_CHK_PERM_FLAG
#define NO_CHK_PERM_FLAG
Definition: fileOpen.h:10
PluginTarSubFileDesc
tarSubFileDesc_t PluginTarSubFileDesc[20]
Definition: libstructfile.cpp:89
SpecColl::cacheDir
char cacheDir[(1024+64)]
Definition: objInfo.h:89
rsFileRename
int rsFileRename(rsComm_t *rsComm, fileRenameInp_t *fileRenameInp, fileRenameOut_t **)
Definition: rsFileRename.cpp:22
fileStatInp_t
Definition: fileStat.h:7
fileMkdirInp_t::mode
int mode
Definition: fileMkdir.h:11
irods::experimental::filesystem::client::last_write_time
auto last_write_time(rcComm_t &_comm, const path &_p) -> object_time_type
Definition: filesystem.cpp:645
structFileDesc::rsComm
rsComm_t * rsComm
Definition: libstructfile.cpp:51
tar_file_sync
irods::error tar_file_sync(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:2458
irods::RESOURCE_OP_READ
const std::string RESOURCE_OP_READ("resource_read")
rsFileTruncate.hpp
NUM_TAR_SUB_FILE_DESC
#define NUM_TAR_SUB_FILE_DESC
Definition: libstructfile.cpp:67
irods::RESOURCE_OP_FREESPACE
const std::string RESOURCE_OP_FREESPACE("resource_freespace")
fileRenameInp_t::newFileName
char newFileName[(1024+64)]
Definition: fileRename.h:10
SpecColl::replNum
int replNum
Definition: objInfo.h:93
irods_resource_backport.hpp
fileOpenInp_t::resc_hier_
char resc_hier_[(1024+64)]
Definition: fileOpen.h:16
SpecColl
Definition: objInfo.h:76
irods::RESOURCE_OP_LSEEK
const std::string RESOURCE_OP_LSEEK("resource_lseek")
rsFileReaddir
int rsFileReaddir(rsComm_t *rsComm, fileReaddirInp_t *fileReaddirInp, rodsDirent_t **fileReaddirOut)
Definition: rsFileReaddir.cpp:16
fileWriteInp_t
Definition: fileWrite.h:7
PASSMSG
#define PASSMSG(message_, prev_error_)
Definition: irods_error.hpp:119
plugin_factory
irods::resource * plugin_factory(const std::string &_inst_name, const std::string &_context)
Definition: libstructfile.cpp:2663
rsFileOpendir.hpp
fileWriteInp_t::len
int len
Definition: fileWrite.h:9
fileRenameInp_t
Definition: fileRename.h:7
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
fileRmdirInp_t::rescHier
char rescHier[(1024+64)]
Definition: fileRmdir.h:14
irods::plugin_context
Definition: irods_plugin_context.hpp:18
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
irods::lookup_table::get
error get(const std::string &_key, ValueType &_val)
Definition: irods_lookup_table.hpp:71
irods::resource::resource
resource(const std::string &_inst, const std::string &_ctx)
Definition: irods_resource_plugin.hpp:29
tar_file_create
irods::error tar_file_create(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:801
fileOpenInp_t::fileName
char fileName[(1024+64)]
Definition: fileOpen.h:20
tar_file_rename
irods::error tar_file_rename(irods::plugin_context &_ctx, const char *_new_file_name)
Definition: libstructfile.cpp:1756
rsFileRename.hpp
rsFileOpen
int rsFileOpen(rsComm_t *rsComm, fileOpenInp_t *fileOpenInp)
Definition: rsFileOpen.cpp:21
fileUnlinkInp_t::fileName
char fileName[(1024+64)]
Definition: fileUnlink.h:9
SYS_OUT_OF_FILE_DESC
@ SYS_OUT_OF_FILE_DESC
Definition: rodsErrorTable.h:86
rsFileClose.hpp
getDefFileMode
int getDefFileMode()
Definition: physPath.cpp:1057
BytesBuf::len
int len
Definition: rodsDef.h:198
rodsStat::st_size
rodsLong_t st_size
Definition: rodsType.h:53
FileCloseInp
Definition: fileClose.h:6
hasSymlinkInDir
int hasSymlinkInDir(const char *mydir)
Definition: rcMisc.cpp:4368
tar_file_rebalance
irods::error tar_file_rebalance(irods::plugin_context &)
Definition: libstructfile.cpp:2624
irods_resource_plugin.hpp
SYS_NOT_SUPPORTED
@ SYS_NOT_SUPPORTED
Definition: rodsErrorTable.h:133
SUCCESS
#define SUCCESS()
Definition: irods_error.hpp:121
irods::plugin_context::comm
virtual rsComm_t * comm()
Definition: irods_plugin_context.hpp:95
irods::RESOURCE_OP_TRUNCATE
const std::string RESOURCE_OP_TRUNCATE("resource_truncate")
irods_string_tokenize.hpp
rsGlobalExtern.hpp
tarfilesystem_resource::tarfilesystem_resource
tarfilesystem_resource(const std::string &_inst_name, const std::string &_context)
Definition: libstructfile.cpp:2647
rsFileStat.hpp
irods::RESOURCE_OP_RENAME
const std::string RESOURCE_OP_RENAME("resource_rename")
FileReadInp
Definition: fileRead.h:7
fileCreateOut_t
Definition: fileCreate.h:9
irods::error::code
long long code() const
Definition: irods_error.cpp:194
fileOpenInp_t::flags
int flags
Definition: fileOpen.h:21
rodsStat
Definition: rodsType.h:52
tar_file_mkdir
irods::error tar_file_mkdir(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:1390
SYS_STRUCT_FILE_PATH_ERR
@ SYS_STRUCT_FILE_PATH_ERR
Definition: rodsErrorTable.h:139
fileOpenInp_t::addr
rodsHostAddr_t addr
Definition: fileOpen.h:19
fileStatInp_t::rescHier
char rescHier[(1024+64)]
Definition: fileStat.h:10
irods.pypyodbc.long
long
Definition: pypyodbc.py:43
alloc_struct_file_desc
int alloc_struct_file_desc()
Definition: libstructfile.cpp:576
irods::plugin_context::prop_map
virtual irods::plugin_property_map & prop_map()
Definition: irods_plugin_context.hpp:99
fileStatInp_t::objPath
char objPath[(1024+64)]
Definition: fileStat.h:11
tar_file_open
irods::error tar_file_open(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:902
FileCloseInp::fileInx
int fileInx
Definition: fileClose.h:7
tar_file_read
irods::error tar_file_read(irods::plugin_context &_ctx, void *_buf, int _len)
Definition: libstructfile.cpp:999
fileOpenInp_t::objPath
char objPath[(1024+64)]
Definition: fileOpen.h:17
fileOpendirInp_t
Definition: fileOpendir.h:7
fileWriteInp_t::fileInx
int fileInx
Definition: fileWrite.h:8
fileStatInp_t::addr
rodsHostAddr_t addr
Definition: fileStat.h:8
free_struct_file_desc
int free_struct_file_desc(int _idx)
Definition: libstructfile.cpp:588
fileRmdirInp_t::dirName
char dirName[(1024+64)]
Definition: fileRmdir.h:13
SYS_STRUCT_FILE_BUSY_ERR
@ SYS_STRUCT_FILE_BUSY_ERR
Definition: rodsErrorTable.h:142
irods::RESOURCE_OP_CREATE
const std::string RESOURCE_OP_CREATE("resource_create")
irods
Definition: apiHandler.hpp:35
fileOpendirInp_t::dirName
char dirName[(1024+64)]
Definition: fileOpendir.h:12
fileOpendirInp_t::resc_hier_
char resc_hier_[(1024+64)]
Definition: fileOpendir.h:9
tarSubFileDesc
Definition: libstructfile.cpp:59
fileMkdirInp_t::addr
rodsHostAddr_t addr
Definition: fileMkdir.h:8
RMDIR_RECUR
#define RMDIR_RECUR
Definition: fileRmdir.h:8
fileMkdirInp_t::dirName
char dirName[(1024+64)]
Definition: fileMkdir.h:9
rsFileOpendir
int rsFileOpendir(rsComm_t *rsComm, fileOpendirInp_t *fileOpendirInp)
Definition: rsFileOpendir.cpp:20
irods::RESOURCE_OP_NOTIFY
const std::string RESOURCE_OP_NOTIFY("resource_notify")
hostName::name
char * name
Definition: rodsConnect.h:38
regNewObjSize
int regNewObjSize(rsComm_t *rsComm, char *objPath, int replNum, rodsLong_t newSize)
Definition: dataObjOpr.cpp:1847
fileRmdirInp_t::flags
int flags
Definition: fileRmdir.h:11
build_directory_listing
irods::error build_directory_listing(const boost::filesystem::path &_path, std::vector< boost::filesystem::path > &_listing)
Definition: libstructfile.cpp:2123
FD_FREE
#define FD_FREE
Definition: fileOpr.hpp:20
bundle_cache_dir
irods::error bundle_cache_dir(int _index, std::string _data_type)
Definition: libstructfile.cpp:2185
fileUnlinkInp_t::rescHier
char rescHier[(1024+64)]
Definition: fileUnlink.h:10
irods::structured_object
Definition: irods_structured_object.hpp:15
fileOpendirInp_t::objPath
char objPath[(1024+64)]
Definition: fileOpendir.h:10
MAX_NAME_LEN
#define MAX_NAME_LEN
Definition: rodsDef.h:61
irods::RESOURCE_OP_WRITE
const std::string RESOURCE_OP_WRITE("resource_write")
irods::resource_manager::resolve
error resolve(std::string, resource_ptr &)
Definition: irods_resource_manager.cpp:51
ZIP_DT_STR
#define ZIP_DT_STR
Definition: objInfo.h:31
getErrno
int getErrno(int errCode)
Definition: rcMisc.cpp:3261
SYS_STRUCT_FILE_DESC_ERR
@ SYS_STRUCT_FILE_DESC_ERR
Definition: rodsErrorTable.h:135
structFileDesc_t
struct structFileDesc structFileDesc_t
fileOpenInp_t::mode
int mode
Definition: fileOpen.h:22
tarfilesystem_resource_start
irods::error tarfilesystem_resource_start(irods::plugin_property_map &)
Definition: libstructfile.cpp:99
rsFileReaddir.hpp
rsFileCreate
int rsFileCreate(rsComm_t *rsComm, fileCreateInp_t *fileCreateInp, fileCreateOut_t **)
Definition: rsFileCreate.cpp:28
tar_file_getfs_freespace
irods::error tar_file_getfs_freespace(irods::plugin_context &)
Definition: libstructfile.cpp:2592
irods.pypyodbc.status
status
Definition: pypyodbc.py:467
SpecColl::rescHier
char rescHier[(1024+64)]
Definition: objInfo.h:84
tar_file_truncate
irods::error tar_file_truncate(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:1855
collection.hpp
tar_file_opendir
irods::error tar_file_opendir(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:1564
rodsStatToStat
int rodsStatToStat(struct stat *myFileStat, rodsStat_t *rodsStat)
Definition: rcMisc.cpp:305
irods::RESOURCE_OP_CLOSE
const std::string RESOURCE_OP_CLOSE("resource_close")
physPath.hpp
irods::log
void log(const error &)
Definition: irods_log.cpp:13
fileMkdirInp_t::rescHier
char rescHier[(1024+64)]
Definition: fileMkdir.h:10
fileRenameInp_t::rescHier
char rescHier[(1024+64)]
Definition: fileRename.h:11
rodsDirent
Definition: rodsType.h:70
irods::structured_object_ptr
boost::shared_ptr< structured_object > structured_object_ptr
Definition: irods_structured_object.hpp:107
rsFileClosedir.hpp
rsFileClose
int rsFileClose(rsComm_t *rsComm, fileCloseInp_t *fileCloseInp)
Definition: rsFileClose.cpp:18
irods::RESOURCE_OP_UNLINK
const std::string RESOURCE_OP_UNLINK("resource_unlink")
fileRenameInp_t::objPath
char objPath[(1024+64)]
Definition: fileRename.h:12
fileRmdirInp_t
Definition: fileRmdir.h:10
LOG_NOTICE
#define LOG_NOTICE
Definition: rodsLog.h:33
rsFileCreate.hpp
irods::RESOURCE_OP_RMDIR
const std::string RESOURCE_OP_RMDIR("resource_rmdir")
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
BytesBuf
Definition: rodsDef.h:197
cb_ctx_t::desc_
structFileDesc_t * desc_
Definition: libstructfile.cpp:147
irods::RESOURCE_OP_UNREGISTERED
const std::string RESOURCE_OP_UNREGISTERED("resource_unregistered")
irods::error
Definition: irods_error.hpp:23
FileLseekOut
Definition: fileLseek.h:53
extract_file
irods::error extract_file(int _index)
Definition: libstructfile.cpp:315
cb_ctx_t::read_buf
bytesBuf_t read_buf
Definition: libstructfile.cpp:148
FileReadInp::fileInx
int fileInx
Definition: fileRead.h:8
miscServerFunct.hpp
DELETE_STRUCT_FILE
#define DELETE_STRUCT_FILE
Definition: syncMountedColl.h:9
structFileDesc::dataType
char dataType[64]
Definition: libstructfile.cpp:54
tar_file_notify
irods::error tar_file_notify(irods::plugin_context &, const std::string *)
Definition: libstructfile.cpp:2632
SpecColl::collection
char collection[(1024+64)]
Definition: objInfo.h:79
FD_INUSE
#define FD_INUSE
Definition: fileOpr.hpp:21
fileUnlinkInp_t::objPath
char objPath[(1024+64)]
Definition: fileUnlink.h:11
irods::RESOURCE_OP_REGISTERED
const std::string RESOURCE_OP_REGISTERED("resource_registered")
structFileDesc::inuseFlag
int inuseFlag
Definition: libstructfile.cpp:50
rsFileRead.hpp
free_tar_sub_file_desc
int free_tar_sub_file_desc(int _idx)
Definition: libstructfile.cpp:787
structFileDesc::openCnt
int openCnt
Definition: libstructfile.cpp:53
irods_hierarchy_parser.hpp
tar_file_registered
irods::error tar_file_registered(irods::plugin_context &)
Definition: libstructfile.cpp:2600
fileOpenInp_t
Definition: fileOpen.h:14
irods::plugin_base::set_start_operation
void set_start_operation(maintenance_operation_t _op)
Definition: irods_plugin_base.hpp:309
fileOpenInp_t::dataSize
rodsLong_t dataSize
Definition: fileOpen.h:23
rsFileRead
int rsFileRead(rsComm_t *rsComm, fileReadInp_t *fileReadInp, bytesBuf_t *fileReadOutBBuf)
Definition: rsFileRead.cpp:19
structFileDesc
Definition: libstructfile.cpp:49
irods::RESOURCE_OP_MKDIR
const std::string RESOURCE_OP_MKDIR("resource_mkdir")
rodsServerHost
Definition: rodsConnect.h:62
entry
Definition: ruleAdmin.cpp:22
CACHE_DIR_STR
#define CACHE_DIR_STR
Definition: libstructfile.cpp:57
apiHeaderAll.h
fileStatInp_t::fileName
char fileName[(1024+64)]
Definition: fileStat.h:9
FileLseekOut::offset
rodsLong_t offset
Definition: fileLseek.h:54
rodsHostAddr_t::hostAddr
char hostAddr[256]
Definition: rodsDef.h:297
fileRenameInp_t::oldFileName
char oldFileName[(1024+64)]
Definition: fileRename.h:9
tar_check_params
irods::error tar_check_params(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:128
irods::RESOURCE_OP_OPENDIR
const std::string RESOURCE_OP_OPENDIR("resource_opendir")
NUM_STRUCT_FILE_DESC
const int NUM_STRUCT_FILE_DESC
Definition: libstructfile.cpp:87
rsFileClosedir
int rsFileClosedir(rsComm_t *rsComm, fileClosedirInp_t *fileClosedirInp)
Definition: rsFileClosedir.cpp:16
sync_cache_dir_to_tar_file
irods::error sync_cache_dir_to_tar_file(int _index, int _opr_type, std::string _host)
Definition: libstructfile.cpp:2406
error
int error
Definition: filesystem.cpp:101
PURGE_STRUCT_FILE_CACHE
#define PURGE_STRUCT_FILE_CACHE
Definition: syncMountedColl.h:8
tar_file_close
irods::error tar_file_close(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:1112
structFileDesc::specColl
specColl_t * specColl
Definition: libstructfile.cpp:52
irods_resource_manager.hpp
tarSubFileDesc::structFileInx
int structFileInx
Definition: libstructfile.cpp:61
irods::plugin_base::add_operation
error add_operation(const std::string &_op, std::function< error(plugin_context &)> _f)
Definition: irods_plugin_base.hpp:122
FileLseekInp::fileInx
int fileInx
Definition: fileLseek.h:33
irods::resource_manager
Definition: irods_resource_manager.hpp:30
irods::plugin_context::fco
virtual first_class_object_ptr fco()
Definition: irods_plugin_context.hpp:102
PluginStructFileDesc
structFileDesc_t PluginStructFileDesc[NUM_STRUCT_FILE_DESC]
Definition: libstructfile.cpp:88
tar_file_extract
irods::error tar_file_extract(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:1951
tarfilesystem_resource_stop
irods::error tarfilesystem_resource_stop(irods::plugin_property_map &)
Definition: libstructfile.cpp:108
rsFileRmdir.hpp
resource.hpp
stage_tar_struct_file
irods::error stage_tar_struct_file(int _index, std::string _host)
Definition: libstructfile.cpp:496
modCollInfo2
int modCollInfo2(rsComm_t *rsComm, specColl_t *specColl, int clearFlag)
Definition: specColl.cpp:285
tarSubFileDesc::inuseFlag
int inuseFlag
Definition: libstructfile.cpp:60
cb_ctx_t::idx_
int idx_
Definition: libstructfile.cpp:145
irods_file_write
ssize_t irods_file_write(struct archive *_arch, void *_data, const void *_buff, size_t _len)
Definition: libstructfile.cpp:274
GZIP_TAR_DT_STR
#define GZIP_TAR_DT_STR
Definition: objInfo.h:29
fileOpendirInp_t::addr
rodsHostAddr_t addr
Definition: fileOpendir.h:11
tar_file_unlink
irods::error tar_file_unlink(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:1163
irods_file_read
ssize_t irods_file_read(struct archive *_arch, void *_data, const void **_block)
Definition: libstructfile.cpp:205
match_struct_file_desc
int match_struct_file_desc(specColl_t *_spec_coll)
Definition: libstructfile.cpp:603
tar_file_stat
irods::error tar_file_stat(irods::plugin_context &_ctx, struct stat *_statbuf)
Definition: libstructfile.cpp:1250
rodsServerHost::hostName
hostName_t * hostName
Definition: rodsConnect.h:63
irods::RESOURCE_OP_REBALANCE
const std::string RESOURCE_OP_REBALANCE("resource_rebalance")
mode
int mode
Definition: filesystem.cpp:104
rstrcpy
char * rstrcpy(char *dest, const char *src, int maxLen)
Definition: stringOpr.cpp:51
FileLseekInp
Definition: fileLseek.h:32
irods_structured_object.hpp
dataObjOpr.hpp
irods_file_open
int irods_file_open(struct archive *_arch, void *_data, int mode)
Definition: libstructfile.cpp:154
rsFileLseek
int rsFileLseek(rsComm_t *rsComm, fileLseekInp_t *fileLseekInp, fileLseekOut_t **fileLseekOut)
Definition: rsFileLseek.cpp:17
irods::get_loc_for_hier_string
error get_loc_for_hier_string(const std::string &_hier, std::string &_loc)
Definition: irods_resource_backport.cpp:633
SYS_FILE_DESC_OUT_OF_RANGE
@ SYS_FILE_DESC_OUT_OF_RANGE
Definition: rodsErrorTable.h:87
fileReaddirInp_t
Definition: fileReaddir.h:7
NAME_LEN
#define NAME_LEN
Definition: rodsDef.h:55
fileOpenInp_t::otherFlags
int otherFlags
Definition: fileOpen.h:18
DEFAULT_DIR_MODE
#define DEFAULT_DIR_MODE
Definition: objInfo.h:241
tarSubFileDesc::cacheFilePath
char cacheFilePath[(1024+64)]
Definition: libstructfile.cpp:63
rsFileLseek.hpp
CODE
#define CODE(code_)
Definition: irods_error.hpp:120
irods::error::ok
bool ok()
Definition: irods_error.cpp:258
fileUnlinkInp_t::addr
rodsHostAddr_t addr
Definition: fileUnlink.h:8
SpecColl::objPath
char objPath[(1024+64)]
Definition: objInfo.h:80
fileUnlinkInp_t
Definition: fileUnlink.h:7
tar_file_unregistered
irods::error tar_file_unregistered(irods::plugin_context &)
Definition: libstructfile.cpp:2608
cb_ctx_t
Definition: libstructfile.cpp:144
irods::RESOURCE_HOST
const std::string RESOURCE_HOST("resource_property_host")
irods::RESOURCE_OP_OPEN
const std::string RESOURCE_OP_OPEN("resource_open")
FileLseekInp::offset
rodsLong_t offset
Definition: fileLseek.h:34
tarfilesystem_resource
Definition: libstructfile.cpp:2645
irods::plugin_base::set_stop_operation
void set_stop_operation(maintenance_operation_t _op)
Definition: irods_plugin_base.hpp:313
SpecCollCache::specColl
specColl_t specColl
Definition: objInfo.h:104
tar_file_rmdir
irods::error tar_file_rmdir(irods::plugin_context &_ctx)
Definition: libstructfile.cpp:1479
FileLseekInp::whence
int whence
Definition: fileLseek.h:35
tarSubFileDesc::fd
int fd
Definition: libstructfile.cpp:62
rsFileMkdir
int rsFileMkdir(rsComm_t *rsComm, fileMkdirInp_t *fileMkdirInp)
Definition: rsFileMkdir.cpp:17
SpecCollCache
Definition: objInfo.h:102
fileMkdirInp_t
Definition: fileMkdir.h:7
rodsLong_t
long long rodsLong_t
Definition: rodsType.h:32
fileRenameInp_t::addr
rodsHostAddr_t addr
Definition: fileRename.h:8
objMetaOpr.hpp
rodsHostAddr_t
Definition: rodsDef.h:296