"Fossies" - the Fresh Open Source Software Archive

Member "cfitsio-4.0.0/drvrgsiftp.c" (20 May 2021, 13960 Bytes) of package /linux/misc/cfitsio-4.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "drvrgsiftp.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 3430_vs_3440.

    1 
    2 /*  This file, drvrgsiftp.c contains driver routines for gsiftp files. */
    3 /*  Andrea Barisani <lcars@si.inaf.it>                                 */
    4 /* Taffoni Giuliano <taffoni@oats.inaf.it>                             */
    5 #ifdef HAVE_NET_SERVICES 
    6 #ifdef HAVE_GSIFTP
    7 
    8 #include <sys/types.h>
    9 #include <string.h>
   10 #include <signal.h>
   11 #include <stdlib.h>
   12 #include <setjmp.h>
   13 #include "fitsio2.h"
   14 
   15 #include <globus_ftp_client.h>
   16 
   17 #define MAXLEN 1200
   18 #define NETTIMEOUT 80
   19 #define MAX_BUFFER_SIZE_R 1024
   20 #define MAX_BUFFER_SIZE_W (64*1024)
   21 
   22 static int gsiftpopen = 0;
   23 static int global_offset = 0;
   24 static int free_gsiftp_tmp=0;
   25 static int gsiftp_get(char *filename, FILE **gsiftpfile, int num_streams);
   26 
   27 static globus_mutex_t lock;
   28 static globus_cond_t cond;
   29 static globus_bool_t done;
   30 
   31 static char *gsiftp_tmpfile;
   32 static char *gsiftpurl = NULL;
   33 static char gsiftp_tmpdir[MAXLEN];
   34 
   35 static jmp_buf env; /* holds the jump buffer for setjmp/longjmp pairs */
   36 static void signal_handler(int sig);
   37 
   38 int gsiftp_init(void)
   39 {
   40 
   41   if (getenv("GSIFTP_TMPFILE")) {
   42     gsiftp_tmpfile = getenv("GSIFTP_TMPFILE");
   43   } else {
   44     strncpy(gsiftp_tmpdir, "/tmp/gsiftp_XXXXXX", sizeof gsiftp_tmpdir);
   45     if (mkdtemp(gsiftp_tmpdir) == NULL) {
   46         ffpmsg("Cannot create temporary directory!");
   47         return (FILE_NOT_OPENED);
   48     }
   49     gsiftp_tmpfile = malloc(strlen(gsiftp_tmpdir) + strlen("/gsiftp_buffer.tmp")+1);
   50     gsiftp_tmpfile[0]=0;
   51     free_gsiftp_tmp=1;
   52     strcat(gsiftp_tmpfile, gsiftp_tmpdir);
   53     strcat(gsiftp_tmpfile, "/gsiftp_buffer.tmp");
   54   }
   55 
   56   return file_init();
   57 }
   58 
   59 int gsiftp_shutdown(void)
   60 {
   61   free(gsiftpurl);
   62   if (free_gsiftp_tmp)
   63      free(gsiftp_tmpfile);
   64 
   65   return file_shutdown();
   66 }
   67 
   68 int gsiftp_setoptions(int options)
   69 {
   70   return file_setoptions(options);
   71 }
   72 
   73 int gsiftp_getoptions(int *options)
   74 {
   75   return file_getoptions(options);
   76 }
   77 
   78 int gsiftp_getversion(int *version)
   79 {
   80   return file_getversion(version);
   81 }
   82 
   83 int gsiftp_checkfile(char *urltype, char *infile, char *outfile)
   84 {
   85   return file_checkfile(urltype, infile, outfile);
   86 }
   87 
   88 int gsiftp_open(char *filename, int rwmode, int *handle)
   89 {
   90   FILE *gsiftpfile;
   91   int num_streams;
   92 
   93   if (getenv("GSIFTP_STREAMS")) {
   94     num_streams = (int)getenv("GSIFTP_STREAMS");
   95   } else {
   96     num_streams = 1;
   97   }
   98   
   99   if (rwmode) {
  100     gsiftpopen = 2;
  101   } else {
  102     gsiftpopen = 1;
  103   }
  104  
  105   if (gsiftpurl)
  106     free(gsiftpurl);
  107  
  108   gsiftpurl = strdup(filename);
  109 
  110   if (setjmp(env) != 0) {
  111     ffpmsg("Timeout (gsiftp_open)");
  112     goto error;
  113   }
  114   
  115   signal(SIGALRM, signal_handler);
  116   alarm(NETTIMEOUT);
  117 
  118   if (gsiftp_get(filename,&gsiftpfile,num_streams)) {
  119     alarm(0);
  120     ffpmsg("Unable to open gsiftp file (gsiftp_open)");
  121     ffpmsg(filename);
  122     goto error;
  123   } 
  124   
  125   fclose(gsiftpfile);
  126   
  127   signal(SIGALRM, SIG_DFL);
  128   alarm(0);
  129 
  130   return file_open(gsiftp_tmpfile, rwmode, handle);
  131 
  132   error:
  133    alarm(0);
  134    signal(SIGALRM, SIG_DFL);
  135    return (FILE_NOT_OPENED);
  136 }
  137 
  138 int gsiftp_create(char *filename, int *handle)
  139 {
  140   if (gsiftpurl)
  141     free(gsiftpurl);
  142 
  143   gsiftpurl = strdup(filename);
  144 
  145   return file_create(gsiftp_tmpfile, handle);
  146 }
  147 
  148 int gsiftp_truncate(int handle, LONGLONG filesize)
  149 {
  150   return file_truncate(handle, filesize);
  151 }
  152 
  153 int gsiftp_size(int handle, LONGLONG *filesize)
  154 {
  155   return file_size(handle, filesize);
  156 }
  157 
  158 int gsiftp_flush(int handle)
  159 {
  160   FILE *gsiftpfile;
  161   int num_streams;
  162 
  163   if (getenv("GSIFTP_STREAMS")) {
  164     num_streams = (int)getenv("GSIFTP_STREAMS");
  165   } else {
  166     num_streams = 1;
  167   }
  168   
  169   int rc = file_flush(handle);
  170 
  171   if (gsiftpopen != 1) {
  172   
  173     if (setjmp(env) != 0) {
  174       ffpmsg("Timeout (gsiftp_write)");
  175       goto error;
  176     }
  177   
  178     signal(SIGALRM, signal_handler);
  179     alarm(NETTIMEOUT);
  180 
  181     if (gsiftp_put(gsiftpurl,&gsiftpfile,num_streams)) {
  182       alarm(0);
  183       ffpmsg("Unable to open gsiftp file (gsiftp_flush)");
  184       ffpmsg(gsiftpurl);
  185       goto error;
  186     } 
  187   
  188     fclose(gsiftpfile);
  189   
  190     signal(SIGALRM, SIG_DFL);
  191     alarm(0);
  192   }
  193   
  194   return rc;
  195 
  196   error:
  197    alarm(0);
  198    signal(SIGALRM, SIG_DFL);
  199    return (FILE_NOT_OPENED);
  200 }
  201 
  202 int gsiftp_seek(int handle, LONGLONG offset)
  203 {
  204   return file_seek(handle, offset);
  205 }
  206 
  207 int gsiftp_read(int hdl, void *buffer, long nbytes)
  208 {
  209   return file_read(hdl, buffer, nbytes);
  210 }
  211 
  212 int gsiftp_write(int hdl, void *buffer, long nbytes)
  213 {
  214   return file_write(hdl, buffer, nbytes);
  215 }
  216 
  217 int gsiftp_close(int handle)
  218 {
  219     unlink(gsiftp_tmpfile);
  220     
  221     if (gsiftp_tmpdir)
  222         rmdir(gsiftp_tmpdir);
  223 
  224     return file_close(handle);
  225 }
  226 
  227 static void done_cb( void *                 user_arg,
  228                      globus_ftp_client_handle_t *   handle,
  229                      globus_object_t *          err)
  230 {
  231 
  232     if(err){
  233         fprintf(stderr, "%s", globus_object_printable_to_string(err));
  234     }
  235     
  236     globus_mutex_lock(&lock);
  237     done = GLOBUS_TRUE;
  238     globus_cond_signal(&cond);
  239     globus_mutex_unlock(&lock);
  240     return;
  241 }
  242 
  243 static void data_cb_read( void *            user_arg,
  244                           globus_ftp_client_handle_t *  handle,
  245                           globus_object_t *         err,
  246                           globus_byte_t *       buffer,
  247                           globus_size_t         length,
  248                           globus_off_t          offset,
  249                           globus_bool_t         eof)
  250 {
  251     if(err) {
  252         fprintf(stderr, "%s", globus_object_printable_to_string(err));
  253     }
  254     else {
  255         FILE* fd = (FILE*) user_arg;
  256         int rc = fwrite(buffer, 1, length, fd);
  257         if (ferror(fd)) {
  258             printf("Read error in function data_cb_read; errno = %d\n", errno);
  259             return;
  260         }
  261 
  262         if (!eof) {
  263             globus_ftp_client_register_read(handle,
  264                                             buffer,
  265                                             MAX_BUFFER_SIZE_R,
  266                                             data_cb_read,
  267                                             (void*) fd);
  268         }
  269     }
  270     return;
  271 }
  272 
  273 static void data_cb_write( void *           user_arg,
  274                            globus_ftp_client_handle_t * handle,
  275                            globus_object_t *        err,
  276                            globus_byte_t *      buffer,
  277                            globus_size_t        length,
  278                            globus_off_t         offset,
  279                            globus_bool_t        eof)
  280 {
  281     int curr_offset;
  282     if(err) {
  283         fprintf(stderr, "%s", globus_object_printable_to_string(err));
  284     }
  285     else {
  286         if (!eof) {
  287             FILE* fd = (FILE*) user_arg;
  288             int rc;
  289             globus_mutex_lock(&lock);
  290             curr_offset = global_offset;
  291             rc = fread(buffer, 1, MAX_BUFFER_SIZE_W, fd);
  292             global_offset += rc;
  293             globus_mutex_unlock(&lock);
  294             if (ferror(fd)) {
  295                 printf("Read error in function data_cb_write; errno = %d\n", errno);
  296                 return;
  297             }
  298 
  299             globus_ftp_client_register_write(handle,
  300                                              buffer,
  301                          rc,
  302                          curr_offset,
  303                                              feof(fd) != 0,
  304                                              data_cb_write,
  305                                              (void*) fd);
  306         } else {
  307             globus_libc_free(buffer);
  308         }
  309     }
  310     return;
  311 }
  312 
  313 int gsiftp_get(char *filename, FILE **gsiftpfile, int num_streams)
  314 {
  315     char gsiurl[MAXLEN];
  316 
  317     globus_ftp_client_handle_t      handle;
  318     globus_ftp_client_operationattr_t   attr;
  319     globus_ftp_client_handleattr_t  handle_attr;
  320     globus_ftp_control_parallelism_t    parallelism;
  321     globus_ftp_control_layout_t     layout;
  322     globus_byte_t           buffer[MAX_BUFFER_SIZE_R];
  323     globus_size_t buffer_length = sizeof(buffer);
  324     globus_result_t             result;
  325     globus_ftp_client_restart_marker_t  restart;
  326     globus_ftp_control_type_t       filetype;
  327    
  328     globus_module_activate(GLOBUS_FTP_CLIENT_MODULE);
  329     globus_mutex_init(&lock, GLOBUS_NULL);
  330     globus_cond_init(&cond, GLOBUS_NULL);
  331     globus_ftp_client_handle_init(&handle,  GLOBUS_NULL);
  332     globus_ftp_client_handleattr_init(&handle_attr);
  333     globus_ftp_client_operationattr_init(&attr);
  334     layout.mode = GLOBUS_FTP_CONTROL_STRIPING_NONE;
  335     globus_ftp_client_restart_marker_init(&restart);
  336     globus_ftp_client_operationattr_set_mode(
  337             &attr,
  338             GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK);
  339    
  340     if (num_streams >= 1)
  341     {
  342         parallelism.mode = GLOBUS_FTP_CONTROL_PARALLELISM_FIXED;
  343         parallelism.fixed.size = num_streams;
  344        
  345         globus_ftp_client_operationattr_set_parallelism(
  346             &attr,
  347             &parallelism);
  348     }
  349    
  350     globus_ftp_client_operationattr_set_layout(&attr,
  351                                                &layout);
  352    
  353     filetype = GLOBUS_FTP_CONTROL_TYPE_IMAGE;
  354     globus_ftp_client_operationattr_set_type (&attr,
  355                                               filetype);
  356    
  357     globus_ftp_client_handle_init(&handle, &handle_attr);
  358    
  359     done = GLOBUS_FALSE;
  360 
  361     strcpy(gsiurl,"gsiftp://");
  362     if (strlen(gsiurl)+strlen(filename) > MAXLEN-1)
  363     {
  364        ffpmsg("file name too long (gsiftp_get)");
  365        return (FILE_NOT_OPENED);
  366     }
  367     strcat(gsiurl,filename);
  368 
  369     *gsiftpfile = fopen(gsiftp_tmpfile,"w+");
  370     
  371     if (!*gsiftpfile) {
  372         ffpmsg("Unable to open temporary file!");
  373         return (FILE_NOT_OPENED);
  374     }
  375    
  376     result = globus_ftp_client_get(&handle,
  377                                    gsiurl,
  378                                    &attr,
  379                                    &restart,
  380                                    done_cb,
  381                                    0);
  382     if(result != GLOBUS_SUCCESS) {
  383         globus_object_t * err;
  384         err = globus_error_get(result);
  385         fprintf(stderr, "%s", globus_object_printable_to_string(err));
  386         done = GLOBUS_TRUE;
  387     }
  388     else {
  389         globus_ftp_client_register_read(&handle,
  390                                         buffer,
  391                                         buffer_length,
  392                                         data_cb_read,
  393                                         (void*) *gsiftpfile);
  394     }
  395    
  396     globus_mutex_lock(&lock);
  397 
  398     while(!done) {
  399         globus_cond_wait(&cond, &lock);
  400     }
  401 
  402     globus_mutex_unlock(&lock);
  403     globus_ftp_client_handle_destroy(&handle);
  404     globus_module_deactivate_all();
  405    
  406     return 0;
  407 }
  408 
  409 int gsiftp_put(char *filename, FILE **gsiftpfile, int num_streams)
  410 {
  411     int i;
  412     char gsiurl[MAXLEN];
  413 
  414     globus_ftp_client_handle_t      handle;
  415     globus_ftp_client_operationattr_t   attr;
  416     globus_ftp_client_handleattr_t  handle_attr;
  417     globus_ftp_control_parallelism_t    parallelism;
  418     globus_ftp_control_layout_t     layout;
  419     globus_byte_t *             buffer;
  420     globus_size_t buffer_length = sizeof(buffer);
  421     globus_result_t             result;
  422     globus_ftp_client_restart_marker_t  restart;
  423     globus_ftp_control_type_t       filetype;
  424    
  425     globus_module_activate(GLOBUS_FTP_CLIENT_MODULE);
  426     globus_mutex_init(&lock, GLOBUS_NULL);
  427     globus_cond_init(&cond, GLOBUS_NULL);
  428     globus_ftp_client_handle_init(&handle,  GLOBUS_NULL);
  429     globus_ftp_client_handleattr_init(&handle_attr);
  430     globus_ftp_client_operationattr_init(&attr);
  431     layout.mode = GLOBUS_FTP_CONTROL_STRIPING_NONE;
  432     globus_ftp_client_restart_marker_init(&restart);
  433     globus_ftp_client_operationattr_set_mode(
  434             &attr,
  435             GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK);
  436    
  437     if (num_streams >= 1)
  438     {
  439         parallelism.mode = GLOBUS_FTP_CONTROL_PARALLELISM_FIXED;
  440         parallelism.fixed.size = num_streams;
  441        
  442         globus_ftp_client_operationattr_set_parallelism(
  443             &attr,
  444             &parallelism);
  445     }
  446    
  447     globus_ftp_client_operationattr_set_layout(&attr,
  448                                                &layout);
  449    
  450     filetype = GLOBUS_FTP_CONTROL_TYPE_IMAGE;
  451     globus_ftp_client_operationattr_set_type (&attr,
  452                                               filetype);
  453    
  454     globus_ftp_client_handle_init(&handle, &handle_attr);
  455    
  456     done = GLOBUS_FALSE;
  457     
  458     strcpy(gsiurl,"gsiftp://");
  459     if (strlen(gsiurl)+strlen(filename) > MAXLEN-1)
  460     {
  461        ffpmsg("file name too long (gsiftp_put)");
  462        return (FILE_NOT_OPENED);
  463     }
  464     strcat(gsiurl,filename);
  465 
  466     *gsiftpfile = fopen(gsiftp_tmpfile,"r");
  467 
  468     if (!*gsiftpfile) {
  469         ffpmsg("Unable to open temporary file!");
  470         return (FILE_NOT_OPENED);
  471     }
  472    
  473     result = globus_ftp_client_put(&handle,
  474                                    gsiurl,
  475                                    &attr,
  476                                    &restart,
  477                                    done_cb,
  478                                    0);
  479     if(result != GLOBUS_SUCCESS) {
  480         globus_object_t * err;
  481         err = globus_error_get(result);
  482         fprintf(stderr, "%s", globus_object_printable_to_string(err));
  483         done = GLOBUS_TRUE;
  484     }
  485     else {
  486         int rc;
  487         int curr_offset;
  488 
  489     for (i = 0; i< 2 * num_streams && feof(*gsiftpfile) == 0; i++)
  490         {
  491             buffer = malloc(MAX_BUFFER_SIZE_W);
  492             globus_mutex_lock(&lock);
  493             curr_offset = global_offset;
  494             rc = fread(buffer, 1, MAX_BUFFER_SIZE_W, *gsiftpfile);
  495             global_offset += rc;
  496             globus_mutex_unlock(&lock);
  497             globus_ftp_client_register_write(
  498                 &handle,
  499                 buffer,
  500                 rc,
  501                 curr_offset,
  502                 feof(*gsiftpfile) != 0,
  503                 data_cb_write,
  504                 (void*) *gsiftpfile);
  505         }
  506     }
  507    
  508     globus_mutex_lock(&lock);
  509 
  510     while(!done) {
  511         globus_cond_wait(&cond, &lock);
  512     }
  513 
  514     globus_mutex_unlock(&lock);
  515     globus_ftp_client_handle_destroy(&handle);
  516     globus_module_deactivate_all();
  517    
  518     return 0;
  519 }
  520 
  521 static void signal_handler(int sig) {
  522 
  523   switch (sig) {
  524   case SIGALRM:    /* process for alarm */
  525     longjmp(env,sig);
  526     
  527   default: {
  528       /* Hmm, shouldn't have happend */
  529       exit(sig);
  530     }
  531   }
  532 }
  533 
  534 #endif
  535 #endif